1. Eliminate struct eqn, instead use the existing members
authorschwarze <schwarze@openbsd.org>
Sat, 8 Jul 2017 14:51:01 +0000 (14:51 +0000)
committerschwarze <schwarze@openbsd.org>
Sat, 8 Jul 2017 14:51:01 +0000 (14:51 +0000)
of struct roff_node which is allocated for each equation anyway.
2. Do not keep a list of equation parsers, one parser is enough.
Minus fifty lines of code, no functional change.

13 files changed:
usr.bin/mandoc/eqn.c
usr.bin/mandoc/eqn_html.c
usr.bin/mandoc/eqn_term.c
usr.bin/mandoc/html.h
usr.bin/mandoc/libmandoc.h
usr.bin/mandoc/libroff.h
usr.bin/mandoc/mandoc.h
usr.bin/mandoc/read.c
usr.bin/mandoc/roff.c
usr.bin/mandoc/roff.h
usr.bin/mandoc/roff_int.h
usr.bin/mandoc/term.h
usr.bin/mandoc/tree.c

index fb65cb8..4de6117 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: eqn.c,v 1.38 2017/07/07 17:15:21 schwarze Exp $ */
+/*     $OpenBSD: eqn.c,v 1.39 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -25,8 +25,9 @@
 #include <string.h>
 #include <time.h>
 
-#include "mandoc.h"
 #include "mandoc_aux.h"
+#include "mandoc.h"
+#include "roff.h"
 #include "libmandoc.h"
 #include "libroff.h"
 
@@ -282,76 +283,48 @@ enum      parse_mode {
 };
 
 static struct eqn_box  *eqn_box_alloc(struct eqn_node *, struct eqn_box *);
-static void             eqn_box_free(struct eqn_box *);
 static struct eqn_box  *eqn_box_makebinary(struct eqn_node *,
                                struct eqn_box *);
 static void             eqn_def(struct eqn_node *);
 static struct eqn_def  *eqn_def_find(struct eqn_node *);
 static void             eqn_delim(struct eqn_node *);
 static enum eqn_tok     eqn_next(struct eqn_node *, enum parse_mode);
-static enum rofferr     eqn_parse(struct eqn_node *, struct eqn_box *);
 static void             eqn_undef(struct eqn_node *);
 
 
-enum rofferr
-eqn_read(struct eqn_node **epp, int ln,
-               const char *p, int pos, int *offs)
+struct eqn_node *
+eqn_alloc(struct mparse *parse)
 {
-       size_t           sz;
-       struct eqn_node *ep;
-       enum rofferr     er;
-
-       ep = *epp;
-
-       /*
-        * If we're the terminating mark, unset our equation status and
-        * validate the full equation.
-        */
+       struct eqn_node *ep;
 
-       if (0 == strncmp(p, ".EN", 3)) {
-               er = eqn_end(epp);
-               p += 3;
-               while (' ' == *p || '\t' == *p)
-                       p++;
-               if ('\0' == *p)
-                       return er;
-               mandoc_vmsg(MANDOCERR_ARG_SKIP, ep->parse,
-                   ln, pos, "EN %s", p);
-               return er;
-       }
-
-       /*
-        * Build up the full string, replacing all newlines with regular
-        * whitespace.
-        */
-
-       sz = strlen(p + pos) + 1;
-       ep->data = mandoc_realloc(ep->data, ep->sz + sz + 1);
-
-       /* First invocation: nil terminate the string. */
-
-       if (0 == ep->sz)
-               *ep->data = '\0';
-
-       ep->sz += sz;
-       strlcat(ep->data, p + pos, ep->sz + 1);
-       strlcat(ep->data, " ", ep->sz + 1);
-       return ROFF_IGN;
+       ep = mandoc_calloc(1, sizeof(*ep));
+       ep->parse = parse;
+       ep->gsize = EQN_DEFSIZE;
+       return ep;
 }
 
