+/*
+ * Parse a formatted manual page.
+ * By necessity, this involves rather crude guesswork.
+ */
+static void
+pformatted(DB *hash, struct buf *buf, struct buf *dbuf,
+ const struct of *of)
+{
+ FILE *stream;
+ char *line, *p;
+ size_t len, plen;
+
+ if (NULL == (stream = fopen(of->fname, "r"))) {
+ perror(of->fname);
+ return;
+ }
+
+ /*
+ * Always use the title derived from the filename up front,
+ * do not even try to find it in the file. This also makes
+ * sure we don't end up with an orphan index record, even if
+ * the file content turns out to be completely unintelligible.
+ */
+
+ buf->len = 0;
+ buf_append(buf, of->title);
+ hash_put(hash, buf, TYPE_Nm);
+
+ while (NULL != (line = fgetln(stream, &len)) && '\n' != *line)
+ /* Skip to first blank line. */ ;
+
+ while (NULL != (line = fgetln(stream, &len)) &&
+ ('\n' == *line || ' ' == *line))
+ /* Skip to first section header. */ ;
+
+ /*
+ * If no page content can be found,
+ * reuse the page title as the page description.
+ */
+
+ if (NULL == (line = fgetln(stream, &len))) {
+ buf_appendb(dbuf, buf->cp, buf->size);
+ hash_put(hash, buf, TYPE_Nd);
+ fclose(stream);
+ return;
+ }
+ fclose(stream);
+
+ /*
+ * If there is a dash, skip to the text following it.
+ */
+
+ for (p = line, plen = len; plen; p++, plen--)
+ if ('-' == *p)
+ break;
+ for ( ; plen; p++, plen--)
+ if ('-' != *p && ' ' != *p && 8 != *p)
+ break;
+ if (0 == plen) {
+ p = line;
+ plen = len;
+ }
+
+ /*
+ * Copy the rest of the line, but no more than 70 bytes.
+ */
+
+ if (70 < plen)
+ plen = 70;
+ p[plen-1] = '\0';
+ buf_appendb(dbuf, p, plen);
+ buf->len = 0;
+ buf_appendb(buf, p, plen);
+ hash_put(hash, buf, TYPE_Nd);
+}
+
+static void
+ofile_argbuild(int argc, char *argv[], struct of **of)
+{
+ char buf[MAXPATHLEN];
+ char *sec, *arch, *title, *p;
+ int i, src_form;
+ struct of *nof;
+
+ for (i = 0; i < argc; i++) {
+
+ /*
+ * Try to infer the manual section, architecture and
+ * page title from the path, assuming it looks like
+ * man*[/<arch>]/<title>.<section> or
+ * cat<section>[/<arch>]/<title>.0
+ */
+
+ if (strlcpy(buf, argv[i], sizeof(buf)) >= sizeof(buf)) {
+ fprintf(stderr, "%s: Path too long\n", argv[i]);
+ continue;
+ }
+ sec = arch = title = NULL;
+ src_form = 0;
+ p = strrchr(buf, '\0');
+ while (p-- > buf) {
+ if (NULL == sec && '.' == *p) {
+ sec = p + 1;
+ *p = '\0';
+ if ('0' == *sec)
+ src_form |= MANDOC_FORM;
+ else if ('1' <= *sec && '9' >= *sec)
+ src_form |= MANDOC_SRC;
+ continue;
+ }
+ if ('/' != *p)
+ continue;
+ if (NULL == title) {
+ title = p + 1;
+ *p = '\0';
+ continue;
+ }
+ if (strncmp("man", p + 1, 3)) {
+ src_form |= MANDOC_SRC;
+ arch = p + 1;
+ } else if (strncmp("cat", p + 1, 3)) {
+ src_form |= MANDOC_FORM;
+ arch = p + 1;
+ }
+ break;
+ }
+ if (NULL == title)
+ title = buf;
+
+ /*
+ * Build the file structure.
+ */
+
+ nof = mandoc_calloc(1, sizeof(struct of));
+ nof->fname = mandoc_strdup(argv[i]);
+ if (NULL != sec)
+ nof->sec = mandoc_strdup(sec);
+ if (NULL != arch)
+ nof->arch = mandoc_strdup(arch);
+ nof->title = mandoc_strdup(title);
+ nof->src_form = src_form;
+
+ /*
+ * Add the structure to the list.
+ */
+
+ if (verb > 2)
+ printf("%s: Scheduling\n", argv[i]);
+ if (NULL == *of) {
+ *of = nof;
+ (*of)->first = nof;
+ } else {
+ nof->first = (*of)->first;
+ (*of)->next = nof;
+ *of = nof;
+ }
+ }
+}
+