]> git.cameronkatri.com Git - mandoc.git/blobdiff - roff.c
Move main format autodetection from the parser dispatcher to the
[mandoc.git] / roff.c
diff --git a/roff.c b/roff.c
index 178065456bb6f653fac339344f5f9e02c57227f9..1d8a3991ba396e2af7e3d09f5054eae3c24c26b7 100644 (file)
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/*     $Id: roff.c,v 1.220 2014/07/07 11:35:06 schwarze Exp $ */
+/*     $Id: roff.c,v 1.227 2014/09/06 22:39:36 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,9 +15,9 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+
+#include <sys/types.h>
 
 #include <assert.h>
 #include <ctype.h>
@@ -27,8 +27,8 @@
 
 #include "mandoc.h"
 #include "mandoc_aux.h"
-#include "libroff.h"
 #include "libmandoc.h"
+#include "libroff.h"
 
 /* Maximum number of nested if-else conditionals. */
 #define        RSTACK_MAX      128
@@ -106,11 +106,8 @@ struct     roffreg {
 
 struct roff {
        struct mparse   *parse; /* parse point */
-       int              options; /* parse options */
        struct roffnode *last; /* leaf of stack */
-       int              rstack[RSTACK_MAX]; /* stack of !`ie' rules */
-       char             control; /* control character */
-       int              rstackpos; /* position in rstack */
+       int             *rstack; /* stack of inverted `ie' values */
        struct roffreg  *regtab; /* number registers */
        struct roffkv   *strtab; /* user-defined strings & macros */
        struct roffkv   *xmbtab; /* multi-byte trans table (`tr') */
@@ -122,6 +119,11 @@ struct     roff {
        struct eqn_node *last_eqn; /* last equation parsed */
        struct eqn_node *first_eqn; /* first equation parsed */
        struct eqn_node *eqn; /* current equation being parsed */
+       int              options; /* parse options */
+       int              rstacksz; /* current size limit of rstack */
+       int              rstackpos; /* position in rstack */
+       int              format; /* current file in mdoc or man format */
+       char             control; /* control character */
 };
 
 struct roffnode {
@@ -420,32 +422,32 @@ roff_free1(struct roff *r)
                r->first_tbl = tbl->next;
                tbl_free(tbl);
        }
-
        r->first_tbl = r->last_tbl = r->tbl = NULL;
 
        while (NULL != (e = r->first_eqn)) {
                r->first_eqn = e->next;
                eqn_free(e);
        }
-
        r->first_eqn = r->last_eqn = r->eqn = NULL;
 
        while (r->last)
                roffnode_pop(r);
 
-       roff_freestr(r->strtab);
-       roff_freestr(r->xmbtab);
-
-       r->strtab = r->xmbtab = NULL;
+       free (r->rstack);
+       r->rstack = NULL;
+       r->rstacksz = 0;
+       r->rstackpos = -1;
 
        roff_freereg(r->regtab);
-
        r->regtab = NULL;
 
+       roff_freestr(r->strtab);
+       roff_freestr(r->xmbtab);
+       r->strtab = r->xmbtab = NULL;
+
        if (r->xtab)
                for (i = 0; i < 128; i++)
                        free(r->xtab[i].p);
-
        free(r->xtab);
        r->xtab = NULL;
 }
@@ -455,6 +457,7 @@ roff_reset(struct roff *r)
 {
 
        roff_free1(r);
+       r->format = r->options & (MPARSE_MDOC | MPARSE_MAN);
        r->control = 0;
 }
 
@@ -474,6 +477,7 @@ roff_alloc(struct mparse *parse, int options)
        r = mandoc_calloc(1, sizeof(struct roff));
        r->parse = parse;
        r->options = options;
+       r->format = options & (MPARSE_MDOC | MPARSE_MAN);
        r->rstackpos = -1;
 
        roffhash_init();
@@ -786,18 +790,19 @@ roff_endparse(struct roff *r)
 {
 
        if (r->last)
-               mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse,
-                   r->last->line, r->last->col, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOEND, r->parse,
+                   r->last->line, r->last->col,
+                   roffs[r->last->tok].name);
 
        if (r->eqn) {
-               mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse,
-                   r->eqn->eqn.ln, r->eqn->eqn.pos, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOEND, r->parse,
+                   r->eqn->eqn.ln, r->eqn->eqn.pos, "EQ");
                eqn_end(&r->eqn);
        }
 
        if (r->tbl) {
-               mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse,
-                   r->tbl->line, r->tbl->pos, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOEND, r->parse,
+                   r->tbl->line, r->tbl->pos, "TS");
                tbl_end(&r->tbl);
        }
 }
@@ -841,7 +846,8 @@ roff_cblock(ROFF_ARGS)
         */
 
        if (NULL == r->last) {
-               mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse,
+                   ln, ppos, "..");
                return(ROFF_IGN);
        }
 
@@ -859,7 +865,8 @@ roff_cblock(ROFF_ARGS)
        case ROFF_ig:
                break;
        default:
-               mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse,
+                   ln, ppos, "..");
                return(ROFF_IGN);
        }
 
