diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2017-07-06 00:08:53 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2017-07-06 00:08:53 +0000 |
commit | 64da98b2200848a909217a97925e326be60b8eb2 (patch) | |
tree | a7e75fa9de1102786254e434ae1e3f7ec1fa01c8 /usr.bin/mandoc | |
parent | 3bfa6cac118b9219cc28d93116433ad0217bcbe3 (diff) |
Fix operator precedence according to Brian W. Kernighan and Lorinda
L. Cherry, "Typesetting Mathematics - User's Guide (Second Edition)",
August 15, 1978, paragraph 23; swarm of bugs pointed out by bentley@.
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r-- | usr.bin/mandoc/eqn.c | 31 | ||||
-rw-r--r-- | usr.bin/mandoc/eqn_term.c | 19 |
2 files changed, 29 insertions, 21 deletions
diff --git a/usr.bin/mandoc/eqn.c b/usr.bin/mandoc/eqn.c index 251a87aa816..e0775f1ac6e 100644 --- a/usr.bin/mandoc/eqn.c +++ b/usr.bin/mandoc/eqn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eqn.c,v 1.36 2017/07/05 15:03:20 schwarze Exp $ */ +/* $OpenBSD: eqn.c,v 1.37 2017/07/06 00:08:52 schwarze Exp $ */ /* * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -817,6 +817,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; @@ -838,13 +840,25 @@ 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; @@ -893,6 +907,8 @@ 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); @@ -1097,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(); diff --git a/usr.bin/mandoc/eqn_term.c b/usr.bin/mandoc/eqn_term.c index f41bc1d4129..503919fdbf8 100644 --- a/usr.bin/mandoc/eqn_term.c +++ b/usr.bin/mandoc/eqn_term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eqn_term.c,v 1.6 2017/07/05 15:03:20 schwarze Exp $ */ +/* $OpenBSD: eqn_term.c,v 1.7 2017/07/06 00:08:52 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -111,15 +111,6 @@ eqn_box(struct termp *p, const struct eqn_box *bp) if (bp->font != EQNFONT_NONE) term_fontpop(p); - if ((bp->type == EQN_LIST && bp->expectargs > 1) || - (bp->type == EQN_PILE && (bp->prev || bp->next)) || - (bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) { - p->flags |= TERMP_NOSPACE; - term_word(p, bp->right != NULL ? bp->right : ")"); - if (bp->parent->type == EQN_SUBEXPR && bp->next != NULL) - p->flags |= TERMP_NOSPACE; - } - if (bp->top != NULL) { p->flags |= TERMP_NOSPACE; term_word(p, bp->top); @@ -128,4 +119,12 @@ eqn_box(struct termp *p, const struct eqn_box *bp) p->flags |= TERMP_NOSPACE; term_word(p, "_"); } + if ((bp->type == EQN_LIST && bp->expectargs > 1) || + (bp->type == EQN_PILE && (bp->prev || bp->next)) || + (bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) { + p->flags |= TERMP_NOSPACE; + term_word(p, bp->right != NULL ? bp->right : ")"); + if (bp->parent->type == EQN_SUBEXPR && bp->next != NULL) + p->flags |= TERMP_NOSPACE; + } } |