From: schwarze Date: Sat, 17 Jun 2017 13:05:47 +0000 (+0000) Subject: correct handling of blank lines after \c X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=3361af3902e32d1dfffbc2c469dc7d69664a6210;p=openbsd correct handling of blank lines after \c --- diff --git a/regress/usr.bin/mandoc/roff/esc/c.in b/regress/usr.bin/mandoc/roff/esc/c.in index c3b7a912c51..b7b47bc155a 100644 --- a/regress/usr.bin/mandoc/roff/esc/c.in +++ b/regress/usr.bin/mandoc/roff/esc/c.in @@ -15,3 +15,12 @@ word one\c word .Ed +Blank line after \ec: +one\c + +word +.Bd -literal +one\c + +word +.Ed diff --git a/regress/usr.bin/mandoc/roff/esc/c.out_ascii b/regress/usr.bin/mandoc/roff/esc/c.out_ascii index a0f6a9964a5..9f8570c47d9 100644 --- a/regress/usr.bin/mandoc/roff/esc/c.out_ascii +++ b/regress/usr.bin/mandoc/roff/esc/c.out_ascii @@ -7,5 +7,9 @@ DDEESSCCRRIIPPTTIIOONN No space between "one" and "word": oneword oneword + Blank line after \c: one word + + one + word OpenBSD December 2, 2014 OpenBSD diff --git a/regress/usr.bin/mandoc/roff/esc/c_man.in b/regress/usr.bin/mandoc/roff/esc/c_man.in index c18fad10c99..09e1ed3b226 100644 --- a/regress/usr.bin/mandoc/roff/esc/c_man.in +++ b/regress/usr.bin/mandoc/roff/esc/c_man.in @@ -7,6 +7,15 @@ one\c word .nf one\c +word +.fi +Blank line after \ec: +one\c + +word +.nf +one\c + word .fi final text diff --git a/regress/usr.bin/mandoc/roff/esc/c_man.out_ascii b/regress/usr.bin/mandoc/roff/esc/c_man.out_ascii index d00b1b48d21..9062c335ae2 100644 --- a/regress/usr.bin/mandoc/roff/esc/c_man.out_ascii +++ b/regress/usr.bin/mandoc/roff/esc/c_man.out_ascii @@ -8,6 +8,9 @@ NNAAMMEE DDEESSCCRRIIPPTTIIOONN No space between "one" and "word": oneword oneword + Blank line after \c: one word + one + word final text diff --git a/usr.bin/mandoc/man.c b/usr.bin/mandoc/man.c index ba7cdd8d386..c6ef632a5f7 100644 --- a/usr.bin/mandoc/man.c +++ b/usr.bin/mandoc/man.c @@ -1,4 +1,4 @@ -/* $OpenBSD: man.c,v 1.122 2017/06/03 15:54:09 schwarze Exp $ */ +/* $OpenBSD: man.c,v 1.123 2017/06/17 13:05:47 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze @@ -74,6 +74,8 @@ static int man_ptext(struct roff_man *man, int line, char *buf, int offs) { int i; + const char *cp, *sp; + char *ep; /* Literal free-form text whitespace is preserved. */ @@ -87,19 +89,36 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs) /* Skip leading whitespace. */ ; /* - * Blank lines are ignored in next line scope and right - * after headings but add a single vertical space elsewhere. + * Blank lines are ignored in next line scope + * and right after headings and cancel preceding \c, + * but add a single vertical space elsewhere. */ if (buf[i] == '\0') { - if (man->flags & (MAN_ELINE | MAN_BLINE)) + if (man->flags & (MAN_ELINE | MAN_BLINE)) { mandoc_msg(MANDOCERR_BLK_BLANK, man->parse, line, 0, NULL); - else if (man->last->tok != MAN_SH && - man->last->tok != MAN_SS) { - roff_elem_alloc(man, line, offs, ROFF_sp); - man->next = ROFF_NEXT_SIBLING; + return 1; } + if (man->last->tok == MAN_SH || man->last->tok == MAN_SS) + return 1; + switch (man->last->type) { + case ROFFT_TEXT: + sp = man->last->string; + cp = ep = strchr(sp, '\0') - 2; + if (cp < sp || cp[0] != '\\' || cp[1] != 'c') + break; + while (cp > sp && cp[-1] == '\\') + cp--; + if ((ep - cp) % 2) + break; + *ep = '\0'; + return 1; + default: + break; + } + roff_elem_alloc(man, line, offs, ROFF_sp); + man->next = ROFF_NEXT_SIBLING; return 1; } diff --git a/usr.bin/mandoc/man_term.c b/usr.bin/mandoc/man_term.c index c284e3f45be..7b34366e6a0 100644 --- a/usr.bin/mandoc/man_term.c +++ b/usr.bin/mandoc/man_term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: man_term.c,v 1.159 2017/06/17 01:26:48 schwarze Exp $ */ +/* $OpenBSD: man_term.c,v 1.160 2017/06/17 13:05:47 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2015, 2017 Ingo Schwarze @@ -870,7 +870,10 @@ print_man_node(DECL_ARGS) * before printing the line's data. */ if (*n->string == '\0') { - term_vspace(p); + if (p->flags & TERMP_NONEWLINE) + term_newln(p); + else + term_vspace(p); return; } else if (*n->string == ' ' && n->flags & NODE_LINE && (p->flags & TERMP_NONEWLINE) == 0) diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c index bc0ec426533..869f4a9a91b 100644 --- a/usr.bin/mandoc/mdoc.c +++ b/usr.bin/mandoc/mdoc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc.c,v 1.155 2017/06/07 20:58:36 schwarze Exp $ */ +/* $OpenBSD: mdoc.c,v 1.156 2017/06/17 13:05:47 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2012-2017 Ingo Schwarze @@ -177,6 +177,7 @@ static int mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs) { struct roff_node *n; + const char *cp, *sp; char *c, *ws, *end; n = mdoc->last; @@ -242,15 +243,30 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs) mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse, line, (int)(ws-buf), NULL); + /* + * Blank lines are allowed in no-fill mode + * and cancel preceding \c, + * but add a single vertical space elsewhere. + */ + if (buf[offs] == '\0' && ! (mdoc->flags & MDOC_LITERAL)) { + switch (mdoc->last->type) { + case ROFFT_TEXT: + sp = mdoc->last->string; + cp = end = strchr(sp, '\0') - 2; + if (cp < sp || cp[0] != '\\' || cp[1] != 'c') + break; + while (cp > sp && cp[-1] == '\\') + cp--; + if ((end - cp) % 2) + break; + *end = '\0'; + return 1; + default: + break; + } mandoc_msg(MANDOCERR_FI_BLANK, mdoc->parse, line, (int)(c - buf), NULL); - - /* - * Insert a `sp' in the case of a blank line. Technically, - * blank lines aren't allowed, but enough manuals assume this - * behaviour that we want to work around it. - */ roff_elem_alloc(mdoc, line, offs, ROFF_sp); mdoc->last->flags |= NODE_VALID | NODE_ENDED; mdoc->next = ROFF_NEXT_SIBLING;