=================================================================== RCS file: /cvs/mandoc/eqn.c,v retrieving revision 1.75 retrieving revision 1.76 diff -u -p -r1.75 -r1.76 --- mandoc/eqn.c 2017/07/07 17:16:17 1.75 +++ mandoc/eqn.c 2017/07/08 14:51:04 1.76 @@ -1,4 +1,4 @@ -/* $Id: eqn.c,v 1.75 2017/07/07 17:16:17 schwarze Exp $ */ +/* $Id: eqn.c,v 1.76 2017/07/08 14:51:04 schwarze Exp $ */ /* * Copyright (c) 2011, 2014 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2017 Ingo Schwarze @@ -27,8 +27,9 @@ #include #include -#include "mandoc.h" #include "mandoc_aux.h" +#include "mandoc.h" +#include "roff.h" #include "libmandoc.h" #include "libroff.h" @@ -284,76 +285,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; + struct eqn_node *ep; - ep = *epp; + ep = mandoc_calloc(1, sizeof(*ep)); + ep->parse = parse; + ep->gsize = EQN_DEFSIZE; + return ep; +} - /* - * If we're the terminating mark, unset our equation status and - * validate the full equation. - */ - - 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; +void +eqn_reset(struct eqn_node *ep) +{ + free(ep->data); + ep->data = ep->start = ep->end = NULL; + ep->sz = ep->toksz = 0; } -struct eqn_node * -eqn_alloc(int pos, int line, struct mparse *parse) +void +eqn_read(struct eqn_node *ep, const char *p) { - struct eqn_node *p; + char *cp; - p = mandoc_calloc(1, sizeof(struct eqn_node)); - - p->parse = parse; - p->eqn.ln = line; - p->eqn.pos = pos; - p->gsize = EQN_DEFSIZE; - - 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; } /* @@ -427,7 +400,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 { @@ -448,7 +421,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; } @@ -492,7 +465,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) { @@ -570,7 +543,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) { @@ -597,7 +570,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) @@ -616,7 +589,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; } @@ -645,7 +618,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; @@ -657,19 +630,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); /* @@ -678,7 +649,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, " ^~"); @@ -696,7 +667,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); @@ -704,7 +675,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: @@ -720,7 +691,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(""); @@ -765,7 +736,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: @@ -803,13 +774,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) { @@ -834,7 +805,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(""); @@ -901,7 +872,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(""); @@ -928,15 +899,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. */ @@ -971,7 +942,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); @@ -1005,7 +976,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); @@ -1019,11 +990,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: @@ -1120,25 +1087,10 @@ 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);