version 1.205, 2014/04/07 21:00:08 |
version 1.206, 2014/04/08 01:37:27 |
Line 485 roff_alloc(struct mparse *parse, int options) |
|
Line 485 roff_alloc(struct mparse *parse, int options) |
|
} |
} |
|
|
/* |
/* |
* In the current line, expand user-defined strings ("\*") |
* In the current line, expand escape sequences that tend to get |
* and references to number registers ("\n"). |
* used in numerical expressions and conditional requests. |
* Also check the syntax of other escape sequences. |
* Also check the syntax of the remaining escape sequences. |
*/ |
*/ |
static enum rofferr |
static enum rofferr |
roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) |
roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) |
Line 503 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
Line 503 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
size_t naml; /* actual length of the escape name */ |
size_t naml; /* actual length of the escape name */ |
size_t ressz; /* size of the replacement string */ |
size_t ressz; /* size of the replacement string */ |
int expand_count; /* to avoid infinite loops */ |
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; |
expand_count = 0; |
start = *bufp + pos; |
start = *bufp + pos; |
Line 525 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
Line 528 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
continue; |
continue; |
} |
} |
|
|
/* |
/* Decide whether to expand or to check only. */ |
* Everything except user-defined strings and number |
|
* registers is only checked, not expanded. |
|
*/ |
|
|
|
|
term = '\0'; |
cp = stesc + 1; |
cp = stesc + 1; |
switch (*cp) { |
switch (*cp) { |
case ('*'): |
case ('*'): |
res = NULL; |
res = NULL; |
break; |
break; |
|
case ('B'): |
|
/* FALLTHROUGH */ |
|
case ('w'): |
|
term = cp[1]; |
|
/* FALLTHROUGH */ |
case ('n'): |
case ('n'): |
res = ubuf; |
res = ubuf; |
break; |
break; |
Line 557 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
Line 563 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
* Save a pointer to the name. |
* Save a pointer to the name. |
*/ |
*/ |
|
|
switch (*++cp) { |
if ('\0' == term) { |
case ('\0'): |
switch (*++cp) { |
continue; |
case ('\0'): |
case ('('): |
maxl = 0; |
cp++; |
break; |
maxl = 2; |
case ('('): |
break; |
cp++; |
case ('['): |
maxl = 2; |
cp++; |
break; |
|
case ('['): |
|
cp++; |
|
term = ']'; |
|
maxl = 0; |
|
break; |
|
default: |
|
maxl = 1; |
|
break; |
|
} |
|
} else { |
|
cp += 2; |
maxl = 0; |
maxl = 0; |
break; |
|
default: |
|
maxl = 1; |
|
break; |
|
} |
} |
stnam = cp; |
stnam = cp; |
|
|
Line 582 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
Line 595 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
(MANDOCERR_BADESCAPE, |
(MANDOCERR_BADESCAPE, |
r->parse, ln, |
r->parse, ln, |
(int)(stesc - *bufp), NULL); |
(int)(stesc - *bufp), NULL); |
continue; |
break; |
} |
} |
if (0 == maxl && ']' == *cp) |
if (0 == maxl && *cp == term) { |
|
cp++; |
break; |
break; |
|
} |
} |
} |
|
|
/* |
/* |
Line 593 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
Line 608 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
* undefined, resume searching for escapes. |
* undefined, resume searching for escapes. |
*/ |
*/ |
|
|
if (NULL == res) |
switch (stesc[1]) { |
|
case ('*'): |
res = roff_getstrn(r, stnam, naml); |
res = roff_getstrn(r, stnam, naml); |
else |
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", |
snprintf(ubuf, sizeof(ubuf), "%d", |
roff_getregn(r, stnam, naml)); |
roff_getregn(r, stnam, naml)); |
|
break; |
|
case ('w'): |
|
snprintf(ubuf, sizeof(ubuf), "%d", |
|
24 * (int)naml); |
|
break; |
|
} |
|
|
if (NULL == res) { |
if (NULL == res) { |
mandoc_msg |
mandoc_msg |
Line 614 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
Line 644 roff_res(struct roff *r, char **bufp, size_t *szp, int |
|
|
|
strlcpy(nbuf, *bufp, (size_t)(stesc - *bufp + 1)); |
strlcpy(nbuf, *bufp, (size_t)(stesc - *bufp + 1)); |
strlcat(nbuf, res, *szp); |
strlcat(nbuf, res, *szp); |
strlcat(nbuf, cp + (maxl ? 0 : 1), *szp); |
strlcat(nbuf, cp, *szp); |
|
|
/* Prepare for the next replacement. */ |
/* Prepare for the next replacement. */ |
|
|
Line 1126 roff_cond_text(ROFF_ARGS) |
|
Line 1156 roff_cond_text(ROFF_ARGS) |
|
static int |
static int |
roff_getnum(const char *v, int *pos, int *res) |
roff_getnum(const char *v, int *pos, int *res) |
{ |
{ |
int p, n; |
int myres, n, p; |
|
|
|
if (NULL == res) |
|
res = &myres; |
|
|
p = *pos; |
p = *pos; |
n = v[p] == '-'; |
n = v[p] == '-'; |
if (n) |
if (n) |
Line 1430 roff_evalpar(const char *v, int *pos, int *res) |
|
Line 1463 roff_evalpar(const char *v, int *pos, int *res) |
|
if ( ! roff_evalnum(v, pos, res, 1)) |
if ( ! roff_evalnum(v, pos, res, 1)) |
return(0); |
return(0); |
|
|
/* If the trailing parenthesis is missing, ignore the error. */ |
/* |
|
* Omission of the closing parenthesis |
|
* is an error in validation mode, |
|
* but ignored in evaluation mode. |
|
*/ |
|
|
if (')' == v[*pos]) |
if (')' == v[*pos]) |
(*pos)++; |
(*pos)++; |
|
else if (NULL == res) |
|
return(0); |
|
|
return(1); |
return(1); |
} |
} |
Line 1477 roff_evalnum(const char *v, int *pos, int *res, int sk |
|
Line 1517 roff_evalnum(const char *v, int *pos, int *res, int sk |
|
if (skipwhite) |
if (skipwhite) |
while (isspace((unsigned char)v[*pos])) |
while (isspace((unsigned char)v[*pos])) |
(*pos)++; |
(*pos)++; |
|
|
|
if (NULL == res) |
|
continue; |
|
|
switch (operator) { |
switch (operator) { |
case ('+'): |
case ('+'): |