summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2011-12-09 01:47:12 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2011-12-09 01:47:12 +0000
commit4f8b3a9ea1ccbbea26c488f91263ea664cfcf75e (patch)
tree84b129d7316de38c08fde88ebf87e8341ddabf9c /usr.bin
parent553dab463f8ba9638e06c9426a90e9e192731ad9 (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.c74
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