=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/roff.c,v retrieving revision 1.78 retrieving revision 1.79 diff -c -r1.78 -r1.79 *** src/usr.bin/mandoc/roff.c 2014/04/07 21:00:00 1.78 --- src/usr.bin/mandoc/roff.c 2014/04/08 01:36:50 1.79 *************** *** 1,4 **** ! /* $Id: roff.c,v 1.78 2014/04/07 21:00:00 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze --- 1,4 ---- ! /* $Id: roff.c,v 1.79 2014/04/08 01:36:50 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze *************** *** 481,489 **** } /* ! * In the current line, expand user-defined strings ("\*") ! * and references to number registers ("\n"). ! * Also check the syntax of other escape sequences. */ static enum rofferr roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) --- 481,489 ---- } /* ! * In the current line, expand escape sequences that tend to get ! * used in numerical expressions and conditional requests. ! * Also check the syntax of the remaining escape sequences. */ static enum rofferr roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) *************** *** 499,504 **** --- 499,507 ---- size_t naml; /* actual length of the escape name */ size_t ressz; /* size of the replacement string */ int expand_count; /* to avoid infinite loops */ + int npos; /* position in numeric expression */ + int irc; /* return code from roff_evalnum() */ + char term; /* character terminating the escape */ expand_count = 0; start = *bufp + pos; *************** *** 521,536 **** continue; } ! /* ! * Everything except user-defined strings and number ! * registers is only checked, not expanded. ! */ cp = stesc + 1; switch (*cp) { case ('*'): res = NULL; break; case ('n'): res = ubuf; break; --- 524,542 ---- continue; } ! /* Decide whether to expand or to check only. */ + term = '\0'; cp = stesc + 1; switch (*cp) { case ('*'): res = NULL; break; + case ('B'): + /* FALLTHROUGH */ + case ('w'): + term = cp[1]; + /* FALLTHROUGH */ case ('n'): res = ubuf; break; *************** *** 553,572 **** * Save a pointer to the name. */ ! switch (*++cp) { ! case ('\0'): ! continue; ! case ('('): ! cp++; ! maxl = 2; ! break; ! case ('['): ! cp++; maxl = 0; - break; - default: - maxl = 1; - break; } stnam = cp; --- 559,585 ---- * Save a pointer to the name. */ ! if ('\0' == term) { ! switch (*++cp) { ! case ('\0'): ! maxl = 0; ! break; ! case ('('): ! cp++; ! maxl = 2; ! break; ! case ('['): ! cp++; ! term = ']'; ! maxl = 0; ! break; ! default: ! maxl = 1; ! break; ! } ! } else { ! cp += 2; maxl = 0; } stnam = cp; *************** *** 578,587 **** (MANDOCERR_BADESCAPE, r->parse, ln, (int)(stesc - *bufp), NULL); ! continue; } ! if (0 == maxl && ']' == *cp) break; } /* --- 591,602 ---- (MANDOCERR_BADESCAPE, r->parse, ln, (int)(stesc - *bufp), NULL); ! break; } ! if (0 == maxl && *cp == term) { ! cp++; break; + } } /* *************** *** 589,599 **** * undefined, resume searching for escapes. */ ! if (NULL == res) res = roff_getstrn(r, stnam, naml); ! else snprintf(ubuf, sizeof(ubuf), "%d", roff_getregn(r, stnam, naml)); if (NULL == res) { mandoc_msg --- 604,629 ---- * undefined, resume searching for escapes. */ ! switch (stesc[1]) { ! case ('*'): res = roff_getstrn(r, stnam, naml); ! break; ! case ('B'): ! npos = 0; ! irc = roff_evalnum(stnam, &npos, NULL, 0); ! ubuf[0] = irc && stnam + npos + 1 == cp ! ? '1' : '0'; ! ubuf[1] = '\0'; ! break; ! case ('n'): snprintf(ubuf, sizeof(ubuf), "%d", roff_getregn(r, stnam, naml)); + break; + case ('w'): + snprintf(ubuf, sizeof(ubuf), "%d", + 24 * (int)naml); + break; + } if (NULL == res) { mandoc_msg *************** *** 610,616 **** strlcpy(nbuf, *bufp, (size_t)(stesc - *bufp + 1)); strlcat(nbuf, res, *szp); ! strlcat(nbuf, cp + (maxl ? 0 : 1), *szp); /* Prepare for the next replacement. */ --- 640,646 ---- strlcpy(nbuf, *bufp, (size_t)(stesc - *bufp + 1)); strlcat(nbuf, res, *szp); ! strlcat(nbuf, cp, *szp); /* Prepare for the next replacement. */ *************** *** 1122,1129 **** static int roff_getnum(const char *v, int *pos, int *res) { ! int p, n; p = *pos; n = v[p] == '-'; if (n) --- 1152,1162 ---- static int roff_getnum(const char *v, int *pos, int *res) { ! int myres, n, p; + if (NULL == res) + res = &myres; + p = *pos; n = v[p] == '-'; if (n) *************** *** 1426,1434 **** if ( ! roff_evalnum(v, pos, res, 1)) return(0); ! /* If the trailing parenthesis is missing, ignore the error. */ if (')' == v[*pos]) (*pos)++; return(1); } --- 1459,1474 ---- if ( ! roff_evalnum(v, pos, res, 1)) return(0); ! /* ! * Omission of the closing parenthesis ! * is an error in validation mode, ! * but ignored in evaluation mode. ! */ ! if (')' == v[*pos]) (*pos)++; + else if (NULL == res) + return(0); return(1); } *************** *** 1473,1478 **** --- 1513,1521 ---- if (skipwhite) while (isspace((unsigned char)v[*pos])) (*pos)++; + + if (NULL == res) + continue; switch (operator) { case ('+'):