-struct eqn_node *
-eqn_alloc(int pos, int line, struct mparse *parse)
+void
+eqn_reset(struct eqn_node *ep)
 {
-       struct eqn_node *p;
-
-       p = mandoc_calloc(1, sizeof(struct eqn_node));
+       free(ep->data);
+       ep->data = ep->start = ep->end = NULL;
+       ep->sz = ep->toksz = 0;
+}
 
-       p->parse = parse;
-       p->eqn.ln = line;
-       p->eqn.pos = pos;
-       p->gsize = EQN_DEFSIZE;
+void
+eqn_read(struct eqn_node *ep, const char *p)
+{
+       char            *cp;
 
-       return p;
+       if (ep->data == NULL) {
+               ep->sz = strlen(p);
+               ep->data = mandoc_strdup(p);
+       } else {
+               ep->sz = mandoc_asprintf(&cp, "%s %s", ep->data, p);
+               free(ep->data);
+               ep->data = cp;
+       }
+       ep->sz += 1;
 }
 
 /*
@@ -425,7 +398,7 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode)
                        ep->start++;  /* Skip opening quote. */
                        if (ep->end == NULL) {
                                mandoc_msg(MANDOCERR_ARG_QUOTE, ep->parse,
-                                   ep->eqn.ln, ep->eqn.pos, NULL);
+                                   ep->node->line, ep->node->pos, NULL);
                                ep->end = strchr(ep->start, '\0');
                        }
                } else {
@@ -446,7 +419,7 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode)
                        break;
                if (++lim > EQN_NEST_MAX) {
                        mandoc_msg(MANDOCERR_ROFFLOOP, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, NULL);
+                           ep->node->line, ep->node->pos, NULL);
                        return EQN_TOK_EOF;
                }
 
@@ -490,7 +463,7 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode)
        return EQN_TOK__MAX;
 }
 
-static void
+void
 eqn_box_free(struct eqn_box *bp)
 {
 
@@ -568,7 +541,7 @@ eqn_delim(struct eqn_node *ep)
 {
        if (ep->end[0] == '\0' || ep->end[1] == '\0') {
                mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
-                   ep->eqn.ln, ep->eqn.pos, "delim");
+                   ep->node->line, ep->node->pos, "delim");
                if (ep->end[0] != '\0')
                        ep->end++;
        } else if (strncmp(ep->end, "off", 3) == 0) {
@@ -595,7 +568,7 @@ eqn_undef(struct eqn_node *ep)
 
        if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF) {
                mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
-                   ep->eqn.ln, ep->eqn.pos, "undef");
+                   ep->node->line, ep->node->pos, "undef");
                return;
        }
        if ((def = eqn_def_find(ep)) == NULL)
@@ -614,7 +587,7 @@ eqn_def(struct eqn_node *ep)
 
        if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF) {
                mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
-                   ep->eqn.ln, ep->eqn.pos, "define");
+                   ep->node->line, ep->node->pos, "define");
                return;
        }
 
@@ -643,7 +616,7 @@ eqn_def(struct eqn_node *ep)
 
        if (eqn_next(ep, MODE_QUOTED) == EQN_TOK_EOF) {
                mandoc_vmsg(MANDOCERR_REQ_EMPTY, ep->parse,
-                   ep->eqn.ln, ep->eqn.pos, "define %s", def->key);
+                   ep->node->line, ep->node->pos, "define %s", def->key);
                free(def->key);
                free(def->val);
                def->key = def->val = NULL;
@@ -655,19 +628,17 @@ eqn_def(struct eqn_node *ep)
        def->valsz = ep->toksz;
 }
 
