=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.383 retrieving revision 1.385 diff -u -p -r1.383 -r1.385 --- mandoc/roff.c 2022/04/24 17:40:22 1.383 +++ mandoc/roff.c 2022/04/30 11:32:42 1.385 @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.383 2022/04/24 17:40:22 schwarze Exp $ */ +/* $Id: roff.c,v 1.385 2022/04/30 11:32:42 schwarze Exp $ */ /* * Copyright (c) 2010-2015, 2017-2022 Ingo Schwarze * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons @@ -227,6 +227,7 @@ static int roff_line_ignore(ROFF_ARGS); static void roff_man_alloc1(struct roff_man *); static void roff_man_free1(struct roff_man *); static int roff_manyarg(ROFF_ARGS); +static int roff_mc(ROFF_ARGS); static int roff_noarg(ROFF_ARGS); static int roff_nop(ROFF_ARGS); static int roff_nr(ROFF_ARGS); @@ -379,7 +380,7 @@ static struct roffmac roffs[TOKEN_NONE] = { { roff_noarg, NULL, NULL, 0 }, /* fi */ { roff_onearg, NULL, NULL, 0 }, /* ft */ { roff_onearg, NULL, NULL, 0 }, /* ll */ - { roff_onearg, NULL, NULL, 0 }, /* mc */ + { roff_mc, NULL, NULL, 0 }, /* mc */ { roff_noarg, NULL, NULL, 0 }, /* nf */ { roff_onearg, NULL, NULL, 0 }, /* po */ { roff_onearg, NULL, NULL, 0 }, /* rj */ @@ -2275,12 +2276,8 @@ roff_block_sub(ROFF_ARGS) int i, j; /* - * First check whether a custom macro exists at this level. If - * it does, then check against it. This is some of groff's - * stranger behaviours. If we encountered a custom end-scope - * tag and that tag also happens to be a "real" macro, then we - * need to try interpreting it again as a real macro. If it's - * not, then return ignore. Else continue. + * If a custom end marker is a user-defined or predefined macro + * or a request, interpret it. */ if (r->last->end) { @@ -2306,20 +2303,17 @@ roff_block_sub(ROFF_ARGS) } } - /* - * If we have no custom end-query or lookup failed, then try - * pulling it out of the hashtable. - */ + /* Handle the standard end marker. */ t = roff_parse(r, buf->buf, &pos, ln, ppos); + if (t == ROFF_cblock) + return roff_cblock(r, t, buf, ln, ppos, pos, offs); - if (t != ROFF_cblock) { - if (tok != ROFF_ig) - roff_setstr(r, r->last->name, buf->buf + ppos, 2); - return ROFF_IGN; - } + /* Not an end marker, so append the line to the block. */ - return (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs); + if (tok != ROFF_ig) + roff_setstr(r, r->last->name, buf->buf + ppos, 2); + return ROFF_IGN; } static int @@ -3728,6 +3722,54 @@ roff_eo(ROFF_ARGS) if (buf->buf[pos] != '\0') mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos, "eo %s", buf->buf + pos); + return ROFF_IGN; +} + +static int +roff_mc(ROFF_ARGS) +{ + struct roff_node *n; + char *cp; + + /* Parse the first argument. */ + + cp = buf->buf + pos; + if (*cp != '\0') + cp++; + if (buf->buf[pos] == '\\') { + switch (mandoc_escape((const char **)&cp, NULL, NULL)) { + case ESCAPE_SPECIAL: + case ESCAPE_UNICODE: + case ESCAPE_NUMBERED: + break; + default: + *cp = '\0'; + mandoc_msg(MANDOCERR_MC_ESC, ln, pos, + "mc %s", buf->buf + pos); + buf->buf[pos] = '\0'; + break; + } + } + + /* Ignore additional arguments. */ + + while (*cp == ' ') + *cp++ = '\0'; + if (*cp != '\0') { + mandoc_msg(MANDOCERR_MC_DIST, ln, (int)(cp - buf->buf), + "mc ... %s", cp); + *cp = '\0'; + } + + /* Create the .mc node. */ + + roff_elem_alloc(r->man, ln, ppos, tok); + n = r->man->last; + if (buf->buf[pos] != '\0') + roff_word_alloc(r->man, ln, pos, buf->buf + pos); + n->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; + r->man->last = n; + r->man->next = ROFF_NEXT_SIBLING; return ROFF_IGN; }