=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.308 retrieving revision 1.311 diff -u -p -r1.308 -r1.311 --- mandoc/roff.c 2017/06/13 13:51:11 1.308 +++ mandoc/roff.c 2017/06/14 19:39:18 1.311 @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.308 2017/06/13 13:51:11 schwarze Exp $ */ +/* $Id: roff.c,v 1.311 2017/06/14 19:39:18 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * Copyright (c) 2010-2015, 2017 Ingo Schwarze @@ -146,6 +146,7 @@ static void roffnode_cleanscope(struct roff *); static void roffnode_pop(struct roff *); static void roffnode_push(struct roff *, enum roff_tok, const char *, int, int); +static enum rofferr roff_als(ROFF_ARGS); static enum rofferr roff_block(ROFF_ARGS); static enum rofferr roff_block_text(ROFF_ARGS); static enum rofferr roff_block_sub(ROFF_ARGS); @@ -222,8 +223,8 @@ static enum rofferr roff_userdef(ROFF_ARGS); const char *__roff_name[MAN_MAX + 1] = { "br", "ce", "ft", "ll", - "mc", "sp", "ta", "ti", - NULL, + "mc", "rj", "sp", "ta", + "ti", NULL, "ab", "ad", "af", "aln", "als", "am", "am1", "ami", "ami1", "as", "as1", "asciify", @@ -267,7 +268,7 @@ const char *__roff_name[MAN_MAX + 1] = { "pn", "pnr", "po", "ps", "psbb", "pshape", "pso", "ptr", "pvs", "rchar", "rd", "recursionlimit", - "return", "rfschar", "rhang", "rj", + "return", "rfschar", "rhang", "rm", "rn", "rnn", "rr", "rs", "rt", "schar", "sentchar", "shc", "shift", "sizes", "so", @@ -334,6 +335,7 @@ static struct roffmac roffs[TOKEN_NONE] = { { roff_onearg, NULL, NULL, 0 }, /* ft */ { roff_onearg, NULL, NULL, 0 }, /* ll */ { roff_onearg, NULL, NULL, 0 }, /* mc */ + { roff_onearg, NULL, NULL, 0 }, /* rj */ { roff_onearg, NULL, NULL, 0 }, /* sp */ { roff_manyarg, NULL, NULL, 0 }, /* ta */ { roff_onearg, NULL, NULL, 0 }, /* ti */ @@ -342,7 +344,7 @@ static struct roffmac roffs[TOKEN_NONE] = { { roff_line_ignore, NULL, NULL, 0 }, /* ad */ { roff_line_ignore, NULL, NULL, 0 }, /* af */ { roff_unsupp, NULL, NULL, 0 }, /* aln */ - { roff_unsupp, NULL, NULL, 0 }, /* als */ + { roff_als, NULL, NULL, 0 }, /* als */ { roff_block, roff_block_text, roff_block_sub, 0 }, /* am */ { roff_block, roff_block_text, roff_block_sub, 0 }, /* am1 */ { roff_block, roff_block_text, roff_block_sub, 0 }, /* ami */ @@ -511,7 +513,6 @@ static struct roffmac roffs[TOKEN_NONE] = { { roff_unsupp, NULL, NULL, 0 }, /* return */ { roff_unsupp, NULL, NULL, 0 }, /* rfschar */ { roff_line_ignore, NULL, NULL, 0 }, /* rhang */ - { roff_line_ignore, NULL, NULL, 0 }, /* rj */ { roff_rm, NULL, NULL, 0 }, /* rm */ { roff_rn, NULL, NULL, 0 }, /* rn */ { roff_unsupp, NULL, NULL, 0 }, /* rnn */ @@ -1549,7 +1550,7 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, /* Tables ignore most macros. */ if (r->tbl != NULL && (t == TOKEN_NONE || t == ROFF_TS || - t == ROFF_br || t == ROFF_ce || t == ROFF_sp)) { + t == ROFF_br || t == ROFF_ce || t == ROFF_rj || t == ROFF_sp)) { mandoc_msg(MANDOCERR_TBLMACRO, r->parse, ln, pos, buf->buf + spos); if (t != TOKEN_NONE) @@ -1779,8 +1780,10 @@ roff_block(ROFF_ARGS) * appended from roff_block_text() in multiline mode. */ - if (tok == ROFF_de || tok == ROFF_dei) + if (tok == ROFF_de || tok == ROFF_dei) { roff_setstrn(&r->strtab, name, namesz, "", 0, 0); + roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0); + } if (*cp == '\0') return ROFF_IGN; @@ -2065,7 +2068,7 @@ roff_evalcond(struct roff *r, int ln, char *v, int *po { char *cp, *name; size_t sz; - int number, savepos, wanttrue; + int number, savepos, istrue, wanttrue; if ('!' == v[*pos]) { wanttrue = 0; @@ -2081,17 +2084,23 @@ roff_evalcond(struct roff *r, int ln, char *v, int *po (*pos)++; return wanttrue; case 'c': - case 'd': case 'e': case 't': case 'v': (*pos)++; return !wanttrue; + case 'd': case 'r': - cp = name = v + ++*pos; - sz = roff_getname(r, &cp, ln, *pos); + cp = v + *pos + 1; + while (*cp == ' ') + cp++; + name = cp; + sz = roff_getname(r, &cp, ln, cp - v); + istrue = sz && (v[*pos] == 'r' ? roff_hasregn(r, name, sz) : + (roff_getstrn(r, name, sz) != NULL || + roff_getrenn(r, name, sz) != NULL)); *pos = cp - v; - return (sz && roff_hasregn(r, name, sz)) == wanttrue; + return istrue == wanttrue; default: break; } @@ -2243,6 +2252,7 @@ roff_ds(ROFF_ARGS) /* The rest is the value. */ roff_setstrn(&r->strtab, name, namesz, string, strlen(string), ROFF_as == tok); + roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0); return ROFF_IGN; } @@ -2654,6 +2664,7 @@ roff_rm(ROFF_ARGS) name = cp; namesz = roff_getname(r, &cp, ln, (int)(cp - buf->buf)); roff_setstrn(&r->strtab, name, namesz, NULL, 0, 0); + roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0); if (name[namesz] == '\\') break; } @@ -2880,7 +2891,7 @@ roff_onearg(ROFF_ARGS) (tok == ROFF_sp || tok == ROFF_ti)) man_breakscope(r->man, tok); - if (tok == ROFF_ce && roffce_node != NULL) { + if (roffce_node != NULL && (tok == ROFF_ce || tok == ROFF_rj)) { r->man->last = roffce_node; r->man->next = ROFF_NEXT_SIBLING; } @@ -2901,8 +2912,8 @@ roff_onearg(ROFF_ARGS) roff_word_alloc(r->man, ln, pos, buf->buf + pos); } - if (tok == ROFF_ce) { - if (r->man->last->tok == ROFF_ce) { + if (tok == ROFF_ce || tok == ROFF_rj) { + if (r->man->last->type == ROFFT_ELEM) { roff_word_alloc(r->man, ln, pos, "1"); r->man->last->flags |= NODE_NOSRC; } @@ -2952,6 +2963,32 @@ roff_manyarg(ROFF_ARGS) } static enum rofferr +roff_als(ROFF_ARGS) +{ + char *oldn, *newn, *end, *value; + size_t oldsz, newsz, valsz; + + newn = oldn = buf->buf + pos; + if (*newn == '\0') + return ROFF_IGN; + + newsz = roff_getname(r, &oldn, ln, pos); + if (newn[newsz] == '\\' || *oldn == '\0') + return ROFF_IGN; + + end = oldn; + oldsz = roff_getname(r, &end, ln, oldn - buf->buf); + if (oldsz == 0) + return ROFF_IGN; + + valsz = mandoc_asprintf(&value, ".%.*s \\$*\n", (int)oldsz, oldn); + roff_setstrn(&r->strtab, newn, newsz, value, valsz, 0); + roff_setstrn(&r->rentab, newn, newsz, NULL, 0, 0); + free(value); + return ROFF_IGN; +} + +static enum rofferr roff_br(ROFF_ARGS) { if (r->man->flags & (MAN_BLINE | MAN_ELINE)) @@ -3156,7 +3193,7 @@ roff_so(ROFF_ARGS) static enum rofferr roff_userdef(ROFF_ARGS) { - const char *arg[9], *ap; + const char *arg[16], *ap; char *cp, *n1, *n2; int expand_count, i, ib, ie; size_t asz, rsz; @@ -3168,7 +3205,7 @@ roff_userdef(ROFF_ARGS) r->argc = 0; cp = buf->buf + pos; - for (i = 0; i < 9; i++) { + for (i = 0; i < 16; i++) { if (*cp == '\0') arg[i] = ""; else {