diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2011-12-09 01:47:12 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2011-12-09 01:47:12 +0000 |
commit | 4f8b3a9ea1ccbbea26c488f91263ea664cfcf75e (patch) | |
tree | 84b129d7316de38c08fde88ebf87e8341ddabf9c /usr.bin | |
parent | 553dab463f8ba9638e06c9426a90e9e192731ad9 (diff) |
Improve parsing of preformatted manuals:
* If the first section is empty, reuse the file name as the description.
* Strip backspace encoding from the description.
* Make the loops more readable using string(3) functions.
* Put fclose() at the end, as line isn't valid afterwards.
From kristaps@, tweaked a bit by me.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/mandoc/mandocdb.c | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/usr.bin/mandoc/mandocdb.c b/usr.bin/mandoc/mandocdb.c index 312b38f707f..22dcd4228e3 100644 --- a/usr.bin/mandoc/mandocdb.c +++ b/usr.bin/mandoc/mandocdb.c @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.21 2011/12/09 00:53:10 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.22 2011/12/09 01:47:11 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> @@ -1276,52 +1276,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; + + /* + * Assume the first line that is not indented + * is the first section header. Skip to it. + */ + + while (NULL != (line = fgetln(stream, &len))) + if ('\n' != *line && ' ' != *line) + break; /* - * If no page content can be found, - * reuse the page title as the page description. + * 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. */ - if (NULL == (line = fgetln(stream, &len))) { + 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 |