=================================================================== RCS file: /cvs/mandoc/eqn.c,v retrieving revision 1.73 retrieving revision 1.75 diff -u -p -r1.73 -r1.75 --- mandoc/eqn.c 2017/07/05 15:03:27 1.73 +++ mandoc/eqn.c 2017/07/07 17:16:17 1.75 @@ -1,4 +1,4 @@ -/* $Id: eqn.c,v 1.73 2017/07/05 15:03:27 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; @@ -728,7 +725,7 @@ next_tok: cur->type = EQN_TEXT; cur->text = mandoc_strdup(""); } - parent = eqn_box_makebinary(ep, EQNPOS_NONE, parent); + parent = eqn_box_makebinary(ep, parent); parent->type = EQN_LIST; parent->expectargs = 1; parent->font = EQNFONT_ROMAN; @@ -819,6 +816,8 @@ next_tok: ep->gsize = size; break; } + while (parent->args == parent->expectargs) + parent = parent->parent; parent = eqn_box_alloc(ep, parent); parent->type = EQN_LIST; parent->expectargs = 1; @@ -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: @@ -1099,13 +1113,6 @@ next_tok: parent = split->parent; break; } - /* - * Post-process list status. - */ - while (parent->type == EQN_LIST && - parent->expectargs == 1 && - parent->args == 1) - parent = parent->parent; break; default: abort();