=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.238 retrieving revision 1.243 diff -u -p -r1.238 -r1.243 --- mandoc/roff.c 2014/11/01 06:03:13 1.238 +++ mandoc/roff.c 2014/12/16 23:44:41 1.243 @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.238 2014/11/01 06:03:13 schwarze Exp $ */ +/* $Id: roff.c,v 1.243 2014/12/16 23:44:41 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -730,6 +730,7 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, enum rofft t; enum rofferr e; int pos; /* parse point */ + int spos; /* saved parse point for messages */ int ppos; /* original offset in buf->buf */ int ctl; /* macro line (boolean) */ @@ -800,15 +801,29 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, return((*roffs[t].sub)(r, t, buf, ln, ppos, pos, offs)); } + /* No scope is open. This is a new request or macro. */ + + spos = pos; + t = roff_parse(r, buf->buf, &pos, ln, ppos); + + /* Tables ignore most macros. */ + + if (r->tbl != NULL && (t == ROFF_MAX || t == ROFF_TS)) { + mandoc_msg(MANDOCERR_TBLMACRO, r->parse, + ln, pos, buf->buf + spos); + return(ROFF_IGN); + } + /* - * Lastly, as we've no scope open, try to look up and execute - * the new macro. If no macro is found, simply return and let - * the compilers handle it. + * This is neither a roff request nor a user-defined macro. + * Let the standard macro set parsers handle it. */ - if ((t = roff_parse(r, buf->buf, &pos, ln, ppos)) == ROFF_MAX) + if (t == ROFF_MAX) return(ROFF_CONT); + /* Execute a roff request or a user defined macro. */ + assert(roffs[t].proc); return((*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs)); } @@ -1236,7 +1251,7 @@ roff_evalstrcond(const char *v, int *pos) out: if (NULL == s3) s3 = strchr(s2, '\0'); - else + else if (*s3 != '\0') s3++; *pos = s3 - v; return(match); @@ -1249,7 +1264,7 @@ out: static int roff_evalcond(struct roff *r, int ln, const char *v, int *pos) { - int wanttrue, number; + int number, savepos, wanttrue; if ('!' == v[*pos]) { wanttrue = 0; @@ -1258,6 +1273,8 @@ roff_evalcond(struct roff *r, int ln, const char *v, i wanttrue = 1; switch (v[*pos]) { + case '\0': + return(0); case 'n': /* FALLTHROUGH */ case 'o': @@ -1272,16 +1289,21 @@ roff_evalcond(struct roff *r, int ln, const char *v, i case 'r': /* FALLTHROUGH */ case 't': + /* FALLTHROUGH */ + case 'v': (*pos)++; return(!wanttrue); default: break; } + savepos = *pos; if (roff_evalnum(r, ln, v, pos, &number, 0)) return((number > 0) == wanttrue); - else + else if (*pos == savepos) return(roff_evalstrcond(v, pos) == wanttrue); + else + return (0); } static enum rofferr