=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/roff.c,v retrieving revision 1.176 retrieving revision 1.177 diff -c -r1.176 -r1.177 *** src/usr.bin/mandoc/roff.c 2017/06/04 22:43:50 1.176 --- src/usr.bin/mandoc/roff.c 2017/06/06 15:00:56 1.177 *************** *** 1,4 **** ! /* $OpenBSD: roff.c,v 1.176 2017/06/04 22:43:50 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * Copyright (c) 2010-2015, 2017 Ingo Schwarze --- 1,4 ---- ! /* $OpenBSD: roff.c,v 1.177 2017/06/06 15:00:56 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * Copyright (c) 2010-2015, 2017 Ingo Schwarze *************** *** 187,193 **** static enum rofferr roff_onearg(ROFF_ARGS); static enum roff_tok roff_parse(struct roff *, char *, int *, int, int); ! static enum rofferr roff_parsetext(struct buf *, int, int *); static enum rofferr roff_res(struct roff *, struct buf *, int, int); static enum rofferr roff_rm(ROFF_ARGS); static enum rofferr roff_rr(ROFF_ARGS); --- 187,194 ---- static enum rofferr roff_onearg(ROFF_ARGS); static enum roff_tok roff_parse(struct roff *, char *, int *, int, int); ! static enum rofferr roff_parsetext(struct roff *, struct buf *, ! int, int *); static enum rofferr roff_res(struct roff *, struct buf *, int, int); static enum rofferr roff_rm(ROFF_ARGS); static enum rofferr roff_rr(ROFF_ARGS); *************** *** 213,227 **** #define ROFFNUM_WHITE (1 << 1) /* Skip whitespace in roff_evalnum(). */ const char *__roff_name[MAN_MAX + 1] = { ! "br", "ft", "ll", "mc", ! "sp", "ta", "ti", NULL, "ab", "ad", "af", "aln", "als", "am", "am1", "ami", "ami1", "as", "as1", "asciify", "backtrace", "bd", "bleedat", "blm", "box", "boxa", "bp", "BP", "break", "breakchar", "brnl", "brp", ! "brpnl", "c2", "cc", "ce", "cf", "cflags", "ch", "char", "chop", "class", "close", "CL", "color", "composite", "continue", "cp", --- 214,229 ---- #define ROFFNUM_WHITE (1 << 1) /* Skip whitespace in roff_evalnum(). */ const char *__roff_name[MAN_MAX + 1] = { ! "br", "ce", "ft", "ll", ! "mc", "sp", "ta", "ti", ! NULL, "ab", "ad", "af", "aln", "als", "am", "am1", "ami", "ami1", "as", "as1", "asciify", "backtrace", "bd", "bleedat", "blm", "box", "boxa", "bp", "BP", "break", "breakchar", "brnl", "brp", ! "brpnl", "c2", "cc", "cf", "cflags", "ch", "char", "chop", "class", "close", "CL", "color", "composite", "continue", "cp", *************** *** 321,326 **** --- 323,329 ---- static struct roffmac roffs[TOKEN_NONE] = { { roff_br, NULL, NULL, 0 }, /* br */ + { roff_onearg, NULL, NULL, 0 }, /* ce */ { roff_onearg, NULL, NULL, 0 }, /* ft */ { roff_onearg, NULL, NULL, 0 }, /* ll */ { roff_onearg, NULL, NULL, 0 }, /* mc */ *************** *** 355,361 **** { roff_line_ignore, NULL, NULL, 0 }, /* brpnl */ { roff_unsupp, NULL, NULL, 0 }, /* c2 */ { roff_cc, NULL, NULL, 0 }, /* cc */ - { roff_line_ignore, NULL, NULL, 0 }, /* ce */ { roff_insec, NULL, NULL, 0 }, /* cf */ { roff_line_ignore, NULL, NULL, 0 }, /* cflags */ { roff_line_ignore, NULL, NULL, 0 }, /* ch */ --- 358,363 ---- *************** *** 602,607 **** --- 604,611 ---- #include "predefs.in" }; + static int roffce_lines; /* number of input lines to center */ + static struct roff_node *roffce_node; /* active request */ static int roffit_lines; /* number of lines to delay */ static char *roffit_macro; /* nil-terminated macro line */ *************** *** 1385,1391 **** * Process text streams. */ static enum rofferr ! roff_parsetext(struct buf *buf, int pos, int *offs) { size_t sz; const char *start; --- 1389,1395 ---- * Process text streams. */ static enum rofferr ! roff_parsetext(struct roff *r, struct buf *buf, int pos, int *offs) { size_t sz; const char *start; *************** *** 1407,1412 **** --- 1411,1426 ---- } else if (roffit_lines > 1) --roffit_lines; + if (roffce_node != NULL && buf->buf[pos] != '\0') { + if (roffce_lines < 1) { + r->man->last = roffce_node; + r->man->next = ROFF_NEXT_SIBLING; + roffce_lines = 0; + roffce_node = NULL; + } else + roffce_lines--; + } + /* Convert all breakable hyphens into ASCII_HYPH. */ start = p = buf->buf + pos; *************** *** 1492,1498 **** if (r->tbl != NULL && ( ! ctl || buf->buf[pos] == '\0')) return tbl_read(r->tbl, ln, buf->buf, ppos); if ( ! ctl) ! return roff_parsetext(buf, pos, offs); /* Skip empty request lines. */ --- 1506,1512 ---- if (r->tbl != NULL && ( ! ctl || buf->buf[pos] == '\0')) return tbl_read(r->tbl, ln, buf->buf, ppos); if ( ! ctl) ! return roff_parsetext(r, buf, pos, offs); /* Skip empty request lines. */ *************** *** 1533,1538 **** --- 1547,1562 ---- return tbl_read(r->tbl, ln, buf->buf, pos); } + /* For now, let high level macros abort .ce mode. */ + + if (ctl && roffce_node != NULL && + (t == TOKEN_NONE || t == ROFF_EQ || t == ROFF_TS)) { + r->man->last = roffce_node; + r->man->next = ROFF_NEXT_SIBLING; + roffce_lines = 0; + roffce_node = NULL; + } + /* * This is neither a roff request nor a user-defined macro. * Let the standard macro set parsers handle it. *************** *** 2834,2844 **** --- 2858,2874 ---- { struct roff_node *n; char *cp; + int npos; if (r->man->flags & (MAN_BLINE | MAN_ELINE) && (tok == ROFF_sp || tok == ROFF_ti)) man_breakscope(r->man, tok); + if (tok == ROFF_ce && roffce_node != NULL) { + r->man->last = roffce_node; + r->man->next = ROFF_NEXT_SIBLING; + } + roff_elem_alloc(r->man, ln, ppos, tok); n = r->man->last; *************** *** 2855,2862 **** 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; } --- 2885,2913 ---- roff_word_alloc(r->man, ln, pos, buf->buf + pos); } ! if (tok == ROFF_ce) { ! if (r->man->last->tok == ROFF_ce) { ! roff_word_alloc(r->man, ln, pos, "1"); ! r->man->last->flags |= NODE_NOSRC; ! } ! npos = 0; ! if (roff_evalnum(r, ln, r->man->last->string, &npos, ! &roffce_lines, 0) == 0) { ! mandoc_vmsg(MANDOCERR_CE_NONUM, ! r->parse, ln, pos, "ce %s", buf->buf + pos); ! roffce_lines = 1; ! } ! if (roffce_lines < 1) { ! r->man->last = r->man->last->parent; ! roffce_node = NULL; ! roffce_lines = 0; ! } else ! roffce_node = r->man->last->parent; ! } else { ! n->flags |= NODE_VALID | NODE_ENDED; ! r->man->last = n; ! } ! n->flags |= NODE_LINE; r->man->next = ROFF_NEXT_SIBLING; return ROFF_IGN; }