]> git.cameronkatri.com Git - mandoc.git/blobdiff - read.c
Unify mdoc_deroff() and man_deroff() into a common function deroff().
[mandoc.git] / read.c
diff --git a/read.c b/read.c
index a52bfb1c443a2ee13a4c0791af852787c453c006..11836f5cc8c1ab82cb552d7b29bc6b7cebd90c73 100644 (file)
--- a/read.c
+++ b/read.c
@@ -1,4 +1,4 @@
-/*     $Id: read.c,v 1.124 2015/02/06 07:13:14 schwarze Exp $ */
+/*     $Id: read.c,v 1.139 2015/04/19 14:25:41 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -8,9 +8,9 @@
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
@@ -29,6 +29,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 
-#include "mandoc.h"
 #include "mandoc_aux.h"
-#include "libmandoc.h"
+#include "mandoc.h"
+#include "roff.h"
 #include "mdoc.h"
 #include "man.h"
+#include "libmandoc.h"
+#include "roff_int.h"
 
 #define        REPARSE_LIMIT   1000
 
 struct mparse {
-       struct man       *pman; /* persistent man parser */
-       struct mdoc      *pmdoc; /* persistent mdoc parser */
-       struct man       *man; /* man parser */
-       struct mdoc      *mdoc; /* mdoc parser */
+       struct roff_man  *man; /* man parser */
        struct roff      *roff; /* roff parser (!NULL) */
        const struct mchars *mchars; /* character table */
        char             *sodest; /* filename pointed to by .so */
