=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.330 retrieving revision 1.336 diff -u -p -r1.330 -r1.336 --- mandoc/roff.c 2018/08/10 04:41:25 1.330 +++ mandoc/roff.c 2018/08/19 17:46:14 1.336 @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.330 2018/08/10 04:41:25 schwarze Exp $ */ +/* $Id: roff.c,v 1.336 2018/08/19 17:46:14 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze @@ -327,6 +327,7 @@ const char *__roff_name[MAN_MAX + 1] = { "Dx", "%Q", "%U", "Ta", NULL, "TH", "SH", "SS", "TP", + "TQ", "LP", "PP", "P", "IP", "HP", "SM", "SB", "BI", "IB", "BR", "RB", "R", @@ -334,7 +335,8 @@ const char *__roff_name[MAN_MAX + 1] = { "nf", "fi", "RE", "RS", "DT", "UC", "PD", "AT", "in", - "OP", "EX", "EE", "UR", + "SY", "YS", "OP", + "EX", "EE", "UR", "UE", "MT", "ME", NULL }; const char *const *roff_name = __roff_name; @@ -1203,9 +1205,17 @@ roff_res(struct roff *r, struct buf *buf, int ln, int r->man->next = ROFF_NEXT_SIBLING; } - /* Discard comments. */ + /* Line continuation with comment. */ - while (stesc > start && stesc[-1] == ' ') + if (stesc[1] == '#') { + *stesc = '\0'; + return ROFF_APPEND; + } + + /* Discard normal comments. */ + + while (stesc > start && stesc[-1] == ' ' && + (stesc == start + 1 || stesc[-2] != '\\')) stesc--; *stesc = '\0'; break; @@ -1367,6 +1377,19 @@ roff_res(struct roff *r, struct buf *buf, int ln, int if (arg_complete) { deftype = ROFFDEF_USER | ROFFDEF_PRE; res = roff_getstrn(r, stnam, naml, &deftype); + + /* + * If not overriden, let \*(.T + * through to the formatters. + */ + + if (res == NULL && naml == 2 && + stnam[0] == '.' && stnam[1] == 'T') { + roff_setstrn(&r->strtab, + ".T", 2, NULL, 0, 0); + stesc--; + continue; + } } break; case 'B': @@ -2145,9 +2168,10 @@ out: static int roff_evalcond(struct roff *r, int ln, char *v, int *pos) { - char *cp, *name; - size_t sz; - int deftype, number, savepos, istrue, wanttrue; + const char *start, *end; + char *cp, *name; + size_t sz; + int deftype, len, number, savepos, istrue, wanttrue; if ('!' == v[*pos]) { wanttrue = 0; @@ -2162,12 +2186,50 @@ roff_evalcond(struct roff *r, int ln, char *v, int *po case 'o': (*pos)++; return wanttrue; - case 'c': case 'e': case 't': case 'v': (*pos)++; return !wanttrue; + case 'c': + do { + (*pos)++; + } while (v[*pos] == ' '); + + /* + * Quirk for groff compatibility: + * The horizontal tab is neither available nor unavailable. + */ + + if (v[*pos] == '\t') { + (*pos)++; + return 0; + } + + /* Printable ASCII characters are available. */ + + if (v[*pos] != '\\') { + (*pos)++; + return wanttrue; + } + + end = v + ++*pos; + switch (mandoc_escape(&end, &start, &len)) { + case ESCAPE_SPECIAL: + istrue = mchars_spec2cp(start, len) != -1; + break; + case ESCAPE_UNICODE: + istrue = 1; + break; + case ESCAPE_NUMBERED: + istrue = mchars_num2char(start, len) != -1; + break; + default: + istrue = !wanttrue; + break; + } + *pos = end - v; + return istrue == wanttrue; case 'd': case 'r': cp = v + *pos + 1;