=================================================================== RCS file: /cvs/mandoc/mandocdb.c,v retrieving revision 1.25 retrieving revision 1.31 diff -u -p -r1.25 -r1.31 --- mandoc/mandocdb.c 2011/12/07 01:57:20 1.25 +++ mandoc/mandocdb.c 2011/12/09 11:16:34 1.31 @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.25 2011/12/07 01:57:20 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.31 2011/12/09 11:16:34 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -107,7 +107,8 @@ static void index_merge(const struct of *, struct m recno_t, const recno_t *, size_t); static void index_prune(const struct of *, DB *, const char *, DB *, const char *, - recno_t *, recno_t **, size_t *); + recno_t *, recno_t **, size_t *, + size_t *); static void ofile_argbuild(int, char *[], struct of **); static int ofile_dirbuild(const char *, const char *, const char *, int, struct of **); @@ -272,7 +273,9 @@ main(int argc, char *argv[]) struct manpaths dirs; enum op op; /* current operation */ const char *dir; - char ibuf[MAXPATHLEN], /* index fname */ + char *cp; + char pbuf[PATH_MAX], + ibuf[MAXPATHLEN], /* index fname */ fbuf[MAXPATHLEN]; /* btree fname */ int ch, i, flags; DB *idx, /* index database */ @@ -388,7 +391,7 @@ main(int argc, char *argv[]) of = of->first; index_prune(of, db, fbuf, idx, ibuf, - &maxrec, &recs, &recsz); + &maxrec, &recs, &recsz, &reccur); /* * Go to the root of the respective manual tree @@ -413,10 +416,15 @@ main(int argc, char *argv[]) */ if (argc > 0) { - dirs.paths = mandoc_malloc(argc * sizeof(char *)); + dirs.paths = mandoc_calloc(argc, sizeof(char *)); dirs.sz = argc; - for (i = 0; i < argc; i++) - dirs.paths[i] = mandoc_strdup(argv[i]); + for (i = 0; i < argc; i++) { + if (NULL == (cp = realpath(argv[i], pbuf))) { + perror(argv[i]); + goto out; + } + dirs.paths[i] = mandoc_strdup(cp); + } } else manpath_parse(&dirs, NULL, NULL); @@ -675,18 +683,17 @@ index_merge(const struct of *of, struct mparse *mp, */ static void index_prune(const struct of *ofile, DB *db, const char *dbf, - DB *idx, const char *idxf, - recno_t *maxrec, recno_t **recs, size_t *recsz) + DB *idx, const char *idxf, recno_t *maxrec, + recno_t **recs, size_t *recsz, size_t *reccur) { const struct of *of; const char *fn, *cp; struct db_val *vbuf; unsigned seq, sseq; DBT key, val; - size_t reccur; int ch; - reccur = 0; + *reccur = 0; seq = R_FIRST; while (0 == (ch = (*idx->seq)(idx, &key, &val, seq))) { seq = R_NEXT; @@ -760,14 +767,14 @@ index_prune(const struct of *ofile, DB *db, const char if (ch < 0) break; cont: - if (reccur >= *recsz) { + if (*reccur >= *recsz) { *recsz += MANDOC_SLOP; *recs = mandoc_realloc (*recs, *recsz * sizeof(recno_t)); } - (*recs)[(int)reccur] = *maxrec; - reccur++; + (*recs)[(int)*reccur] = *maxrec; + (*reccur)++; } if (ch < 0) { @@ -1281,52 +1288,72 @@ pformatted(DB *hash, struct buf *buf, struct buf *dbuf buf_append(buf, of->title); hash_put(hash, buf, TYPE_Nm); - while (NULL != (line = fgetln(stream, &len)) && '\n' != *line) - /* Skip to first blank line. */ ; + /* Skip to first blank line. */ - while (NULL != (line = fgetln(stream, &len)) && - ('\n' == *line || ' ' == *line)) - /* Skip to first section header. */ ; + while (NULL != (line = fgetln(stream, &len))) + if ('\n' == *line) + break; /* - * If no page content can be found, - * reuse the page title as the page description. + * Assume the first line that is not indented + * is the first section header. Skip to it. */ - if (NULL == (line = fgetln(stream, &len))) { + while (NULL != (line = fgetln(stream, &len))) + if ('\n' != *line && ' ' != *line) + break; + + /* + * If no page content can be found, or the input line + * is already the next section header, or there is no + * trailing newline, reuse the page title as the page + * description. + */ + + line = fgetln(stream, &len); + if (NULL == line || ' ' != *line || '\n' != line[(int)len - 1]) { buf_appendb(dbuf, buf->cp, buf->size); hash_put(hash, buf, TYPE_Nd); fclose(stream); return; } - fclose(stream); + line[(int)--len] = '\0'; + /* - * If there is a dash, skip to the text following it. + * Skip to the first dash. + * Use the remaining line as the description (no more than 70 + * bytes). */ - for (p = line, plen = len; plen; p++, plen--) - if ('-' == *p) - break; - for ( ; plen; p++, plen--) - if ('-' != *p && ' ' != *p && 8 != *p) - break; - if (0 == plen) { + if (NULL != (p = strstr(line, "- "))) { + for (p += 2; ' ' == *p || '\b' == *p; p++) + /* Skip to next word. */ ; + } else p = line; - plen = len; + + if ((plen = strlen(p)) > 70) { + plen = 70; + p[plen] = '\0'; } - /* - * Copy the rest of the line, but no more than 70 bytes. - */ + /* Strip backspace-encoding from line. */ - if (70 < plen) - plen = 70; - p[plen-1] = '\0'; - buf_appendb(dbuf, p, plen); + while (NULL != (line = memchr(p, '\b', plen))) { + len = line - p; + if (0 == len) { + memmove(line, line + 1, plen--); + continue; + } + memmove(line - 1, line + 1, plen - len); + plen -= 2; + } + + buf_appendb(dbuf, p, plen + 1); buf->len = 0; - buf_appendb(buf, p, plen); + buf_appendb(buf, p, plen + 1); hash_put(hash, buf, TYPE_Nd); + fclose(stream); } static void