-/*
- * Recursively parse an eqn(7) expression.
- */
-static enum rofferr
-eqn_parse(struct eqn_node *ep, struct eqn_box *parent)
+void
+eqn_parse(struct eqn_node *ep)
 {
-       struct eqn_box  *cur, *nbox, *split;
+       struct eqn_box  *cur, *nbox, *parent, *split;
        const char      *cp, *cpn;
        char            *p;
        enum eqn_tok     tok;
        enum { CCL_LET, CCL_DIG, CCL_PUN } ccl, ccln;
        int              size;
 
+       parent = ep->node->eqn;
        assert(parent != NULL);
 
        /*
@@ -676,7 +647,7 @@ eqn_parse(struct eqn_node *ep, struct eqn_box *parent)
         */
 
        if (ep->data == NULL)
-               return ROFF_IGN;
+               return;
 
        ep->start = ep->end = ep->data + strspn(ep->data, " ^~");
 
@@ -694,7 +665,7 @@ next_tok:
                if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF ||
                    eqn_next(ep, MODE_QUOTED) == EQN_TOK_EOF)
                        mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, "tdefine");
+                           ep->node->line, ep->node->pos, "tdefine");
                break;
        case EQN_TOK_DELIM:
                eqn_delim(ep);
@@ -702,7 +673,7 @@ next_tok:
        case EQN_TOK_GFONT:
                if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF)
                        mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                break;
        case EQN_TOK_MARK:
        case EQN_TOK_LINEUP:
@@ -718,7 +689,7 @@ next_tok:
        case EQN_TOK_DOTDOT:
                if (parent->last == NULL) {
                        mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                        cur = eqn_box_alloc(ep, parent);
                        cur->type = EQN_TEXT;
                        cur->text = mandoc_strdup("");
@@ -763,7 +734,7 @@ next_tok:
        case EQN_TOK_UP:
                if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF)
                        mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                break;
        case EQN_TOK_FAT:
        case EQN_TOK_ROMAN:
