aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/eqn.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-07-06 00:19:54 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-07-06 00:19:54 +0000
commit85dde46a7c3beea67394f0a89322372457dcbbf4 (patch)
treeb005a91c14c7f0f5b74bbd5744dc6c218bdce789 /eqn.c
parentacb30a24128863f2d57ac9aa20a93c8dd243b80b (diff)
downloadmandoc-85dde46a7c3beea67394f0a89322372457dcbbf4.tar.gz
mandoc-85dde46a7c3beea67394f0a89322372457dcbbf4.tar.zst
mandoc-85dde46a7c3beea67394f0a89322372457dcbbf4.zip
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 'eqn.c')
-rw-r--r--eqn.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/eqn.c b/eqn.c
index 4806b933..6711d4f6 100644
--- a/eqn.c
+++ b/eqn.c
@@ -1,4 +1,4 @@
-/* $Id: eqn.c,v 1.73 2017/07/05 15:03:27 schwarze Exp $ */
+/* $Id: eqn.c,v 1.74 2017/07/06 00:19:54 schwarze Exp $ */
/*
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -819,6 +819,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,13 +842,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;
@@ -895,6 +909,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);
@@ -1099,13 +1115,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();