=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/roff.c,v retrieving revision 1.4 retrieving revision 1.5 diff -c -r1.4 -r1.5 *** src/usr.bin/mandoc/roff.c 2010/06/06 20:30:08 1.4 --- src/usr.bin/mandoc/roff.c 2010/06/26 17:56:43 1.5 *************** *** 1,4 **** ! /* $Id: roff.c,v 1.4 2010/06/06 20:30:08 schwarze Exp $ */ /* * Copyright (c) 2010 Kristaps Dzonsons * --- 1,4 ---- ! /* $Id: roff.c,v 1.5 2010/06/26 17:56:43 schwarze Exp $ */ /* * Copyright (c) 2010 Kristaps Dzonsons * *************** *** 103,108 **** --- 103,109 ---- static enum rofferr roff_cond(ROFF_ARGS); static enum rofferr roff_cond_text(ROFF_ARGS); static enum rofferr roff_cond_sub(ROFF_ARGS); + static enum roffrule roff_evalcond(const char *, int *); static enum rofferr roff_line(ROFF_ARGS); /* See roff_hash_find() */ *************** *** 621,632 **** { enum rofft t; enum roffrule rr; ppos = pos; rr = r->last->rule; ! roff_cond_text(r, tok, bufp, szp, ln, ppos, pos, offs); if (ROFF_MAX == (t = roff_parse(*bufp, &pos))) return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); --- 622,643 ---- { enum rofft t; enum roffrule rr; + struct roffnode *l; ppos = pos; rr = r->last->rule; ! /* ! * Clean out scope. If we've closed ourselves, then don't ! * continue. ! */ + l = r->last; + roffnode_cleanscope(r); + + if (l != r->last) + return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); + if (ROFF_MAX == (t = roff_parse(*bufp, &pos))) return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); *************** *** 674,685 **** } /* ARGSUSED */ static enum rofferr roff_cond(ROFF_ARGS) { - int cpos; /* position of the condition */ int sv; /* Stack overflow! */ --- 685,721 ---- } + static enum roffrule + roff_evalcond(const char *v, int *pos) + { + + switch (v[*pos]) { + case ('n'): + (*pos)++; + return(ROFFRULE_ALLOW); + case ('e'): + /* FALLTHROUGH */ + case ('o'): + /* FALLTHROUGH */ + case ('t'): + (*pos)++; + return(ROFFRULE_DENY); + default: + break; + } + + while (v[*pos] && ' ' != v[*pos]) + (*pos)++; + return(ROFFRULE_DENY); + } + + /* ARGSUSED */ static enum rofferr roff_cond(ROFF_ARGS) { int sv; + enum roffrule rule; /* Stack overflow! */ *************** *** 688,707 **** return(ROFF_ERR); } ! cpos = pos; ! if (ROFF_if == tok || ROFF_ie == tok) { ! /* ! * Read ahead past the conditional. FIXME: this does ! * not work, as conditionals don't end on whitespace, ! * but are parsed according to a formal grammar. It's ! * good enough for now, however. ! */ ! while ((*bufp)[pos] && ' ' != (*bufp)[pos]) ! pos++; ! } sv = pos; while (' ' == (*bufp)[pos]) pos++; --- 724,745 ---- 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); sv = pos; + while (' ' == (*bufp)[pos]) pos++; *************** *** 711,740 **** * really doing anything. Warn about this. It's probably * wrong. */ if ('\0' == (*bufp)[pos] && sv != pos) { ! if ( ! (*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL)) ! return(ROFF_ERR); ! return(ROFF_IGN); } if ( ! roffnode_push(r, tok, ln, ppos)) return(ROFF_ERR); ! /* XXX: Implement more conditionals. */ - if (ROFF_if == tok || ROFF_ie == tok) - r->last->rule = 'n' == (*bufp)[cpos] ? - ROFFRULE_ALLOW : ROFFRULE_DENY; - else 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) - r->last->rule = ROFFRULE_DENY; - else - r->last->rule = r->rstack[r->rstackpos]; - } if (ROFF_ie == tok) { /* * An if-else will put the NEGATION of the current --- 749,766 ---- * really doing anything. Warn about this. It's probably * wrong. */ + if ('\0' == (*bufp)[pos] && sv != pos) { ! if ((*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL)) ! return(ROFF_IGN); ! return(ROFF_ERR); } if ( ! roffnode_push(r, tok, ln, ppos)) return(ROFF_ERR); ! r->last->rule = rule; if (ROFF_ie == tok) { /* * An if-else will put the NEGATION of the current *************** *** 746,753 **** --- 772,788 ---- else r->rstack[r->rstackpos] = ROFFRULE_DENY; } + + /* If the parent has false as its rule, then so do we. */ + if (r->last->parent && ROFFRULE_DENY == r->last->parent->rule) r->last->rule = ROFFRULE_DENY; + + /* + * Determine scope. If we're invoked with "\{" trailing the + * conditional, then we're in a multiline scope. Else our scope + * expires on the next line. + */ r->last->endspan = 1;