@@ -109,7 +109,10 @@ static     const char * const      mandocerrs[MANDOCERR_MAX] = {
        "no document body",
        "content before first section header",
        "first section is not \"NAME\"",
-       "bad NAME section contents",
+       "NAME section without name",
+       "NAME section without description",
+       "description not at the end of NAME",
+       "bad NAME section content",
        "missing description line, using \"\"",
        "sections out of conventional order",
        "duplicate section title",
@@ -150,6 +153,8 @@ static      const char * const      mandocerrs[MANDOCERR_MAX] = {
        "nothing follows prefix",
        "empty reference block",
        "missing -std argument, adding it",
+       "missing option string, using \"\"",
+       "missing resource identifier, using \"\"",
        "missing eqn box, using \"\"",
 
        /* related to bad macro arguments */
@@ -159,12 +164,14 @@ static    const char * const      mandocerrs[MANDOCERR_MAX] = {
        "skipping duplicate display type",
        "skipping duplicate list type",
        "skipping -width argument",
+       "wrong number of cells",
        "unknown AT&T UNIX version",
        "comma in function argument",
        "parenthesis in function name",
        "invalid content in Rs block",
        "invalid Boolean argument",
        "unknown font, skipping request",
+       "odd number of characters in request",
 
        /* related to plain text */
        "blank line in fill mode, using .sp",
@@ -209,7 +216,6 @@ static      const char * const      mandocerrs[MANDOCERR_MAX] = {
 
        /* related to request and macro arguments */
        "escaped character not allowed in a name",
-       "argument count wrong",
        "NOT IMPLEMENTED: Bd -file",
        "missing list type, using -item",
        "missing manual name, using \"\"",
@@ -284,24 +290,22 @@ choose_parser(struct mparse *curp)
                }
        }
 
-       if (format == MPARSE_MDOC) {
-               if (NULL == curp->pmdoc)
-                       curp->pmdoc = mdoc_alloc(
-                           curp->roff, curp, curp->defos,
-                           MPARSE_QUICK & curp->options ? 1 : 0);
-               assert(curp->pmdoc);
-               curp->mdoc = curp->pmdoc;
-               return;
+       if (curp->man == NULL) {
+               curp->man = roff_man_alloc(curp->roff, curp, curp->defos,
+                   curp->options & MPARSE_QUICK ? 1 : 0);
+               curp->man->macroset = MACROSET_MAN;
+               curp->man->first->tok = TOKEN_NONE;
        }
 
-       /* Fall back to man(7) as a last resort. */
-
-       if (NULL == curp->pman)
-               curp->pman = man_alloc(
-                   curp->roff, curp, curp->defos,
-                   MPARSE_QUICK & curp->options ? 1 : 0);
-       assert(curp->pman);
-       curp->man = curp->pman;
+       if (format == MPARSE_MDOC) {
+               mdoc_hash_init();
+               curp->man->macroset = MACROSET_MDOC;
+               curp->man->first->tok = TOKEN_NONE;
+       } else {
+               man_hash_init();
+               curp->man->macroset = MACROSET_MAN;
+               curp->man->first->tok = TOKEN_NONE;
+       }
 }
 
 /*
@@ -396,7 +400,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
                                    MANDOCERR_CHAR_UNSUPP,
                                    curp, curp->line, pos, "0x%x", c);
                                i++;
-                               ln.buf[pos++] = '?';
+                               if (c != '\r')
+                                       ln.buf[pos++] = '?';
                                continue;
                        }
 
@@ -566,7 +571,8 @@ rerun:
                 * parsers with each one.
                 */
 
-               if ( ! (curp->man || curp->mdoc))
+               if (curp->man == NULL ||
+                   curp->man->macroset == MACROSET_NONE)
                        choose_parser(curp);
 
                /*
@@ -578,19 +584,13 @@ rerun:
                 * Do the same for ROFF_EQN.
                 */
 
-               if (rr == ROFF_TBL) {
+               if (rr == ROFF_TBL)
                        while ((span = roff_span(curp->roff)) != NULL)
-                               if (curp->man == NULL)
-                                       mdoc_addspan(curp->mdoc, span);
-                               else
-                                       man_addspan(curp->man, span);
-               } else if (rr == ROFF_EQN) {
-                       if (curp->man == NULL)
-                               mdoc_addeqn(curp->mdoc, roff_eqn(curp->roff));
-                       else
-                               man_addeqn(curp->man, roff_eqn(curp->roff));
-               } else if ((curp->man == NULL ?
-                   mdoc_parseln(curp->mdoc, curp->line, ln.buf, of) :
+                               roff_addtbl(curp->man, span);
+               else if (rr == ROFF_EQN)
+                       roff_addeqn(curp->man, roff_eqn(curp->roff));
+               else if ((curp->man->macroset == MACROSET_MDOC ?
+                   mdoc_parseln(curp->man, curp->line, ln.buf, of) :
                    man_parseln(curp->man, curp->line, ln.buf, of)) == 2)
                                break;
 
@@ -629,7 +629,7 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
         */
 
        if (S_ISREG(st.st_mode)) {
-               if (st.st_size >= (1U << 31)) {
+               if (st.st_size > 0x7fffffff) {
                        mandoc_msg(MANDOCERR_TOOLARGE, curp, 0, 0, NULL);
                        return(0);
                }
@@ -680,22 +680,14 @@ static void
 mparse_end(struct mparse *curp)
 {
 
-       if (curp->mdoc == NULL &&
-           curp->man == NULL &&
-           curp->sodest == NULL) {
-               if (curp->options & MPARSE_MDOC)
-                       curp->mdoc = curp->pmdoc;
-               else {
-                       if (curp->pman == NULL)
-                               curp->pman = man_alloc(
-                                   curp->roff, curp, curp->defos,
-                                   curp->options & MPARSE_QUICK ? 1 : 0);
-                       curp->man = curp->pman;
-               }
-       }
-       if (curp->mdoc)
-               mdoc_endparse(curp->mdoc);
-       if (curp->man)
+       if (curp->man == NULL && curp->sodest == NULL)
+               curp->man = roff_man_alloc(curp->roff, curp, curp->defos,
+                   curp->options & MPARSE_QUICK ? 1 : 0);
+       if (curp->man->macroset == MACROSET_NONE)
+               curp->man->macroset = MACROSET_MAN;
+       if (curp->man->macroset == MACROSET_MDOC)
+               mdoc_endparse(curp->man);
+       else
                man_endparse(curp->man);
        roff_endparse(curp->roff);
 }
@@ -839,6 +831,7 @@ mparse_open(struct mparse *curp, int *fd, const char *file)
                        perror("dup");
                        exit((int)MANDOCLEVEL_SYSERR);
                }
+               signal(SIGPIPE, SIG_DFL);
                execlp("gunzip", "gunzip", "-c", file, NULL);
                perror("exec");
                exit((int)MANDOCLEVEL_SYSERR);
@@ -861,6 +854,7 @@ mparse_wait(struct mparse *curp)
                perror("wait");
                exit((int)MANDOCLEVEL_SYSERR);
        }
+       curp->child = 0;
        if (WIFSIGNALED(status)) {
                mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
                    "gunzip died from signal %d", WTERMSIG(status));
@@ -889,15 +883,16 @@ mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
 
        curp->mchars = mchars;
        curp->roff = roff_alloc(curp, curp->mchars, options);
-       if (curp->options & MPARSE_MDOC)
-               curp->pmdoc = mdoc_alloc(
-                   curp->roff, curp, curp->defos,
-                   curp->options & MPARSE_QUICK ? 1 : 0);
-       if (curp->options & MPARSE_MAN)
-               curp->pman = man_alloc(
-                   curp->roff, curp, curp->defos,
-                   curp->options & MPARSE_QUICK ? 1 : 0);
-
+       curp->man = roff_man_alloc( curp->roff, curp, curp->defos,
+               curp->options & MPARSE_QUICK ? 1 : 0);
+       if (curp->options & MPARSE_MDOC) {
+               mdoc_hash_init();
+               curp->man->macroset = MACROSET_MDOC;
+       } else if (curp->options & MPARSE_MAN) {
+               man_hash_init();
+               curp->man->macroset = MACROSET_MAN;
+       }
+       curp->man->first->tok = TOKEN_NONE;
        return(curp);
 }
 
@@ -907,16 +902,12 @@ mparse_reset(struct mparse *curp)
 
        roff_reset(curp->roff);
 
-       if (curp->mdoc)
-               mdoc_reset(curp->mdoc);
-       if (curp->man)
-               man_reset(curp->man);
+       if (curp->man != NULL)
+               roff_man_reset(curp->man);
        if (curp->secondary)
                curp->secondary->sz = 0;
 
        curp->file_status = MANDOCLEVEL_OK;
-       curp->mdoc = NULL;
-       curp->man = NULL;
 
        free(curp->sodest);
        curp->sodest = NULL;
@@ -926,10 +917,7 @@ void
 mparse_free(struct mparse *curp)
 {
 
-       if (curp->pmdoc)
-               mdoc_free(curp->pmdoc);
-       if (curp->pman)
-               man_free(curp->pman);
+       roff_man_free(curp->man);
        if (curp->roff)
                roff_free(curp->roff);
        if (curp->secondary)
@@ -941,17 +929,14 @@ mparse_free(struct mparse *curp)
 }
 
 void
-mparse_result(struct mparse *curp,
-       struct mdoc **mdoc, struct man **man, char **sodest)
+mparse_result(struct mparse *curp, struct roff_man **man,
+       char **sodest)
 {
 
        if (sodest && NULL != (*sodest = curp->sodest)) {
-               *mdoc = NULL;
                *man = NULL;
                return;
        }
-       if (mdoc)
-               *mdoc = curp->mdoc;
        if (man)
                *man = curp->man;
 }