@@ -889,7 +896,8 @@ roff_ccond(struct roff *r, int ln, int ppos)
 {
 
        if (NULL == r->last) {
-               mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse,
+                   ln, ppos, "\\}");
                return;
        }
 
@@ -901,12 +909,14 @@ roff_ccond(struct roff *r, int ln, int ppos)
        case ROFF_if:
                break;
        default:
-               mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse,
+                   ln, ppos, "\\}");
                return;
        }
 
        if (r->last->endspan > -1) {
-               mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse,
+                   ln, ppos, "\\}");
                return;
        }
 
@@ -1277,10 +1287,10 @@ roff_cond(ROFF_ARGS)
         */
 
        if (ROFF_ie == tok) {
-               if (r->rstackpos == RSTACK_MAX - 1) {
-                       mandoc_msg(MANDOCERR_MEM,
-                           r->parse, ln, ppos, NULL);
-                       return(ROFF_ERR);
+               if (r->rstackpos + 1 == r->rstacksz) {
+                       r->rstacksz += 16;
+                       r->rstack = mandoc_reallocarray(r->rstack,
+                           r->rstacksz, sizeof(int));
                }
                r->rstack[++r->rstackpos] = !r->last->rule;
        }
@@ -1752,7 +1762,7 @@ roff_it(ROFF_ARGS)
        len = strcspn(cp, " \t");
        cp[len] = '\0';
        if ((iv = mandoc_strntoi(cp, len, 10)) <= 0) {
-               mandoc_msg(MANDOCERR_NUMERIC, r->parse,
+               mandoc_msg(MANDOCERR_IT_NONUM, r->parse,
                    ln, ppos, *bufp + 1);
                return(ROFF_IGN);
        }
@@ -1769,10 +1779,13 @@ roff_Dd(ROFF_ARGS)
 {
        const char *const       *cp;
 
-       if (0 == ((MPARSE_MDOC | MPARSE_QUICK) & r->options))
+       if ((r->options & (MPARSE_MDOC | MPARSE_QUICK)) == 0)
                for (cp = __mdoc_reserved; *cp; cp++)
                        roff_setstr(r, *cp, NULL, 0);
 
+       if (r->format == 0)
+               r->format = MPARSE_MDOC;
+
        return(ROFF_CONT);
 }
 
@@ -1781,10 +1794,13 @@ roff_TH(ROFF_ARGS)
 {
        const char *const       *cp;
 
-       if (0 == (MPARSE_QUICK & r->options))
+       if ((r->options & MPARSE_QUICK) == 0)
                for (cp = __man_reserved; *cp; cp++)
                        roff_setstr(r, *cp, NULL, 0);
 
+       if (r->format == 0)
+               r->format = MPARSE_MAN;
+
        return(ROFF_CONT);
 }
 
@@ -1793,7 +1809,8 @@ roff_TE(ROFF_ARGS)
 {
 
        if (NULL == r->tbl)
-               mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse,
+                   ln, ppos, "TE");
        else
                tbl_end(&r->tbl);
 
@@ -1805,7 +1822,8 @@ roff_T_(ROFF_ARGS)
 {
 
        if (NULL == r->tbl)
-               mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
+               mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse,
+                   ln, ppos, "T&");
        else
                tbl_restart(ppos, ln, r->tbl);
 
@@ -1856,7 +1874,7 @@ static enum rofferr
 roff_EN(ROFF_ARGS)
 {
 
-       mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
+       mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, ln, ppos, "EN");
        return(ROFF_IGN);
 }
 
@@ -1866,7 +1884,8 @@ roff_TS(ROFF_ARGS)
        struct tbl_node *tbl;
 
        if (r->tbl) {
-               mandoc_msg(MANDOCERR_SCOPEBROKEN, r->parse, ln, ppos, NULL);
+               mandoc_msg(MANDOCERR_BLK_BROKEN, r->parse,
+                   ln, ppos, "TS breaks TS");
                tbl_end(&r->tbl);
        }
 
@@ -1965,7 +1984,7 @@ roff_so(ROFF_ARGS)
        char *name;
 
        name = *bufp + pos;
-       mandoc_vmsg(MANDOCERR_SO, r->parse, ln, ppos, ".so %s", name);
+       mandoc_vmsg(MANDOCERR_SO, r->parse, ln, ppos, "so %s", name);
 
        /*
         * Handle `so'.  Be EXTREMELY careful, as we shouldn't be
@@ -2057,7 +2076,8 @@ roff_getname(struct roff *r, char **cpp, int ln, int pos)
                cp++;
                if ('\\' == *cp)
                        continue;
-               mandoc_msg(MANDOCERR_NAMESC, r->parse, ln, pos, NULL);
+               mandoc_vmsg(MANDOCERR_NAMESC, r->parse, ln, pos,
+                   "%.*s", (int)(cp - name + 1), name);
                mandoc_escape((const char **)&cp, NULL, NULL);
                break;
        }
@@ -2296,6 +2316,13 @@ roff_strdup(const struct roff *r, const char *p)
        return(res);
 }
 
+int
+roff_getformat(const struct roff *r)
+{
+
+       return(r->format);
+}
+
 /*
  * Find out whether a line is a macro line or not.
  * If it is, adjust the current position and return one; if it isn't,