version 1.257, 2022/04/30 11:32:39 |
version 1.258, 2022/04/30 18:46:16 |
|
|
static int roff_parsetext(struct roff *, struct buf *, |
static int roff_parsetext(struct roff *, struct buf *, |
int, int *); |
int, int *); |
static int roff_renamed(ROFF_ARGS); |
static int roff_renamed(ROFF_ARGS); |
|
static int roff_req_or_macro(ROFF_ARGS); |
static int roff_return(ROFF_ARGS); |
static int roff_return(ROFF_ARGS); |
static int roff_rm(ROFF_ARGS); |
static int roff_rm(ROFF_ARGS); |
static int roff_rn(ROFF_ARGS); |
static int roff_rn(ROFF_ARGS); |
|
|
/* |
/* |
* If a scope is open, go to the child handler for that macro, |
* If a scope is open, go to the child handler for that macro, |
* as it may want to preprocess before doing anything with it. |
* as it may want to preprocess before doing anything with it. |
* Don't do so if an equation is open. |
|
*/ |
*/ |
|
|
if (r->last) { |
if (r->last) { |
|
|
return (*roffs[t].sub)(r, t, buf, ln, ppos, pos, offs); |
return (*roffs[t].sub)(r, t, buf, ln, ppos, pos, offs); |
} |
} |
|
|
/* No scope is open. This is a new request or macro. */ |
|
|
|
r->options &= ~MPARSE_COMMENT; |
r->options &= ~MPARSE_COMMENT; |
spos = pos; |
spos = pos; |
t = roff_parse(r, buf->buf, &pos, ln, ppos); |
t = roff_parse(r, buf->buf, &pos, ln, ppos); |
|
return roff_req_or_macro(r, t, buf, ln, spos, pos, offs); |
|
} |
|
|
/* Tables ignore most macros. */ |
/* |
|
* Handle a new request or macro. |
|
* May be called outside any scope or from inside a conditional scope. |
|
*/ |
|
static int |
|
roff_req_or_macro(ROFF_ARGS) { |
|
|
if (r->tbl != NULL && (t == TOKEN_NONE || t == ROFF_TS || |
/* For now, tables ignore most macros and some request. */ |
t == ROFF_br || t == ROFF_ce || t == ROFF_rj || t == ROFF_sp)) { |
|
|
if (r->tbl != NULL && (tok == TOKEN_NONE || tok == ROFF_TS || |
|
tok == ROFF_br || tok == ROFF_ce || tok == ROFF_rj || |
|
tok == ROFF_sp)) { |
mandoc_msg(MANDOCERR_TBLMACRO, |
mandoc_msg(MANDOCERR_TBLMACRO, |
ln, pos, "%s", buf->buf + spos); |
ln, ppos, "%s", buf->buf + ppos); |
if (t != TOKEN_NONE) |
if (tok != TOKEN_NONE) |
return ROFF_IGN; |
return ROFF_IGN; |
while (buf->buf[pos] != '\0' && buf->buf[pos] != ' ') |
while (buf->buf[pos] != '\0' && buf->buf[pos] != ' ') |
pos++; |
pos++; |
|
|
|
|
/* For now, let high level macros abort .ce mode. */ |
/* For now, let high level macros abort .ce mode. */ |
|
|
if (ctl && roffce_node != NULL && |
if (roffce_node != NULL && |
(t == TOKEN_NONE || t == ROFF_Dd || t == ROFF_EQ || |
(tok == TOKEN_NONE || tok == ROFF_Dd || tok == ROFF_EQ || |
t == ROFF_TH || t == ROFF_TS)) { |
tok == ROFF_TH || tok == ROFF_TS)) { |
r->man->last = roffce_node; |
r->man->last = roffce_node; |
r->man->next = ROFF_NEXT_SIBLING; |
r->man->next = ROFF_NEXT_SIBLING; |
roffce_lines = 0; |
roffce_lines = 0; |
|
|
* Let the standard macro set parsers handle it. |
* Let the standard macro set parsers handle it. |
*/ |
*/ |
|
|
if (t == TOKEN_NONE) |
if (tok == TOKEN_NONE) |
return ROFF_CONT; |
return ROFF_CONT; |
|
|
/* Execute a roff request or a user defined macro. */ |
/* Execute a roff request or a user-defined macro. */ |
|
|
return (*roffs[t].proc)(r, t, buf, ln, spos, pos, offs); |
return (*roffs[tok].proc)(r, tok, buf, ln, ppos, pos, offs); |
} |
} |
|
|
/* |
/* |
|
|
} |
} |
|
|
/* |
/* |
* Parse a roff node's type from the input buffer. This must be in the |
* Parse the request or macro name at buf[*pos]. |
* form of ".foo xxx" in the usual way. |
* Return ROFF_RENAMED, ROFF_USERDEF, or a ROFF_* token value. |
|
* For empty, undefined, mdoc(7), and man(7) macros, return TOKEN_NONE. |
|
* As a side effect, set r->current_string to the definition or to NULL. |
*/ |
*/ |
static enum roff_tok |
static enum roff_tok |
roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos) |
roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos) |
|
|
roff_cond_sub(ROFF_ARGS) |
roff_cond_sub(ROFF_ARGS) |
{ |
{ |
struct roffnode *bl; |
struct roffnode *bl; |
int irc, rr; |
int irc, rr, spos; |
enum roff_tok t; |
enum roff_tok t; |
|
|
rr = 0; /* If arguments follow "\}", skip them. */ |
rr = 0; /* If arguments follow "\}", skip them. */ |
irc = roff_cond_checkend(r, tok, buf, ln, ppos, pos, &rr); |
irc = roff_cond_checkend(r, tok, buf, ln, ppos, pos, &rr); |
|
spos = pos; |
t = roff_parse(r, buf->buf, &pos, ln, ppos); |
t = roff_parse(r, buf->buf, &pos, ln, ppos); |
|
|
/* For now, let high level macros abort .ce mode. */ |
|
|
|
if (roffce_node != NULL && |
|
(t == TOKEN_NONE || t == ROFF_Dd || t == ROFF_EQ || |
|
t == ROFF_TH || t == ROFF_TS)) { |
|
r->man->last = roffce_node; |
|
r->man->next = ROFF_NEXT_SIBLING; |
|
roffce_lines = 0; |
|
roffce_node = NULL; |
|
} |
|
|
|
/* |
/* |
* Fully handle known macros when they are structurally |
* Handle requests and macros if the conditional evaluated |
* required or when the conditional evaluated to true. |
* to true or if they are structurally required. |
|
* The .break request is always handled specially. |
*/ |
*/ |
|
|
if (t == ROFF_break) { |
if (t == ROFF_break) { |
|
|
break; |
break; |
} |
} |
} |
} |
} else if (t != TOKEN_NONE && |
} else if (rr || (t < TOKEN_NONE && roffs[t].flags & ROFFMAC_STRUCT)) { |
(rr || roffs[t].flags & ROFFMAC_STRUCT)) { |
irc |= roff_req_or_macro(r, t, buf, ln, spos, pos, offs); |
irc |= (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs); |
|
if (irc & ROFF_WHILE) |
if (irc & ROFF_WHILE) |
irc &= ~(ROFF_LOOPCONT | ROFF_LOOPEXIT); |
irc &= ~(ROFF_LOOPCONT | ROFF_LOOPEXIT); |
} else |
} |
irc |= rr ? ROFF_CONT : ROFF_IGN; |
|
return irc; |
return irc; |
} |
} |
|
|