* roff conditional recursion @ 2011-04-07 0:39 Joerg Sonnenberger 2011-04-07 10:02 ` Kristaps Dzonsons 0 siblings, 1 reply; 2+ messages in thread From: Joerg Sonnenberger @ 2011-04-07 0:39 UTC (permalink / raw) To: tech [-- Attachment #1: Type: text/plain, Size: 295 bytes --] Hi Ingo, at the moment, as soon as ROFF_ie is seen, r->stackpos is incremented. This happens in roff.c 1028. But the corresponding code for handling ROFF_el in 995 doesn't decrement it again. Shouldn't it be rule = r->rstack[r->rstackpos--]; in line 998? Attached is a trivial example. Joerg [-- Attachment #2: test.1 --] [-- Type: text/plain, Size: 7901 bytes --] .de REQ . if (\n[.$] = 0) \ . return . ds @1 \$1\" . shift 1 . ie (\n[.$] = 0) \{\ . TP 10n . Text \f[CB]\*[@1]\f[] . \} . el \{\ . TP 10n . Text \f[CB]\*[@1]\~\f[]\f[I]\$*\f[] . \} . rm @1 .. .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 .REQ . test .REQ foo test2 .REQ foo test2 .REQ foo test2 ^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: roff conditional recursion 2011-04-07 0:39 roff conditional recursion Joerg Sonnenberger @ 2011-04-07 10:02 ` Kristaps Dzonsons 0 siblings, 0 replies; 2+ messages in thread From: Kristaps Dzonsons @ 2011-04-07 10:02 UTC (permalink / raw) To: tech [-- Attachment #1: Type: text/plain, Size: 672 bytes --] On 07/04/2011 02:39, Joerg Sonnenberger wrote: > Hi Ingo, > at the moment, as soon as ROFF_ie is seen, r->stackpos is incremented. > This happens in roff.c 1028. But the corresponding code for handling > ROFF_el in 995 doesn't decrement it again. Shouldn't it be > rule = r->rstack[r->rstackpos--]; > in line 998? > > Attached is a trivial example. Joerg, Enclosed is a patch that follows this logic, plus some clean-up and documentation (it works on test.1 and doesn't seem to cause problems anywhere else). The rstackpos, yes, can be safely "consumed" when the `el' is called, and need not wait until the nodes are popped. Ingo, any comments? Thanks, Kristaps [-- Attachment #2: patch.roff.txt --] [-- Type: text/plain, Size: 2209 bytes --] Index: roff.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v retrieving revision 1.131 diff -u -r1.131 roff.c --- roff.c 5 Apr 2011 22:22:33 -0000 1.131 +++ roff.c 7 Apr 2011 09:57:11 -0000 @@ -277,10 +277,6 @@ assert(r->last); p = r->last; - if (ROFF_el == p->tok) - if (r->rstackpos > -1) - r->rstackpos--; - r->last = r->last->parent; free(p->name); free(p->end); @@ -976,29 +972,20 @@ int sv; enum roffrule rule; - /* Stack overflow! */ + /* + * An `.el' has no conditional body: it will consume the value + * of the current rstack entry set in prior `ie' calls or + * defaults to DENY. + * + * If we're not an `el', however, then evaluate the conditional. + */ - if (ROFF_ie == tok && r->rstackpos == RSTACK_MAX - 1) { - mandoc_msg(MANDOCERR_MEM, r->parse, ln, ppos, NULL); - return(ROFF_ERR); - } - - /* First, evaluate the conditional. */ - - if (ROFF_el == tok) { - /* - * An `.el' will get the value of the current rstack - * entry set in prior `ie' calls or defaults to DENY. - */ - if (r->rstackpos < 0) - rule = ROFFRULE_DENY; - else - rule = r->rstack[r->rstackpos]; - } else - rule = roff_evalcond(*bufp, &pos); + rule = ROFF_el == tok ? + (r->rstackpos < 0 ? + ROFFRULE_DENY : r->rstack[r->rstackpos--]) : + roff_evalcond(*bufp, &pos); sv = pos; - while (' ' == (*bufp)[pos]) pos++; @@ -1018,16 +1005,20 @@ r->last->rule = rule; + /* + * An if-else will put the NEGATION of the current evaluated + * conditional into the stack of rules. + */ + if (ROFF_ie == tok) { - /* - * An if-else will put the NEGATION of the current - * evaluated conditional into the stack. - */ - r->rstackpos++; - if (ROFFRULE_DENY == r->last->rule) - r->rstack[r->rstackpos] = ROFFRULE_ALLOW; - else - r->rstack[r->rstackpos] = ROFFRULE_DENY; + if (r->rstackpos == RSTACK_MAX - 1) { + mandoc_msg(MANDOCERR_MEM, + r->parse, ln, ppos, NULL); + return(ROFF_ERR); + } + r->rstack[++r->rstackpos] = + ROFFRULE_DENY == r->last->rule ? + ROFFRULE_ALLOW : ROFFRULE_DENY; } /* If the parent has false as its rule, then so do we. */ ^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-04-07 10:02 UTC | newest] Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-04-07 0:39 roff conditional recursion Joerg Sonnenberger 2011-04-07 10:02 ` Kristaps Dzonsons
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).