+
+ if (pos >= (int)ln.sz)
+ if (! resize_buf(&ln, 256))
+ goto bailout;
+ ln.buf[pos] = '\0';
+
+ re = roff_parseln(roff, lnn_start, &ln.buf, &ln.sz);
+ if (ROFF_IGN == re)
+ continue;
+ else if (ROFF_ERR == re)
+ goto bailout;
+
+ /* If unset, assign parser in pset(). */
+
+ if ( ! (man || mdoc) && ! pset(ln.buf, pos, curp, &man, &mdoc))
+ goto bailout;
+
+ /* Pass down into parsers. */
+
+ if (man && ! man_parseln(man, lnn_start, ln.buf))
+ goto bailout;
+ if (mdoc && ! mdoc_parseln(mdoc, lnn_start, ln.buf))
+ goto bailout;
+ }
+
+ /* NOTE a parser may not have been assigned, yet. */
+
+ if ( ! (man || mdoc)) {
+ fprintf(stderr, "%s: Not a manual\n", curp->file);
+ goto bailout;
+ }
+
+ if (mdoc && ! mdoc_endparse(mdoc))
+ goto bailout;
+ if (man && ! man_endparse(man))
+ goto bailout;
+ if (roff && ! roff_endparse(roff))
+ goto bailout;
+
+ /* If unset, allocate output dev now (if applicable). */
+
+ if ( ! (curp->outman && curp->outmdoc)) {
+ switch (curp->outtype) {
+ case (OUTT_XHTML):
+ curp->outdata = xhtml_alloc(curp->outopts);
+ curp->outman = html_man;
+ curp->outmdoc = html_mdoc;
+ curp->outfree = html_free;
+ break;
+ case (OUTT_HTML):
+ curp->outdata = html_alloc(curp->outopts);
+ curp->outman = html_man;
+ curp->outmdoc = html_mdoc;
+ curp->outfree = html_free;
+ break;
+ case (OUTT_TREE):
+ curp->outman = tree_man;
+ curp->outmdoc = tree_mdoc;
+ break;
+ case (OUTT_LINT):
+ break;
+ default:
+ curp->outdata = ascii_alloc(80);
+ curp->outman = terminal_man;
+ curp->outmdoc = terminal_mdoc;
+ curp->outfree = terminal_free;
+ break;
+ }
+ }
+
+ /* Execute the out device, if it exists. */
+
+ if (man && curp->outman)
+ (*curp->outman)(curp->outdata, man);
+ if (mdoc && curp->outmdoc)
+ (*curp->outmdoc)(curp->outdata, mdoc);
+
+ cleanup:
+ if (mdoc)
+ mdoc_reset(mdoc);
+ if (man)
+ man_reset(man);
+ if (roff)
+ roff_reset(roff);
+ if (ln.buf)
+ free(ln.buf);
+ if (with_mmap)
+ munmap(blk.buf, blk.sz);
+ else
+ free(blk.buf);
+
+ return;
+
+ bailout:
+ with_error = 1;
+ goto cleanup;
+}
+
+
+static int
+pset(const char *buf, int pos, struct curparse *curp,
+ struct man **man, struct mdoc **mdoc)
+{
+ int i;
+
+ /*
+ * Try to intuit which kind of manual parser should be used. If
+ * passed in by command-line (-man, -mdoc), then use that
+ * explicitly. If passed as -mandoc, then try to guess from the
+ * line: either skip dot-lines, use -mdoc when finding `.Dt', or
+ * default to -man, which is more lenient.
+ */
+
+ if ('.' == buf[0] || '\'' == buf[0]) {
+ for (i = 1; buf[i]; i++)
+ if (' ' != buf[i] && '\t' != buf[i])
+ break;
+ if (0 == buf[i])
+ return(1);
+ }
+
+ switch (curp->inttype) {
+ case (INTT_MDOC):
+ if (NULL == curp->mdoc)
+ curp->mdoc = mdoc_init(curp);
+ if (NULL == (*mdoc = curp->mdoc))
+ return(0);
+ return(1);
+ case (INTT_MAN):
+ if (NULL == curp->man)
+ curp->man = man_init(curp);
+ if (NULL == (*man = curp->man))
+ return(0);
+ return(1);
+ default:
+ break;
+ }
+
+ if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) {
+ if (NULL == curp->mdoc)
+ curp->mdoc = mdoc_init(curp);
+ if (NULL == (*mdoc = curp->mdoc))
+ return(0);
+ return(1);
+ }
+
+ if (NULL == curp->man)
+ curp->man = man_init(curp);
+ if (NULL == (*man = curp->man))
+ return(0);
+ return(1);
+}
+
+
+static int
+moptions(enum intt *tflags, char *arg)
+{
+
+ if (0 == strcmp(arg, "doc"))
+ *tflags = INTT_MDOC;
+ else if (0 == strcmp(arg, "andoc"))
+ *tflags = INTT_AUTO;
+ else if (0 == strcmp(arg, "an"))
+ *tflags = INTT_MAN;
+ else {
+ fprintf(stderr, "%s: Bad argument\n", arg);
+ return(0);