=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.356 retrieving revision 1.362 diff -u -p -r1.356 -r1.362 --- mandoc/roff.c 2018/12/30 00:49:56 1.356 +++ mandoc/roff.c 2019/02/06 17:40:13 1.362 @@ -1,7 +1,7 @@ -/* $Id: roff.c,v 1.356 2018/12/30 00:49:56 schwarze Exp $ */ +/* $Id: roff.c,v 1.362 2019/02/06 17:40:13 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons - * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze + * Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -181,7 +181,6 @@ static int roff_als(ROFF_ARGS); static int roff_block(ROFF_ARGS); static int roff_block_text(ROFF_ARGS); static int roff_block_sub(ROFF_ARGS); -static int roff_br(ROFF_ARGS); static int roff_cblock(ROFF_ARGS); static int roff_cc(ROFF_ARGS); static int roff_ccond(struct roff *, int, int); @@ -221,6 +220,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_noarg(ROFF_ARGS); static int roff_nop(ROFF_ARGS); static int roff_nr(ROFF_ARGS); static int roff_onearg(ROFF_ARGS); @@ -257,8 +257,9 @@ static int roff_userdef(ROFF_ARGS); #define ROFFNUM_WHITE (1 << 1) /* Skip whitespace in roff_evalnum(). */ const char *__roff_name[MAN_MAX + 1] = { - "br", "ce", "ft", "ll", - "mc", "po", "rj", "sp", + "br", "ce", "fi", "ft", + "ll", "mc", "nf", + "po", "rj", "sp", "ta", "ti", NULL, "ab", "ad", "af", "aln", "als", "am", "am1", "ami", @@ -357,7 +358,6 @@ const char *__roff_name[MAN_MAX + 1] = { "HP", "SM", "SB", "BI", "IB", "BR", "RB", "R", "B", "I", "IR", "RI", - "nf", "fi", "RE", "RS", "DT", "UC", "PD", "AT", "in", "SY", "YS", "OP", @@ -367,11 +367,13 @@ const char *__roff_name[MAN_MAX + 1] = { const char *const *roff_name = __roff_name; static struct roffmac roffs[TOKEN_NONE] = { - { roff_br, NULL, NULL, 0 }, /* br */ + { roff_noarg, NULL, NULL, 0 }, /* br */ { roff_onearg, NULL, NULL, 0 }, /* ce */ + { 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_noarg, NULL, NULL, 0 }, /* nf */ { roff_onearg, NULL, NULL, 0 }, /* po */ { roff_onearg, NULL, NULL, 0 }, /* rj */ { roff_onearg, NULL, NULL, 0 }, /* sp */ @@ -401,7 +403,7 @@ static struct roffmac roffs[TOKEN_NONE] = { { roff_unsupp, NULL, NULL, 0 }, /* break */ { roff_line_ignore, NULL, NULL, 0 }, /* breakchar */ { roff_line_ignore, NULL, NULL, 0 }, /* brnl */ - { roff_br, NULL, NULL, 0 }, /* brp */ + { roff_noarg, NULL, NULL, 0 }, /* brp */ { roff_line_ignore, NULL, NULL, 0 }, /* brpnl */ { roff_unsupp, NULL, NULL, 0 }, /* c2 */ { roff_cc, NULL, NULL, 0 }, /* cc */ @@ -819,18 +821,25 @@ roff_man_free1(struct roff_man *man) free(man->meta.sodest); } +void +roff_state_reset(struct roff_man *man) +{ + man->last = man->meta.first; + man->last_es = NULL; + man->flags = 0; + man->lastsec = man->lastnamed = SEC_NONE; + man->next = ROFF_NEXT_CHILD; + roff_setreg(man->roff, "nS", 0, '='); +} + static void roff_man_alloc1(struct roff_man *man) { memset(&man->meta, 0, sizeof(man->meta)); man->meta.first = mandoc_calloc(1, sizeof(*man->meta.first)); man->meta.first->type = ROFFT_ROOT; - man->last = man->meta.first; - man->last_es = NULL; - man->flags = 0; man->meta.macroset = MACROSET_NONE; - man->lastsec = man->lastnamed = SEC_NONE; - man->next = ROFF_NEXT_CHILD; + roff_state_reset(man); } void @@ -880,6 +889,10 @@ roff_node_alloc(struct roff_man *man, int line, int po n->flags |= NODE_SYNPRETTY; else n->flags &= ~NODE_SYNPRETTY; + if ((man->flags & (ROFF_NOFILL | ROFF_NONOFILL)) == ROFF_NOFILL) + n->flags |= NODE_NOFILL; + else + n->flags &= ~NODE_NOFILL; if (man->flags & MDOC_NEWLINE) n->flags |= NODE_LINE; man->flags &= ~MDOC_NEWLINE; @@ -3179,6 +3192,7 @@ roff_Dd(ROFF_ARGS) static int roff_TE(ROFF_ARGS) { + r->man->flags &= ~ROFF_NONOFILL; if (r->tbl == NULL) { mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, "TE"); return ROFF_IGN; @@ -3323,6 +3337,7 @@ roff_TS(ROFF_ARGS) mandoc_msg(MANDOCERR_BLK_BROKEN, ln, ppos, "TS breaks TS"); tbl_end(r->tbl, 0); } + r->man->flags |= ROFF_NONOFILL; r->tbl = tbl_alloc(ppos, ln, r->last_tbl); if (r->last_tbl == NULL) r->first_tbl = r->tbl; @@ -3331,6 +3346,26 @@ roff_TS(ROFF_ARGS) } static int +roff_noarg(ROFF_ARGS) +{ + if (r->man->flags & (MAN_BLINE | MAN_ELINE)) + man_breakscope(r->man, tok); + if (tok == ROFF_brp) + tok = ROFF_br; + roff_elem_alloc(r->man, ln, ppos, tok); + if (buf->buf[pos] != '\0') + mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos, + "%s %s", roff_name[tok], buf->buf + pos); + if (tok == ROFF_nf) + r->man->flags |= ROFF_NOFILL; + else if (tok == ROFF_fi) + r->man->flags &= ~ROFF_NOFILL; + r->man->last->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; + r->man->next = ROFF_NEXT_SIBLING; + return ROFF_IGN; +} + +static int roff_onearg(ROFF_ARGS) { struct roff_node *n; @@ -3441,20 +3476,6 @@ roff_als(ROFF_ARGS) } static int -roff_br(ROFF_ARGS) -{ - if (r->man->flags & (MAN_BLINE | MAN_ELINE)) - man_breakscope(r->man, ROFF_br); - roff_elem_alloc(r->man, ln, ppos, ROFF_br); - if (buf->buf[pos] != '\0') - mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos, - "%s %s", roff_name[tok], buf->buf + pos); - r->man->last->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; - r->man->next = ROFF_NEXT_SIBLING; - return ROFF_IGN; -} - -static int roff_cc(ROFF_ARGS) { const char *p; @@ -3844,6 +3865,10 @@ roff_renamed(ROFF_ARGS) return ROFF_CONT; } +/* + * Measure the length in bytes of the roff identifier at *cpp + * and advance the pointer to the next word. + */ static size_t roff_getname(struct roff *r, char **cpp, int ln, int pos) { @@ -3851,22 +3876,20 @@ roff_getname(struct roff *r, char **cpp, int ln, int p size_t namesz; name = *cpp; - if ('\0' == *name) + if (*name == '\0') return 0; - /* Read until end of name and terminate it with NUL. */ + /* Advance cp to the byte after the end of the name. */ + for (cp = name; 1; cp++) { - if ('\0' == *cp || ' ' == *cp) { - namesz = cp - name; + namesz = cp - name; + if (*cp == '\0' || *cp == ' ') break; - } - if ('\\' != *cp) + if (*cp != '\\') continue; - namesz = cp - name; - if ('{' == cp[1] || '}' == cp[1]) + if (cp[1] == '{' || cp[1] == '}') break; - cp++; - if ('\\' == *cp) + if (*++cp == '\\') continue; mandoc_msg(MANDOCERR_NAMESC, ln, pos, "%.*s", (int)(cp - name + 1), name); @@ -3875,7 +3898,8 @@ roff_getname(struct roff *r, char **cpp, int ln, int p } /* Read past spaces. */ - while (' ' == *cp) + + while (*cp == ' ') cp++; *cpp = cp;