=================================================================== RCS file: /cvs/mandoc/eqn.c,v retrieving revision 1.71 retrieving revision 1.75 diff -u -p -r1.71 -r1.75 --- mandoc/eqn.c 2017/06/26 20:09:04 1.71 +++ mandoc/eqn.c 2017/07/07 17:16:17 1.75 @@ -1,4 +1,4 @@ -/* $Id: eqn.c,v 1.71 2017/06/26 20:09:04 schwarze Exp $ */ +/* $Id: eqn.c,v 1.75 2017/07/07 17:16:17 schwarze Exp $ */ /* * Copyright (c) 2011, 2014 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2017 Ingo Schwarze @@ -286,7 +286,7 @@ 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 *, - enum eqn_post, struct eqn_box *); + 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 *); @@ -541,8 +541,7 @@ eqn_box_alloc(struct eqn_node *ep, struct eqn_box *par * The new EQN_SUBEXPR will have a two-child limit. */ static struct eqn_box * -eqn_box_makebinary(struct eqn_node *ep, - enum eqn_post pos, struct eqn_box *parent) +eqn_box_makebinary(struct eqn_node *ep, struct eqn_box *parent) { struct eqn_box *b, *newb; @@ -554,7 +553,6 @@ eqn_box_makebinary(struct eqn_node *ep, parent->last = b->prev; b->prev = NULL; newb = eqn_box_alloc(ep, parent); - newb->pos = pos; newb->type = EQN_SUBEXPR; newb->expectargs = 2; newb->args = 1; @@ -669,7 +667,6 @@ eqn_parse(struct eqn_node *ep, struct eqn_box *parent) const char *cp, *cpn; char *p; enum eqn_tok tok; - enum eqn_post pos; enum { CCL_LET, CCL_DIG, CCL_PUN } ccl, ccln; int size; @@ -683,7 +680,7 @@ eqn_parse(struct eqn_node *ep, struct eqn_box *parent) if (ep->data == NULL) return ROFF_IGN; - ep->start = ep->end = ep->data; + ep->start = ep->end = ep->data + strspn(ep->data, " ^~"); next_tok: tok = eqn_next(ep, MODE_TOK); @@ -728,8 +725,8 @@ next_tok: cur->type = EQN_TEXT; cur->text = mandoc_strdup(""); } - parent = eqn_box_makebinary(ep, EQNPOS_NONE, parent); - parent->type = EQN_LISTONE; + parent = eqn_box_makebinary(ep, parent); + parent->type = EQN_LIST; parent->expectargs = 1; parent->font = EQNFONT_ROMAN; switch (tok) { @@ -782,7 +779,7 @@ next_tok: * exactly one of those. */ parent = eqn_box_alloc(ep, parent); - parent->type = EQN_LISTONE; + parent->type = EQN_LIST; parent->expectargs = 1; switch (tok) { case EQN_TOK_FAT: @@ -819,8 +816,10 @@ next_tok: ep->gsize = size; break; } + while (parent->args == parent->expectargs) + parent = parent->parent; parent = eqn_box_alloc(ep, parent); - parent->type = EQN_LISTONE; + parent->type = EQN_LIST; parent->expectargs = 1; parent->size = size; break; @@ -840,34 +839,46 @@ next_tok: cur->type = EQN_TEXT; cur->text = mandoc_strdup(""); } - /* Handle the "subsup" and "fromto" positions. */ - if (EQN_TOK_SUP == tok && parent->pos == EQNPOS_SUB) { + while (parent->expectargs == 1 && parent->args == 1) + parent = parent->parent; + if (tok == EQN_TOK_FROM || tok == EQN_TOK_TO) { + for (cur = parent; cur != NULL; cur = cur->parent) + if (cur->pos == EQNPOS_SUB || + cur->pos == EQNPOS_SUP || + cur->pos == EQNPOS_SUBSUP || + cur->pos == EQNPOS_SQRT || + cur->pos == EQNPOS_OVER) + break; + if (cur != NULL) + parent = cur->parent; + } + if (tok == EQN_TOK_SUP && parent->pos == EQNPOS_SUB) { parent->expectargs = 3; parent->pos = EQNPOS_SUBSUP; break; } - if (EQN_TOK_TO == tok && parent->pos == EQNPOS_FROM) { + if (tok == EQN_TOK_TO && parent->pos == EQNPOS_FROM) { parent->expectargs = 3; parent->pos = EQNPOS_FROMTO; break; } + parent = eqn_box_makebinary(ep, parent); switch (tok) { case EQN_TOK_FROM: - pos = EQNPOS_FROM; + parent->pos = EQNPOS_FROM; break; case EQN_TOK_TO: - pos = EQNPOS_TO; + parent->pos = EQNPOS_TO; break; case EQN_TOK_SUP: - pos = EQNPOS_SUP; + parent->pos = EQNPOS_SUP; break; case EQN_TOK_SUB: - pos = EQNPOS_SUB; + parent->pos = EQNPOS_SUB; break; default: abort(); } - parent = eqn_box_makebinary(ep, pos, parent); break; case EQN_TOK_SQRT: while (parent->args == parent->expectargs) @@ -895,9 +906,12 @@ next_tok: cur->type = EQN_TEXT; cur->text = mandoc_strdup(""); } + while (parent->args == parent->expectargs) + parent = parent->parent; while (EQN_SUBEXPR == parent->type) parent = parent->parent; - parent = eqn_box_makebinary(ep, EQNPOS_OVER, parent); + parent = eqn_box_makebinary(ep, parent); + parent->pos = EQNPOS_OVER; break; case EQN_TOK_RIGHT: case EQN_TOK_BRACE_CLOSE: @@ -908,6 +922,7 @@ next_tok: */ for (cur = parent; cur != NULL; cur = cur->parent) if (cur->type == EQN_LIST && + cur->expectargs > 1 && (tok == EQN_TOK_BRACE_CLOSE || cur->left != NULL)) break; @@ -939,8 +954,9 @@ next_tok: parent->type == EQN_MATRIX)) parent = parent->parent; /* Close out any "singleton" lists. */ - while (parent->type == EQN_LISTONE && - parent->args == parent->expectargs) + while (parent->type == EQN_LIST && + parent->expectargs == 1 && + parent->args == 1) parent = parent->parent; break; case EQN_TOK_BRACE_OPEN: @@ -1097,12 +1113,6 @@ next_tok: parent = split->parent; break; } - /* - * Post-process list status. - */ - while (parent->type == EQN_LISTONE && - parent->args == parent->expectargs) - parent = parent->parent; break; default: abort();