@@ -801,13 +772,13 @@ next_tok:
                /* Accept two values: integral size and a single. */
                if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {
                        mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                        break;
                }
                size = mandoc_strntoi(ep->start, ep->toksz, 10);
                if (-1 == size) {
                        mandoc_msg(MANDOCERR_IT_NONUM, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                        break;
                }
                if (EQN_TOK_GSIZE == tok) {
@@ -832,7 +803,7 @@ next_tok:
                 */
                if (parent->last == NULL) {
                        mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                        cur = eqn_box_alloc(ep, parent);
                        cur->type = EQN_TEXT;
                        cur->text = mandoc_strdup("");
@@ -899,7 +870,7 @@ next_tok:
                 */
                if (parent->last == NULL) {
                        mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                        cur = eqn_box_alloc(ep, parent);
                        cur->type = EQN_TEXT;
                        cur->text = mandoc_strdup("");
@@ -926,15 +897,15 @@ next_tok:
                                break;
                if (cur == NULL) {
                        mandoc_msg(MANDOCERR_BLK_NOTOPEN, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                        break;
                }
                parent = cur;
                if (EQN_TOK_RIGHT == tok) {
                        if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {
                                mandoc_msg(MANDOCERR_REQ_EMPTY,
-                                   ep->parse, ep->eqn.ln,
-                                   ep->eqn.pos, eqn_toks[tok]);
+                                   ep->parse, ep->node->line,
+                                   ep->node->pos, eqn_toks[tok]);
                                break;
                        }
                        /* Handling depends on right/left. */
@@ -969,7 +940,7 @@ next_tok:
                if (EQN_TOK_LEFT == tok &&
                    eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {
                        mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                        break;
                }
                parent = eqn_box_alloc(ep, parent);
@@ -1003,7 +974,7 @@ next_tok:
                                break;
                if (cur == NULL) {
                        mandoc_msg(MANDOCERR_IT_STRAY, ep->parse,
-                           ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
+                           ep->node->line, ep->node->pos, eqn_toks[tok]);
                        break;
                }
                parent = eqn_box_alloc(ep, cur);
@@ -1017,11 +988,7 @@ next_tok:
                parent->expectargs = 1;
                break;
        case EQN_TOK_EOF:
-               /*
-                * End of file!
-                * TODO: make sure we're not in an open subexpression.
-                */
-               return ROFF_EQN;
+               return;
        case EQN_TOK__MAX:
        case EQN_TOK_FUNC:
        case EQN_TOK_QUOTED:
@@ -1118,26 +1085,11 @@ next_tok:
        goto next_tok;
 }
 
-enum rofferr
-eqn_end(struct eqn_node **epp)
-{
-       struct eqn_node *ep;
-
-       ep = *epp;
-       *epp = NULL;
-
-       ep->eqn.root = mandoc_calloc(1, sizeof(struct eqn_box));
-       ep->eqn.root->expectargs = UINT_MAX;
-       return eqn_parse(ep, ep->eqn.root);
-}
-
 void
 eqn_free(struct eqn_node *p)
 {
        int              i;
 
-       eqn_box_free(p->eqn.root);
-
        for (i = 0; i < (int)p->defsz; i++) {
                free(p->defs[i].key);
                free(p->defs[i].val);
index 82e68f2..b725bfc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: eqn_html.c,v 1.11 2017/07/05 15:03:20 schwarze Exp $ */
+/*     $OpenBSD: eqn_html.c,v 1.12 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -225,14 +225,14 @@ out:
 }
 
 void
-print_eqn(struct html *p, const struct eqn *ep)
+print_eqn(struct html *p, const struct eqn_box *bp)
 {
        struct tag      *t;
 
        t = print_otag(p, TAG_MATH, "c", "eqn");
 
        p->flags |= HTML_NONOSPACE;
-       eqn_box(p, ep->root);
+       eqn_box(p, bp);
        p->flags &= ~HTML_NONOSPACE;
 
        print_tagq(p, t);
index 4a48e79..8688fee 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: eqn_term.c,v 1.8 2017/07/07 19:06:15 schwarze Exp $ */
+/*     $OpenBSD: eqn_term.c,v 1.9 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -38,10 +38,10 @@ static void eqn_box(struct termp *, const struct eqn_box *);
 
 
 void
-term_eqn(struct termp *p, const struct eqn *ep)
+term_eqn(struct termp *p, const struct eqn_box *bp)
 {
 
-       eqn_box(p, ep->root);
+       eqn_box(p, bp);
        p->flags &= ~TERMP_NOSPACE;
 }
 
index 94fd059..234ab44 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: html.h,v 1.48 2017/06/23 02:31:39 schwarze Exp $ */
+/*     $OpenBSD: html.h,v 1.49 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -115,7 +115,7 @@ struct      html {
 
 struct roff_node;
 struct tbl_span;
-struct eqn;
+struct eqn_box;
 
 void             roff_html_pre(struct html *, const struct roff_node *);
 
@@ -127,7 +127,7 @@ void                  print_stagq(struct html *, const struct tag *);
 void             print_text(struct html *, const char *);
 void             print_tblclose(struct html *);
 void             print_tbl(struct html *, const struct tbl_span *);
-void             print_eqn(struct html *, const struct eqn *);
+void             print_eqn(struct html *, const struct eqn_box *);
 void             print_paragraph(struct html *);
 void             print_endline(struct html *);
 
index 4b42b61..b526498 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: libmandoc.h,v 1.53 2017/06/11 19:36:31 schwarze Exp $ */
+/*     $OpenBSD: libmandoc.h,v 1.54 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -24,7 +24,6 @@ enum  rofferr {
        ROFF_SO, /* include another file */
        ROFF_IGN, /* ignore current line */
        ROFF_TBL, /* a table row was successfully parsed */
-       ROFF_EQN /* an equation was successfully parsed */
 };
 
 struct buf {
@@ -35,7 +34,6 @@ struct        buf {
 
 struct mparse;
 struct tbl_span;
-struct eqn;
 struct roff;
 struct roff_man;
 
@@ -77,4 +75,3 @@ int            roff_getcontrol(const struct roff *,
 int             roff_getformat(const struct roff *);
 
 const struct tbl_span  *roff_span(const struct roff *);
-const struct eqn       *roff_eqn(const struct roff *);
index 3beca8c..532333a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: libroff.h,v 1.18 2017/06/26 19:53:00 schwarze Exp $ */
+/*     $OpenBSD: libroff.h,v 1.19 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -38,9 +38,8 @@ struct        tbl_node {
 };
 
 struct eqn_node {
-       struct eqn        eqn;    /* syntax tree of this equation */
        struct mparse    *parse;  /* main parser, for error reporting */
-       struct eqn_node  *next;   /* singly linked list of equations */
+       struct roff_node *node;   /* syntax tree of this equation */
        struct eqn_def   *defs;   /* array of definitions */
        char             *data;   /* source code of this equation */
        char             *start;  /* first byte of the current token */
@@ -73,8 +72,9 @@ void           tbl_data(struct tbl_node *, int, const char *, int);
 int             tbl_cdata(struct tbl_node *, int, const char *, int);
 const struct tbl_span  *tbl_span(struct tbl_node *);
 int             tbl_end(struct tbl_node **);
-struct eqn_node        *eqn_alloc(int, int, struct mparse *);
-enum rofferr    eqn_end(struct eqn_node **);
+struct eqn_node        *eqn_alloc(struct mparse *);
+void            eqn_box_free(struct eqn_box *);
 void            eqn_free(struct eqn_node *);
-enum rofferr    eqn_read(struct eqn_node **, int,
-                       const char *, int, int *);
+void            eqn_parse(struct eqn_node *);
+void            eqn_read(struct eqn_node *, const char *);
+void            eqn_reset(struct eqn_node *);
index b78d886..8f4d4ee 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mandoc.h,v 1.186 2017/07/07 19:39:17 schwarze Exp $ */
+/*     $OpenBSD: mandoc.h,v 1.187 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -401,17 +401,6 @@ struct     eqn_box {
        enum eqn_pilet    pile; /* equation piling */
 };
 
-/*
- * An equation consists of a tree of expressions starting at a given
- * line and position.
- */
-struct eqn {
-       char             *name; /* identifier (or NULL) */
-       struct eqn_box   *root; /* root mathematical expression */
-       int               ln; /* invocation line */
-       int               pos; /* invocation position */
-};
-
 /*
  * Parse options.
  */
index d5c9e6d..3636e1c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: read.c,v 1.161 2017/07/06 22:58:44 schwarze Exp $ */
+/*     $OpenBSD: read.c,v 1.162 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -536,14 +536,11 @@ rerun:
                 * currently open parse.  Since we only get here if
                 * there does exist data (see tbl_data.c), we're
                 * guaranteed that something's been allocated.
-                * Do the same for ROFF_EQN.
                 */
 
                if (rr == ROFF_TBL)
                        while ((span = roff_span(curp->roff)) != NULL)
                                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)
index 6d085c5..a645b02 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: roff.c,v 1.190 2017/07/04 22:49:59 schwarze Exp $ */
+/*     $OpenBSD: roff.c,v 1.191 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -96,9 +96,8 @@ struct        roff {
        struct tbl_node *first_tbl; /* first table parsed */
        struct tbl_node *last_tbl; /* last table parsed */
        struct tbl_node *tbl; /* current table being parsed */
-       struct eqn_node *last_eqn; /* last equation parsed */
-       struct eqn_node *first_eqn; /* first equation parsed */
-       struct eqn_node *eqn; /* current equation being parsed */
+       struct eqn_node *last_eqn; /* equation parser */
+       struct eqn_node *eqn; /* active equation parser */
        int              eqn_inline; /* current equation is inline */
        int              options; /* parse options */
        int              rstacksz; /* current size limit of rstack */
@@ -693,7 +692,6 @@ static void
 roff_free1(struct roff *r)
 {
        struct tbl_node *tbl;
-       struct eqn_node *e;
        int              i;
 
        while (NULL != (tbl = r->first_tbl)) {
@@ -702,11 +700,9 @@ roff_free1(struct roff *r)
        }
        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;
+       if (r->last_eqn != NULL)
+               eqn_free(r->last_eqn);
+       r->last_eqn = r->eqn = NULL;
 
        while (r->last)
                roffnode_pop(r);
@@ -981,19 +977,6 @@ roff_body_alloc(struct roff_man *man, int line, int pos, int tok)
        return n;
 }
 
-void
-roff_addeqn(struct roff_man *man, const struct eqn *eqn)
-{
-       struct roff_node        *n;
-
-       n = roff_node_alloc(man, eqn->ln, eqn->pos, ROFFT_EQN, TOKEN_NONE);
-       n->eqn = eqn;
-       if (eqn->ln > man->last->line)
-               n->flags |= NODE_LINE;
-       roff_node_append(man, n);
-       man->next = ROFF_NEXT_SIBLING;
-}
-
 void
 roff_addtbl(struct roff_man *man, const struct tbl_span *tbl)
 {
@@ -1053,6 +1036,8 @@ roff_node_free(struct roff_node *n)
                mdoc_argv_free(n->args);
        if (n->type == ROFFT_BLOCK || n->type == ROFFT_ELEM)
                free(n->norm);
+       if (n->eqn != NULL)
+               eqn_box_free(n->eqn);
        free(n->string);
        free(n);
 }
@@ -1510,8 +1495,10 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs)
                        return e;
                assert(e == ROFF_CONT);
        }
-       if (r->eqn != NULL)
-               return eqn_read(&r->eqn, ln, buf->buf, ppos, offs);
+       if (r->eqn != NULL && strncmp(buf->buf + ppos, ".EN", 3)) {
+               eqn_read(r->eqn, buf->buf + ppos);
+               return ROFF_IGN;
+       }
        if (r->tbl != NULL && ( ! ctl || buf->buf[pos] == '\0'))
                return tbl_read(r->tbl, ln, buf->buf, ppos);
        if ( ! ctl)
@@ -1591,8 +1578,9 @@ roff_endparse(struct roff *r)
 
        if (r->eqn) {
                mandoc_msg(MANDOCERR_BLK_NOEND, r->parse,
-                   r->eqn->eqn.ln, r->eqn->eqn.pos, "EQ");
-               eqn_end(&r->eqn);
+                   r->eqn->node->line, r->eqn->node->pos, "EQ");
+               eqn_parse(r->eqn);
+               r->eqn = NULL;
        }
 
        if (r->tbl) {
@@ -2875,20 +2863,23 @@ roff_eqndelim(struct roff *r, struct buf *buf, int pos)
 static enum rofferr
 roff_EQ(ROFF_ARGS)
 {
-       struct eqn_node *e;
-
-       assert(r->eqn == NULL);
-       e = eqn_alloc(ppos, ln, r->parse);
+       struct roff_node        *n;
 
-       if (r->last_eqn) {
-               r->last_eqn->next = e;
-               e->delim = r->last_eqn->delim;
-               e->odelim = r->last_eqn->odelim;
-               e->cdelim = r->last_eqn->cdelim;
-       } else
-               r->first_eqn = r->last_eqn = e;
+       n = roff_node_alloc(r->man, ln, ppos, ROFFT_EQN, TOKEN_NONE);
+       if (ln > r->man->last->line)
+               n->flags |= NODE_LINE;
+       n->eqn = mandoc_calloc(1, sizeof(*n->eqn));
+       n->eqn->expectargs = UINT_MAX;
+       roff_node_append(r->man, n);
+       r->man->next = ROFF_NEXT_SIBLING;
 
-       r->eqn = r->last_eqn = e;
+       assert(r->eqn == NULL);
+       if (r->last_eqn == NULL)
+               r->last_eqn = eqn_alloc(r->parse);
+       else
+               eqn_reset(r->last_eqn);
+       r->eqn = r->last_eqn;
+       r->eqn->node = n;
 
        if (buf->buf[pos] != '\0')
                mandoc_vmsg(MANDOCERR_ARG_SKIP, r->parse, ln, pos,
@@ -2900,8 +2891,14 @@ roff_EQ(ROFF_ARGS)
 static enum rofferr
 roff_EN(ROFF_ARGS)
 {
-
-       mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, ln, ppos, "EN");
+       if (r->eqn != NULL) {
+               eqn_parse(r->eqn);
+               r->eqn = NULL;
+       } else
+               mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, ln, ppos, "EN");
+       if (buf->buf[pos] != '\0')
+               mandoc_vmsg(MANDOCERR_ARG_SKIP, r->parse, ln, pos,
+                   "EN %s", buf->buf + pos);
        return ROFF_IGN;
 }
 
@@ -3608,13 +3605,6 @@ roff_span(const struct roff *r)
        return r->tbl ? tbl_span(r->tbl) : NULL;
 }
 
-const struct eqn *
-roff_eqn(const struct roff *r)
-{
-
-       return r->last_eqn ? &r->last_eqn->eqn : NULL;
-}
-
 /*
  * Duplicate an input string, making the appropriate character
  * conversations (as stipulated by `tr') along the way.
index a7ffc1d..2be8356 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: roff.h,v 1.39 2017/06/25 07:23:53 bentley Exp $       */
+/*     $OpenBSD: roff.h,v 1.40 2017/07/08 14:51:01 schwarze Exp $      */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -499,7 +499,7 @@ struct      roff_node {
        union mdoc_data  *norm;    /* Normalized arguments. */
        char             *string;  /* TEXT */
        const struct tbl_span *span; /* TBL */
-       const struct eqn *eqn;     /* EQN */
+       struct eqn_box   *eqn;     /* EQN */
        int               line;    /* Input file line number. */
        int               pos;     /* Input file column number. */
        int               flags;
index bae90e4..e8b7592 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: roff_int.h,v 1.7 2015/11/07 13:57:55 schwarze Exp $   */
+/*     $OpenBSD: roff_int.h,v 1.8 2017/07/08 14:51:01 schwarze Exp $   */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -25,7 +25,6 @@ void            roff_elem_alloc(struct roff_man *, int, int, int);
 struct roff_node *roff_block_alloc(struct roff_man *, int, int, int);
 struct roff_node *roff_head_alloc(struct roff_man *, int, int, int);
 struct roff_node *roff_body_alloc(struct roff_man *, int, int, int);
-void             roff_addeqn(struct roff_man *, const struct eqn *);
 void             roff_addtbl(struct roff_man *, const struct tbl_span *);
 void             roff_node_unlink(struct roff_man *, struct roff_node *);
 void             roff_node_free(struct roff_node *);
index 6a8ef60..792fc09 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: term.h,v 1.73 2017/06/17 14:55:02 schwarze Exp $ */
+/*     $OpenBSD: term.h,v 1.74 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -36,7 +36,7 @@ enum  termfont {
        TERMFONT__MAX
 };
 
-struct eqn;
+struct eqn_box;
 struct roff_meta;
 struct roff_node;
 struct tbl_span;
@@ -126,7 +126,7 @@ const char   *ascii_uc2str(int);
 
 void             roff_term_pre(struct termp *, const struct roff_node *);
 
-void             term_eqn(struct termp *, const struct eqn *);
+void             term_eqn(struct termp *, const struct eqn_box *);
 void             term_tbl(struct termp *, const struct tbl_span *);
 void             term_free(struct termp *);
 void             term_setcol(struct termp *, size_t);
index b217ad8..e7c163b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tree.c,v 1.43 2017/07/07 19:39:17 schwarze Exp $ */
+/*     $OpenBSD: tree.c,v 1.44 2017/07/08 14:51:01 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -200,7 +200,7 @@ print_mdoc(const struct roff_node *n, int indent)
        }
 
        if (n->eqn)
-               print_box(n->eqn->root->first, indent + 4);
+               print_box(n->eqn->first, indent + 4);
        if (n->child)
                print_mdoc(n->child, indent +
                    (n->type == ROFFT_BLOCK ? 2 : 4));
@@ -285,7 +285,7 @@ print_man(const struct roff_node *n, int indent)
        }
 
        if (n->eqn)
-               print_box(n->eqn->root->first, indent + 4);
+               print_box(n->eqn->first, indent + 4);
        if (n->child)
                print_man(n->child, indent +
                    (n->type == ROFFT_BLOCK ? 2 : 4));