version 1.342, 2018/10/25 01:32:40 |
version 1.350, 2018/12/14 05:18:03 |
|
|
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
|
|
#include "mandoc.h" |
|
#include "mandoc_aux.h" |
#include "mandoc_aux.h" |
#include "mandoc_ohash.h" |
#include "mandoc_ohash.h" |
|
#include "mandoc.h" |
#include "roff.h" |
#include "roff.h" |
|
#include "mandoc_parse.h" |
#include "libmandoc.h" |
#include "libmandoc.h" |
#include "roff_int.h" |
#include "roff_int.h" |
#include "libroff.h" |
#include "tbl_parse.h" |
|
#include "eqn_parse.h" |
|
|
/* Maximum number of string expansions per line, to break infinite loops. */ |
/* Maximum number of string expansions per line, to break infinite loops. */ |
#define EXPAND_LIMIT 1000 |
#define EXPAND_LIMIT 1000 |
Line 167 static int roffnode_cleanscope(struct roff *); |
|
Line 169 static int roffnode_cleanscope(struct roff *); |
|
static int roffnode_pop(struct roff *); |
static int roffnode_pop(struct roff *); |
static void roffnode_push(struct roff *, enum roff_tok, |
static void roffnode_push(struct roff *, enum roff_tok, |
const char *, int, int); |
const char *, int, int); |
static void roff_addtbl(struct roff_man *, struct tbl_node *); |
static void roff_addtbl(struct roff_man *, int, struct tbl_node *); |
static int roff_als(ROFF_ARGS); |
static int roff_als(ROFF_ARGS); |
static int roff_block(ROFF_ARGS); |
static int roff_block(ROFF_ARGS); |
static int roff_block_text(ROFF_ARGS); |
static int roff_block_text(ROFF_ARGS); |
Line 717 roffnode_push(struct roff *r, enum roff_tok tok, const |
|
Line 719 roffnode_push(struct roff *r, enum roff_tok tok, const |
|
static void |
static void |
roff_free1(struct roff *r) |
roff_free1(struct roff *r) |
{ |
{ |
struct tbl_node *tbl; |
|
int i; |
int i; |
|
|
while (NULL != (tbl = r->first_tbl)) { |
tbl_free(r->first_tbl); |
r->first_tbl = tbl->next; |
|
tbl_free(tbl); |
|
} |
|
r->first_tbl = r->last_tbl = r->tbl = NULL; |
r->first_tbl = r->last_tbl = r->tbl = NULL; |
|
|
if (r->last_eqn != NULL) |
eqn_free(r->last_eqn); |
eqn_free(r->last_eqn); |
|
r->last_eqn = r->eqn = NULL; |
r->last_eqn = r->eqn = NULL; |
|
|
while (r->mstackpos >= 0) |
while (r->mstackpos >= 0) |
Line 1013 roff_body_alloc(struct roff_man *man, int line, int po |
|
Line 1010 roff_body_alloc(struct roff_man *man, int line, int po |
|
} |
} |
|
|
static void |
static void |
roff_addtbl(struct roff_man *man, struct tbl_node *tbl) |
roff_addtbl(struct roff_man *man, int line, struct tbl_node *tbl) |
{ |
{ |
struct roff_node *n; |
struct roff_node *n; |
const struct tbl_span *span; |
struct tbl_span *span; |
|
|
if (man->macroset == MACROSET_MAN) |
if (man->macroset == MACROSET_MAN) |
man_breakscope(man, ROFF_TS); |
man_breakscope(man, ROFF_TS); |
while ((span = tbl_span(tbl)) != NULL) { |
while ((span = tbl_span(tbl)) != NULL) { |
n = roff_node_alloc(man, tbl->line, 0, ROFFT_TBL, TOKEN_NONE); |
n = roff_node_alloc(man, line, 0, ROFFT_TBL, TOKEN_NONE); |
n->span = span; |
n->span = span; |
roff_node_append(man, n); |
roff_node_append(man, n); |
n->flags |= NODE_VALID | NODE_ENDED; |
n->flags |= NODE_VALID | NODE_ENDED; |
Line 1067 roff_node_unlink(struct roff_man *man, struct roff_nod |
|
Line 1064 roff_node_unlink(struct roff_man *man, struct roff_nod |
|
} |
} |
|
|
void |
void |
|
roff_node_relink(struct roff_man *man, struct roff_node *n) |
|
{ |
|
roff_node_unlink(man, n); |
|
n->prev = n->next = NULL; |
|
roff_node_append(man, n); |
|
} |
|
|
|
void |
roff_node_free(struct roff_node *n) |
roff_node_free(struct roff_node *n) |
{ |
{ |
|
|
Line 1074 roff_node_free(struct roff_node *n) |
|
Line 1079 roff_node_free(struct roff_node *n) |
|
mdoc_argv_free(n->args); |
mdoc_argv_free(n->args); |
if (n->type == ROFFT_BLOCK || n->type == ROFFT_ELEM) |
if (n->type == ROFFT_BLOCK || n->type == ROFFT_ELEM) |
free(n->norm); |
free(n->norm); |
if (n->eqn != NULL) |
eqn_box_free(n->eqn); |
eqn_box_free(n->eqn); |
|
free(n->string); |
free(n->string); |
free(n); |
free(n); |
} |
} |
Line 1200 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
Line 1204 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
isalnum((unsigned char)*cp) == 0 && |
isalnum((unsigned char)*cp) == 0 && |
strchr(cp, '$') != NULL) { |
strchr(cp, '$') != NULL) { |
if (r->man->meta.rcsids & rcsid) |
if (r->man->meta.rcsids & rcsid) |
mandoc_msg(MANDOCERR_RCS_REP, r->parse, |
mandoc_msg(MANDOCERR_RCS_REP, ln, |
ln, stesc + 1 - buf->buf, stesc + 1); |
(int)(stesc - buf->buf) + 1, |
|
"%s", stesc + 1); |
r->man->meta.rcsids |= rcsid; |
r->man->meta.rcsids |= rcsid; |
} |
} |
|
|
Line 1213 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
Line 1218 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
ep--; |
ep--; |
} |
} |
if (*ep == ' ' || *ep == '\t') |
if (*ep == ' ' || *ep == '\t') |
mandoc_msg(MANDOCERR_SPACE_EOL, r->parse, |
mandoc_msg(MANDOCERR_SPACE_EOL, |
ln, ep - buf->buf, NULL); |
ln, (int)(ep - buf->buf), NULL); |
|
|
/* |
/* |
* Save comments preceding the title macro |
* Save comments preceding the title macro |
Line 1323 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
Line 1328 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
if (esc == ESCAPE_ERROR || |
if (esc == ESCAPE_ERROR || |
(esc == ESCAPE_SPECIAL && |
(esc == ESCAPE_SPECIAL && |
mchars_spec2cp(stnam, inaml) < 0)) |
mchars_spec2cp(stnam, inaml) < 0)) |
mandoc_vmsg(MANDOCERR_ESC_BAD, |
mandoc_msg(MANDOCERR_ESC_BAD, |
r->parse, ln, (int)(stesc - buf->buf), |
ln, (int)(stesc - buf->buf), |
"%.*s", (int)(cp - stesc), stesc); |
"%.*s", (int)(cp - stesc), stesc); |
stesc--; |
stesc--; |
continue; |
continue; |
} |
} |
|
|
if (EXPAND_LIMIT < ++expand_count) { |
if (EXPAND_LIMIT < ++expand_count) { |
mandoc_msg(MANDOCERR_ROFFLOOP, r->parse, |
mandoc_msg(MANDOCERR_ROFFLOOP, |
ln, (int)(stesc - buf->buf), NULL); |
ln, (int)(stesc - buf->buf), NULL); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
Line 1372 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
Line 1377 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
arg_complete = 1; |
arg_complete = 1; |
while (maxl == 0 || naml < maxl) { |
while (maxl == 0 || naml < maxl) { |
if (*cp == '\0') { |
if (*cp == '\0') { |
mandoc_msg(MANDOCERR_ESC_BAD, r->parse, |
mandoc_msg(MANDOCERR_ESC_BAD, ln, |
ln, (int)(stesc - buf->buf), stesc); |
(int)(stesc - buf->buf), "%s", stesc); |
arg_complete = 0; |
arg_complete = 0; |
break; |
break; |
} |
} |
Line 1424 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
Line 1429 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
break; |
break; |
case '$': |
case '$': |
if (r->mstackpos < 0) { |
if (r->mstackpos < 0) { |
mandoc_vmsg(MANDOCERR_ARG_UNDEF, |
mandoc_msg(MANDOCERR_ARG_UNDEF, ln, |
r->parse, ln, (int)(stesc - buf->buf), |
(int)(stesc - buf->buf), "%.3s", stesc); |
"%.3s", stesc); |
|
break; |
break; |
} |
} |
ctx = r->mstack + r->mstackpos; |
ctx = r->mstack + r->mstackpos; |
Line 1441 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
Line 1445 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
else if (stesc[2] == '@') |
else if (stesc[2] == '@') |
quote_args = 1; |
quote_args = 1; |
else { |
else { |
mandoc_vmsg(MANDOCERR_ARG_NONUM, |
mandoc_msg(MANDOCERR_ARG_NONUM, ln, |
r->parse, ln, (int)(stesc - buf->buf), |
(int)(stesc - buf->buf), "%.3s", stesc); |
"%.3s", stesc); |
|
break; |
break; |
} |
} |
asz = 0; |
asz = 0; |
Line 1502 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
Line 1505 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
|
|
if (res == NULL) { |
if (res == NULL) { |
if (stesc[1] == '*') |
if (stesc[1] == '*') |
mandoc_vmsg(MANDOCERR_STR_UNDEF, |
mandoc_msg(MANDOCERR_STR_UNDEF, |
r->parse, ln, (int)(stesc - buf->buf), |
ln, (int)(stesc - buf->buf), |
"%.*s", (int)naml, stnam); |
"%.*s", (int)naml, stnam); |
res = ""; |
res = ""; |
} else if (buf->sz + strlen(res) > SHRT_MAX) { |
} else if (buf->sz + strlen(res) > SHRT_MAX) { |
mandoc_msg(MANDOCERR_ROFFLOOP, r->parse, |
mandoc_msg(MANDOCERR_ROFFLOOP, |
ln, (int)(stesc - buf->buf), NULL); |
ln, (int)(stesc - buf->buf), NULL); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
Line 1651 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
Line 1654 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
} |
} |
if (r->tbl != NULL && (ctl == 0 || buf->buf[pos] == '\0')) { |
if (r->tbl != NULL && (ctl == 0 || buf->buf[pos] == '\0')) { |
tbl_read(r->tbl, ln, buf->buf, ppos); |
tbl_read(r->tbl, ln, buf->buf, ppos); |
roff_addtbl(r->man, r->tbl); |
roff_addtbl(r->man, ln, r->tbl); |
return e; |
return e; |
} |
} |
if ( ! ctl) |
if ( ! ctl) |
Line 1660 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
Line 1663 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
/* Skip empty request lines. */ |
/* Skip empty request lines. */ |
|
|
if (buf->buf[pos] == '"') { |
if (buf->buf[pos] == '"') { |
mandoc_msg(MANDOCERR_COMMENT_BAD, r->parse, |
mandoc_msg(MANDOCERR_COMMENT_BAD, ln, pos, NULL); |
ln, pos, NULL); |
|
return ROFF_IGN; |
return ROFF_IGN; |
} else if (buf->buf[pos] == '\0') |
} else if (buf->buf[pos] == '\0') |
return ROFF_IGN; |
return ROFF_IGN; |
Line 1686 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
Line 1688 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
|
|
if (r->tbl != NULL && (t == TOKEN_NONE || t == ROFF_TS || |
if (r->tbl != NULL && (t == TOKEN_NONE || t == ROFF_TS || |
t == ROFF_br || t == ROFF_ce || t == ROFF_rj || t == ROFF_sp)) { |
t == ROFF_br || t == ROFF_ce || t == ROFF_rj || t == ROFF_sp)) { |
mandoc_msg(MANDOCERR_TBLMACRO, r->parse, |
mandoc_msg(MANDOCERR_TBLMACRO, |
ln, pos, buf->buf + spos); |
ln, pos, "%s", buf->buf + spos); |
if (t != TOKEN_NONE) |
if (t != TOKEN_NONE) |
return ROFF_IGN; |
return ROFF_IGN; |
while (buf->buf[pos] != '\0' && buf->buf[pos] != ' ') |
while (buf->buf[pos] != '\0' && buf->buf[pos] != ' ') |
Line 1695 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
Line 1697 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
while (buf->buf[pos] == ' ') |
while (buf->buf[pos] == ' ') |
pos++; |
pos++; |
tbl_read(r->tbl, ln, buf->buf, pos); |
tbl_read(r->tbl, ln, buf->buf, pos); |
roff_addtbl(r->man, r->tbl); |
roff_addtbl(r->man, ln, r->tbl); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
|
|
roff_endparse(struct roff *r) |
roff_endparse(struct roff *r) |
{ |
{ |
if (r->last != NULL) |
if (r->last != NULL) |
mandoc_msg(MANDOCERR_BLK_NOEND, r->parse, |
mandoc_msg(MANDOCERR_BLK_NOEND, r->last->line, |
r->last->line, r->last->col, |
r->last->col, "%s", roff_name[r->last->tok]); |
roff_name[r->last->tok]); |
|
|
|
if (r->eqn != NULL) { |
if (r->eqn != NULL) { |
mandoc_msg(MANDOCERR_BLK_NOEND, r->parse, |
mandoc_msg(MANDOCERR_BLK_NOEND, |
r->eqn->node->line, r->eqn->node->pos, "EQ"); |
r->eqn->node->line, r->eqn->node->pos, "EQ"); |
eqn_parse(r->eqn); |
eqn_parse(r->eqn); |
r->eqn = NULL; |
r->eqn = NULL; |
} |
} |
|
|
if (r->tbl != NULL) { |
if (r->tbl != NULL) { |
mandoc_msg(MANDOCERR_BLK_NOEND, r->parse, |
tbl_end(r->tbl, 1); |
r->tbl->line, r->tbl->pos, "TS"); |
|
tbl_end(r->tbl); |
|
r->tbl = NULL; |
r->tbl = NULL; |
} |
} |
} |
} |
Line 1821 roff_cblock(ROFF_ARGS) |
|
Line 1820 roff_cblock(ROFF_ARGS) |
|
*/ |
*/ |
|
|
if (r->last == NULL) { |
if (r->last == NULL) { |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, ".."); |
ln, ppos, ".."); |
|
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
Line 1836 roff_cblock(ROFF_ARGS) |
|
Line 1834 roff_cblock(ROFF_ARGS) |
|
case ROFF_ig: |
case ROFF_ig: |
break; |
break; |
default: |
default: |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, ".."); |
ln, ppos, ".."); |
|
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
if (buf->buf[pos] != '\0') |
if (buf->buf[pos] != '\0') |
mandoc_vmsg(MANDOCERR_ARG_SKIP, r->parse, ln, pos, |
mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos, |
".. %s", buf->buf + pos); |
".. %s", buf->buf + pos); |
|
|
roffnode_pop(r); |
roffnode_pop(r); |
|
|
roff_ccond(struct roff *r, int ln, int ppos) |
roff_ccond(struct roff *r, int ln, int ppos) |
{ |
{ |
if (NULL == r->last) { |
if (NULL == r->last) { |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, "\\}"); |
ln, ppos, "\\}"); |
|
return 0; |
return 0; |
} |
} |
|
|
Line 1881 roff_ccond(struct roff *r, int ln, int ppos) |
|
Line 1877 roff_ccond(struct roff *r, int ln, int ppos) |
|
case ROFF_while: |
case ROFF_while: |
break; |
break; |
default: |
default: |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, "\\}"); |
ln, ppos, "\\}"); |
|
return 0; |
return 0; |
} |
} |
|
|
if (r->last->endspan > -1) { |
if (r->last->endspan > -1) { |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, "\\}"); |
ln, ppos, "\\}"); |
|
return 0; |
return 0; |
} |
} |
|
|
Line 1932 roff_block(ROFF_ARGS) |
|
Line 1926 roff_block(ROFF_ARGS) |
|
deftype = ROFFDEF_USER; |
deftype = ROFFDEF_USER; |
name = roff_getstrn(r, iname, namesz, &deftype); |
name = roff_getstrn(r, iname, namesz, &deftype); |
if (name == NULL) { |
if (name == NULL) { |
mandoc_vmsg(MANDOCERR_STR_UNDEF, |
mandoc_msg(MANDOCERR_STR_UNDEF, |
r->parse, ln, (int)(iname - buf->buf), |
ln, (int)(iname - buf->buf), |
"%.*s", (int)namesz, iname); |
"%.*s", (int)namesz, iname); |
namesz = 0; |
namesz = 0; |
} else |
} else |
Line 1942 roff_block(ROFF_ARGS) |
|
Line 1936 roff_block(ROFF_ARGS) |
|
name = iname; |
name = iname; |
|
|
if (namesz == 0 && tok != ROFF_ig) { |
if (namesz == 0 && tok != ROFF_ig) { |
mandoc_msg(MANDOCERR_REQ_EMPTY, r->parse, |
mandoc_msg(MANDOCERR_REQ_EMPTY, |
ln, ppos, roff_name[tok]); |
ln, ppos, "%s", roff_name[tok]); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
Line 2001 roff_block(ROFF_ARGS) |
|
Line 1995 roff_block(ROFF_ARGS) |
|
deftype = ROFFDEF_USER; |
deftype = ROFFDEF_USER; |
name = roff_getstrn(r, iname, namesz, &deftype); |
name = roff_getstrn(r, iname, namesz, &deftype); |
if (name == NULL) { |
if (name == NULL) { |
mandoc_vmsg(MANDOCERR_STR_UNDEF, |
mandoc_msg(MANDOCERR_STR_UNDEF, |
r->parse, ln, (int)(iname - buf->buf), |
ln, (int)(iname - buf->buf), |
"%.*s", (int)namesz, iname); |
"%.*s", (int)namesz, iname); |
namesz = 0; |
namesz = 0; |
} else |
} else |
Line 2014 roff_block(ROFF_ARGS) |
|
Line 2008 roff_block(ROFF_ARGS) |
|
r->last->end = mandoc_strndup(name, namesz); |
r->last->end = mandoc_strndup(name, namesz); |
|
|
if (*cp != '\0') |
if (*cp != '\0') |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, r->parse, |
mandoc_msg(MANDOCERR_ARG_EXCESS, |
ln, pos, ".%s ... %s", roff_name[tok], cp); |
ln, pos, ".%s ... %s", roff_name[tok], cp); |
|
|
return ROFF_IGN; |
return ROFF_IGN; |
Line 2107 roff_cond_sub(ROFF_ARGS) |
|
Line 2101 roff_cond_sub(ROFF_ARGS) |
|
if (ep[0] == '\\' && ep[1] == '}') |
if (ep[0] == '\\' && ep[1] == '}') |
rr = 0; |
rr = 0; |
|
|
/* Always check for the closing delimiter `\}'. */ |
/* |
|
* The closing delimiter `\}' rewinds the conditional scope |
|
* but is otherwise ignored when interpreting the line. |
|
*/ |
|
|
while ((ep = strchr(ep, '\\')) != NULL) { |
while ((ep = strchr(ep, '\\')) != NULL) { |
switch (ep[1]) { |
switch (ep[1]) { |
Line 2150 roff_cond_text(ROFF_ARGS) |
|
Line 2147 roff_cond_text(ROFF_ARGS) |
|
if (roffnode_cleanscope(r)) |
if (roffnode_cleanscope(r)) |
irc |= endloop; |
irc |= endloop; |
|
|
|
/* |
|
* If `\}' occurs on a text line with neither preceding |
|
* nor following characters, drop the line completely. |
|
*/ |
|
|
ep = buf->buf + pos; |
ep = buf->buf + pos; |
|
if (strcmp(ep, "\\}") == 0) |
|
rr = 0; |
|
|
|
/* |
|
* The closing delimiter `\}' rewinds the conditional scope |
|
* but is otherwise ignored when interpreting the line. |
|
*/ |
|
|
while ((ep = strchr(ep, '\\')) != NULL) { |
while ((ep = strchr(ep, '\\')) != NULL) { |
if (*(++ep) == '}') { |
switch (ep[1]) { |
*ep = '&'; |
case '}': |
if (roff_ccond(r, ln, ep - buf->buf - 1)) |
memmove(ep, ep + 2, strlen(ep + 2) + 1); |
|
if (roff_ccond(r, ln, ep - buf->buf)) |
irc |= endloop; |
irc |= endloop; |
} |
break; |
if (*ep != '\0') |
case '\0': |
++ep; |
++ep; |
|
break; |
|
default: |
|
ep += 2; |
|
break; |
|
} |
} |
} |
if (rr) |
if (rr) |
irc |= ROFF_CONT; |
irc |= ROFF_CONT; |
|
|
roff_insec(ROFF_ARGS) |
roff_insec(ROFF_ARGS) |
{ |
{ |
|
|
mandoc_msg(MANDOCERR_REQ_INSEC, r->parse, |
mandoc_msg(MANDOCERR_REQ_INSEC, ln, ppos, "%s", roff_name[tok]); |
ln, ppos, roff_name[tok]); |
|
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
|
|
roff_unsupp(ROFF_ARGS) |
roff_unsupp(ROFF_ARGS) |
{ |
{ |
|
|
mandoc_msg(MANDOCERR_REQ_UNSUPP, r->parse, |
mandoc_msg(MANDOCERR_REQ_UNSUPP, ln, ppos, "%s", roff_name[tok]); |
ln, ppos, roff_name[tok]); |
|
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
Line 2477 roff_cond(ROFF_ARGS) |
|
Line 2491 roff_cond(ROFF_ARGS) |
|
*/ |
*/ |
|
|
if (buf->buf[pos] == '\0') |
if (buf->buf[pos] == '\0') |
mandoc_msg(MANDOCERR_COND_EMPTY, r->parse, |
mandoc_msg(MANDOCERR_COND_EMPTY, |
ln, ppos, roff_name[tok]); |
ln, ppos, "%s", roff_name[tok]); |
|
|
r->last->endspan = 1; |
r->last->endspan = 1; |
|
|
Line 2681 roff_evalnum(struct roff *r, int ln, const char *v, |
|
Line 2695 roff_evalnum(struct roff *r, int ln, const char *v, |
|
case '/': |
case '/': |
if (operand2 == 0) { |
if (operand2 == 0) { |
mandoc_msg(MANDOCERR_DIVZERO, |
mandoc_msg(MANDOCERR_DIVZERO, |
r->parse, ln, *pos, v); |
ln, *pos, "%s", v); |
*res = 0; |
*res = 0; |
break; |
break; |
} |
} |
Line 2690 roff_evalnum(struct roff *r, int ln, const char *v, |
|
Line 2704 roff_evalnum(struct roff *r, int ln, const char *v, |
|
case '%': |
case '%': |
if (operand2 == 0) { |
if (operand2 == 0) { |
mandoc_msg(MANDOCERR_DIVZERO, |
mandoc_msg(MANDOCERR_DIVZERO, |
r->parse, ln, *pos, v); |
ln, *pos, "%s", v); |
*res = 0; |
*res = 0; |
break; |
break; |
} |
} |
Line 2970 roff_it(ROFF_ARGS) |
|
Line 2984 roff_it(ROFF_ARGS) |
|
/* Parse the number of lines. */ |
/* Parse the number of lines. */ |
|
|
if ( ! roff_evalnum(r, ln, buf->buf, &pos, &iv, 0)) { |
if ( ! roff_evalnum(r, ln, buf->buf, &pos, &iv, 0)) { |
mandoc_msg(MANDOCERR_IT_NONUM, r->parse, |
mandoc_msg(MANDOCERR_IT_NONUM, |
ln, ppos, buf->buf + 1); |
ln, ppos, "%s", buf->buf + 1); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
|
|
roff_TE(ROFF_ARGS) |
roff_TE(ROFF_ARGS) |
{ |
{ |
if (r->tbl == NULL) { |
if (r->tbl == NULL) { |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, "TE"); |
ln, ppos, "TE"); |
|
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
if (tbl_end(r->tbl) == 0) { |
if (tbl_end(r->tbl, 0) == 0) { |
r->tbl = NULL; |
r->tbl = NULL; |
free(buf->buf); |
free(buf->buf); |
buf->buf = mandoc_strdup(".sp"); |
buf->buf = mandoc_strdup(".sp"); |
Line 3046 roff_T_(ROFF_ARGS) |
|
Line 3059 roff_T_(ROFF_ARGS) |
|
{ |
{ |
|
|
if (NULL == r->tbl) |
if (NULL == r->tbl) |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, "T&"); |
ln, ppos, "T&"); |
|
else |
else |
tbl_restart(ln, ppos, r->tbl); |
tbl_restart(ln, ppos, r->tbl); |
|
|
Line 3130 roff_EQ(ROFF_ARGS) |
|
Line 3142 roff_EQ(ROFF_ARGS) |
|
n = roff_node_alloc(r->man, ln, ppos, ROFFT_EQN, TOKEN_NONE); |
n = roff_node_alloc(r->man, ln, ppos, ROFFT_EQN, TOKEN_NONE); |
if (ln > r->man->last->line) |
if (ln > r->man->last->line) |
n->flags |= NODE_LINE; |
n->flags |= NODE_LINE; |
n->eqn = mandoc_calloc(1, sizeof(*n->eqn)); |
n->eqn = eqn_box_new(); |
n->eqn->expectargs = UINT_MAX; |
|
roff_node_append(r->man, n); |
roff_node_append(r->man, n); |
r->man->next = ROFF_NEXT_SIBLING; |
r->man->next = ROFF_NEXT_SIBLING; |
|
|
Line 3144 roff_EQ(ROFF_ARGS) |
|
Line 3155 roff_EQ(ROFF_ARGS) |
|
r->eqn->node = n; |
r->eqn->node = n; |
|
|
if (buf->buf[pos] != '\0') |
if (buf->buf[pos] != '\0') |
mandoc_vmsg(MANDOCERR_ARG_SKIP, r->parse, ln, pos, |
mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos, |
".EQ %s", buf->buf + pos); |
".EQ %s", buf->buf + pos); |
|
|
return ROFF_IGN; |
return ROFF_IGN; |
Line 3157 roff_EN(ROFF_ARGS) |
|
Line 3168 roff_EN(ROFF_ARGS) |
|
eqn_parse(r->eqn); |
eqn_parse(r->eqn); |
r->eqn = NULL; |
r->eqn = NULL; |
} else |
} else |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, ln, ppos, "EN"); |
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, "EN"); |
if (buf->buf[pos] != '\0') |
if (buf->buf[pos] != '\0') |
mandoc_vmsg(MANDOCERR_ARG_SKIP, r->parse, ln, pos, |
mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos, |
"EN %s", buf->buf + pos); |
"EN %s", buf->buf + pos); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
roff_TS(ROFF_ARGS) |
roff_TS(ROFF_ARGS) |
{ |
{ |
if (r->tbl != NULL) { |
if (r->tbl != NULL) { |
mandoc_msg(MANDOCERR_BLK_BROKEN, r->parse, |
mandoc_msg(MANDOCERR_BLK_BROKEN, ln, ppos, "TS breaks TS"); |
ln, ppos, "TS breaks TS"); |
tbl_end(r->tbl, 0); |
tbl_end(r->tbl); |
|
} |
} |
r->tbl = tbl_alloc(ppos, ln, r->parse); |
r->tbl = tbl_alloc(ppos, ln, r->parse, r->last_tbl); |
if (r->last_tbl) |
if (r->last_tbl == NULL) |
r->last_tbl->next = r->tbl; |
|
else |
|
r->first_tbl = r->tbl; |
r->first_tbl = r->tbl; |
r->last_tbl = r->tbl; |
r->last_tbl = r->tbl; |
return ROFF_IGN; |
return ROFF_IGN; |
Line 3208 roff_onearg(ROFF_ARGS) |
|
Line 3216 roff_onearg(ROFF_ARGS) |
|
while (*cp == ' ') |
while (*cp == ' ') |
*cp++ = '\0'; |
*cp++ = '\0'; |
if (*cp != '\0') |
if (*cp != '\0') |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, |
mandoc_msg(MANDOCERR_ARG_EXCESS, |
r->parse, ln, cp - buf->buf, |
ln, (int)(cp - buf->buf), |
"%s ... %s", roff_name[tok], cp); |
"%s ... %s", roff_name[tok], cp); |
roff_word_alloc(r->man, ln, pos, buf->buf + pos); |
roff_word_alloc(r->man, ln, pos, buf->buf + pos); |
} |
} |
Line 3222 roff_onearg(ROFF_ARGS) |
|
Line 3230 roff_onearg(ROFF_ARGS) |
|
npos = 0; |
npos = 0; |
if (roff_evalnum(r, ln, r->man->last->string, &npos, |
if (roff_evalnum(r, ln, r->man->last->string, &npos, |
&roffce_lines, 0) == 0) { |
&roffce_lines, 0) == 0) { |
mandoc_vmsg(MANDOCERR_CE_NONUM, |
mandoc_msg(MANDOCERR_CE_NONUM, |
r->parse, ln, pos, "ce %s", buf->buf + pos); |
ln, pos, "ce %s", buf->buf + pos); |
roffce_lines = 1; |
roffce_lines = 1; |
} |
} |
if (roffce_lines < 1) { |
if (roffce_lines < 1) { |
Line 3298 roff_br(ROFF_ARGS) |
|
Line 3306 roff_br(ROFF_ARGS) |
|
man_breakscope(r->man, ROFF_br); |
man_breakscope(r->man, ROFF_br); |
roff_elem_alloc(r->man, ln, ppos, ROFF_br); |
roff_elem_alloc(r->man, ln, ppos, ROFF_br); |
if (buf->buf[pos] != '\0') |
if (buf->buf[pos] != '\0') |
mandoc_vmsg(MANDOCERR_ARG_SKIP, r->parse, ln, pos, |
mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos, |
"%s %s", roff_name[tok], buf->buf + pos); |
"%s %s", roff_name[tok], buf->buf + pos); |
r->man->last->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; |
r->man->last->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; |
r->man->next = ROFF_NEXT_SIBLING; |
r->man->next = ROFF_NEXT_SIBLING; |
Line 3316 roff_cc(ROFF_ARGS) |
|
Line 3324 roff_cc(ROFF_ARGS) |
|
r->control = '\0'; |
r->control = '\0'; |
|
|
if (*p != '\0') |
if (*p != '\0') |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, r->parse, |
mandoc_msg(MANDOCERR_ARG_EXCESS, |
ln, p - buf->buf, "cc ... %s", p); |
ln, p - buf->buf, "cc ... %s", p); |
|
|
return ROFF_IGN; |
return ROFF_IGN; |
Line 3336 roff_char(ROFF_ARGS) |
|
Line 3344 roff_char(ROFF_ARGS) |
|
if (*kp == '\0' || (*kp == '\\' && |
if (*kp == '\0' || (*kp == '\\' && |
mandoc_escape(&p, NULL, NULL) != ESCAPE_SPECIAL) || |
mandoc_escape(&p, NULL, NULL) != ESCAPE_SPECIAL) || |
(*p != ' ' && *p != '\0')) { |
(*p != ' ' && *p != '\0')) { |
mandoc_vmsg(MANDOCERR_CHAR_ARG, r->parse, |
mandoc_msg(MANDOCERR_CHAR_ARG, ln, pos, "char %s", kp); |
ln, pos, "char %s", kp); |
|
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
ksz = p - kp; |
ksz = p - kp; |
Line 3370 roff_char(ROFF_ARGS) |
|
Line 3377 roff_char(ROFF_ARGS) |
|
} |
} |
} |
} |
if (font > 1) |
if (font > 1) |
mandoc_msg(MANDOCERR_CHAR_FONT, r->parse, |
mandoc_msg(MANDOCERR_CHAR_FONT, |
ln, vp - buf->buf, vp); |
ln, (int)(vp - buf->buf), "%s", vp); |
|
|
/* |
/* |
* Approximate the effect of .char using the .tr tables. |
* Approximate the effect of .char using the .tr tables. |
Line 3404 roff_ec(ROFF_ARGS) |
|
Line 3411 roff_ec(ROFF_ARGS) |
|
else { |
else { |
r->escape = *p; |
r->escape = *p; |
if (*++p != '\0') |
if (*++p != '\0') |
mandoc_vmsg(MANDOCERR_ARG_EXCESS, r->parse, |
mandoc_msg(MANDOCERR_ARG_EXCESS, ln, |
ln, p - buf->buf, "ec ... %s", p); |
(int)(p - buf->buf), "ec ... %s", p); |
} |
} |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
Line 3415 roff_eo(ROFF_ARGS) |
|
Line 3422 roff_eo(ROFF_ARGS) |
|
{ |
{ |
r->escape = '\0'; |
r->escape = '\0'; |
if (buf->buf[pos] != '\0') |
if (buf->buf[pos] != '\0') |
mandoc_vmsg(MANDOCERR_ARG_SKIP, r->parse, |
mandoc_msg(MANDOCERR_ARG_SKIP, |
ln, pos, "eo %s", buf->buf + pos); |
ln, pos, "eo %s", buf->buf + pos); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
Line 3439 roff_tr(ROFF_ARGS) |
|
Line 3446 roff_tr(ROFF_ARGS) |
|
p = buf->buf + pos; |
p = buf->buf + pos; |
|
|
if (*p == '\0') { |
if (*p == '\0') { |
mandoc_msg(MANDOCERR_REQ_EMPTY, r->parse, ln, ppos, "tr"); |
mandoc_msg(MANDOCERR_REQ_EMPTY, ln, ppos, "tr"); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
Line 3450 roff_tr(ROFF_ARGS) |
|
Line 3457 roff_tr(ROFF_ARGS) |
|
if (*first == '\\') { |
if (*first == '\\') { |
esc = mandoc_escape(&p, NULL, NULL); |
esc = mandoc_escape(&p, NULL, NULL); |
if (esc == ESCAPE_ERROR) { |
if (esc == ESCAPE_ERROR) { |
mandoc_msg(MANDOCERR_ESC_BAD, r->parse, |
mandoc_msg(MANDOCERR_ESC_BAD, ln, |
ln, (int)(p - buf->buf), first); |
(int)(p - buf->buf), "%s", first); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
fsz = (size_t)(p - first); |
fsz = (size_t)(p - first); |
Line 3461 roff_tr(ROFF_ARGS) |
|
Line 3468 roff_tr(ROFF_ARGS) |
|
if (*second == '\\') { |
if (*second == '\\') { |
esc = mandoc_escape(&p, NULL, NULL); |
esc = mandoc_escape(&p, NULL, NULL); |
if (esc == ESCAPE_ERROR) { |
if (esc == ESCAPE_ERROR) { |
mandoc_msg(MANDOCERR_ESC_BAD, r->parse, |
mandoc_msg(MANDOCERR_ESC_BAD, ln, |
ln, (int)(p - buf->buf), second); |
(int)(p - buf->buf), "%s", second); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
ssz = (size_t)(p - second); |
ssz = (size_t)(p - second); |
} else if (*second == '\0') { |
} else if (*second == '\0') { |
mandoc_vmsg(MANDOCERR_TR_ODD, r->parse, |
mandoc_msg(MANDOCERR_TR_ODD, ln, |
ln, first - buf->buf, "tr %s", first); |
(int)(first - buf->buf), "tr %s", first); |
second = " "; |
second = " "; |
p--; |
p--; |
} |
} |
Line 3503 roff_return(ROFF_ARGS) |
|
Line 3510 roff_return(ROFF_ARGS) |
|
if (r->mstackpos >= 0) |
if (r->mstackpos >= 0) |
return ROFF_IGN | ROFF_USERRET; |
return ROFF_IGN | ROFF_USERRET; |
|
|
mandoc_msg(MANDOCERR_REQ_NOMAC, r->parse, ln, ppos, "return"); |
mandoc_msg(MANDOCERR_REQ_NOMAC, ln, ppos, "return"); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
|
|
Line 3566 roff_shift(ROFF_ARGS) |
|
Line 3573 roff_shift(ROFF_ARGS) |
|
levels = 1; |
levels = 1; |
if (buf->buf[pos] != '\0' && |
if (buf->buf[pos] != '\0' && |
roff_evalnum(r, ln, buf->buf, &pos, &levels, 0) == 0) { |
roff_evalnum(r, ln, buf->buf, &pos, &levels, 0) == 0) { |
mandoc_vmsg(MANDOCERR_CE_NONUM, r->parse, |
mandoc_msg(MANDOCERR_CE_NONUM, |
ln, pos, "shift %s", buf->buf + pos); |
ln, pos, "shift %s", buf->buf + pos); |
levels = 1; |
levels = 1; |
} |
} |
if (r->mstackpos < 0) { |
if (r->mstackpos < 0) { |
mandoc_msg(MANDOCERR_REQ_NOMAC, r->parse, ln, ppos, "shift"); |
mandoc_msg(MANDOCERR_REQ_NOMAC, ln, ppos, "shift"); |
return ROFF_IGN; |
return ROFF_IGN; |
} |
} |
ctx = r->mstack + r->mstackpos; |
ctx = r->mstack + r->mstackpos; |
if (levels > ctx->argc) { |
if (levels > ctx->argc) { |
mandoc_vmsg(MANDOCERR_SHIFT, r->parse, |
mandoc_msg(MANDOCERR_SHIFT, |
ln, pos, "%d, but max is %d", levels, ctx->argc); |
ln, pos, "%d, but max is %d", levels, ctx->argc); |
levels = ctx->argc; |
levels = ctx->argc; |
} |
} |
Line 3596 roff_so(ROFF_ARGS) |
|
Line 3603 roff_so(ROFF_ARGS) |
|
char *name, *cp; |
char *name, *cp; |
|
|
name = buf->buf + pos; |
name = buf->buf + pos; |
mandoc_vmsg(MANDOCERR_SO, r->parse, ln, ppos, "so %s", name); |
mandoc_msg(MANDOCERR_SO, ln, ppos, "so %s", name); |
|
|
/* |
/* |
* Handle `so'. Be EXTREMELY careful, as we shouldn't be |
* Handle `so'. Be EXTREMELY careful, as we shouldn't be |
Line 3606 roff_so(ROFF_ARGS) |
|
Line 3613 roff_so(ROFF_ARGS) |
|
*/ |
*/ |
|
|
if (*name == '/' || strstr(name, "../") || strstr(name, "/..")) { |
if (*name == '/' || strstr(name, "../") || strstr(name, "/..")) { |
mandoc_vmsg(MANDOCERR_SO_PATH, r->parse, ln, ppos, |
mandoc_msg(MANDOCERR_SO_PATH, ln, ppos, ".so %s", name); |
".so %s", name); |
|
buf->sz = mandoc_asprintf(&cp, |
buf->sz = mandoc_asprintf(&cp, |
".sp\nSee the file %s.\n.sp", name) + 1; |
".sp\nSee the file %s.\n.sp", name) + 1; |
free(buf->buf); |
free(buf->buf); |
Line 3720 roff_getname(struct roff *r, char **cpp, int ln, int p |
|
Line 3726 roff_getname(struct roff *r, char **cpp, int ln, int p |
|
cp++; |
cp++; |
if ('\\' == *cp) |
if ('\\' == *cp) |
continue; |
continue; |
mandoc_vmsg(MANDOCERR_NAMESC, r->parse, ln, pos, |
mandoc_msg(MANDOCERR_NAMESC, ln, pos, |
"%.*s", (int)(cp - name + 1), name); |
"%.*s", (int)(cp - name + 1), name); |
mandoc_escape((const char **)&cp, NULL, NULL); |
mandoc_escape((const char **)&cp, NULL, NULL); |
break; |
break; |