From f2e60d142f87cf8475f865280dbc92eca2c91a26 Mon Sep 17 00:00:00 2001 From: schwarze Date: Wed, 29 Apr 2015 18:32:57 +0000 Subject: [PATCH] Replace the kludge for the \z escape sequence by an actual implementation. As a side effect, minus ten lines of code. As another side effect, this also fixes the assertion failure that used to be triggered by "\z\o'ab'c" at the beginning of an output line, found by jsg@ with afl (test case 022/Apr27). --- regress/usr.bin/mandoc/roff/esc/Makefile | 12 +--- regress/usr.bin/mandoc/roff/esc/z.in | 6 +- regress/usr.bin/mandoc/roff/esc/z.out_ascii | 15 ++--- share/man/man7/roff.7 | 9 +-- usr.bin/mandoc/term.c | 70 ++++++++------------- usr.bin/mandoc/term.h | 17 ++--- 6 files changed, 52 insertions(+), 77 deletions(-) diff --git a/regress/usr.bin/mandoc/roff/esc/Makefile b/regress/usr.bin/mandoc/roff/esc/Makefile index ab2b01a543c..f0860368510 100644 --- a/regress/usr.bin/mandoc/roff/esc/Makefile +++ b/regress/usr.bin/mandoc/roff/esc/Makefile @@ -1,16 +1,6 @@ -# $OpenBSD: Makefile,v 1.10 2015/01/21 20:20:49 schwarze Exp $ +# $OpenBSD: Makefile,v 1.11 2015/04/29 18:32:57 schwarze Exp $ REGRESS_TARGETS = one two multi B c c_man e f h o w z ignore LINT_TARGETS = B h w ignore -# Postprocessing to remove "character backspace" sequences -# unless they are followed by the same character again. -# This removes underlining as well, so we mustn't use it. -# Cannot use /g because matches progress backwards. - -z.out_ascii: z.in - ${NROFF} ${NOPTS} -Tascii ${.ALLSRC} | \ - perl -pe 'while (s/(.)\010(?!\1)//) {}' \ - > ${.TARGET} - .include diff --git a/regress/usr.bin/mandoc/roff/esc/z.in b/regress/usr.bin/mandoc/roff/esc/z.in index 7076ebb0bcd..9d3ad1d5f1c 100644 --- a/regress/usr.bin/mandoc/roff/esc/z.in +++ b/regress/usr.bin/mandoc/roff/esc/z.in @@ -1,4 +1,4 @@ -.Dd May 28, 2012 +.Dd April 29, 2015 .Dt ESC-Z 1 .Os OpenBSD .Sh NAME @@ -17,6 +17,8 @@ single z with font escape: >\z\fBxbold\fP< single z with nospace escape: >\z\c new line< .br -single z with undefined escape: >\z\a< +single z with overstrike: >\z\o'ab'c< +.br +single z near the end of the line: >\z< .br double z: >\z\zx< diff --git a/regress/usr.bin/mandoc/roff/esc/z.out_ascii b/regress/usr.bin/mandoc/roff/esc/z.out_ascii index 935ebe6020f..233a4aa5c7b 100644 --- a/regress/usr.bin/mandoc/roff/esc/z.out_ascii +++ b/regress/usr.bin/mandoc/roff/esc/z.out_ascii @@ -4,12 +4,13 @@ NNAAMMEE eesscc--zz - the roff escape z sequence DDEESSCCRRIIPPTTIIOONN - single z with ASCII char: >< - single z with escape char: >< - single z with defined string (mytext): >ytext< - single z with font escape: >bboolldd< + single z with ASCII char: >x< + single z with escape char: >O< + single z with defined string (mytext): >mytext< + single z with font escape: >xxbboolldd< single z with nospace escape: > new line< - single z with undefined escape: >< - double z: >< + single z with overstrike: >abc< + single z near the end of the line: >< + double z: >x< -OpenBSD May 28, 2012 OpenBSD +OpenBSD April 29, 2015 OpenBSD diff --git a/share/man/man7/roff.7 b/share/man/man7/roff.7 index 432ff0339d6..13743c13fc1 100644 --- a/share/man/man7/roff.7 +++ b/share/man/man7/roff.7 @@ -1,4 +1,4 @@ -.\" $OpenBSD: roff.7,v 1.50 2015/02/17 17:16:11 schwarze Exp $ +.\" $OpenBSD: roff.7,v 1.51 2015/04/29 18:32:57 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons .\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: February 17 2015 $ +.Dd $Mdocdate: April 29 2015 $ .Dt ROFF 7 .Os .Sh NAME @@ -2026,10 +2026,7 @@ Print with zero width and height; ignored by .Xr mandoc 1 . .Ss \ez -Output the next character without advancing the cursor position; -approximated in -.Xr mandoc 1 -by simply skipping the next character. +Output the next character without advancing the cursor position. .Sh COMPATIBILITY The .Xr mandoc 1 diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c index 9e6ee91a392..141f548e1ee 100644 --- a/usr.bin/mandoc/term.c +++ b/usr.bin/mandoc/term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: term.c,v 1.107 2015/04/04 17:46:58 schwarze Exp $ */ +/* $OpenBSD: term.c,v 1.108 2015/04/29 18:32:57 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2015 Ingo Schwarze @@ -263,6 +263,7 @@ term_flushln(struct termp *p) p->col = 0; p->overstep = 0; + p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE); if ( ! (TERMP_NOBREAK & p->flags)) { p->viscol = 0; @@ -415,11 +416,6 @@ term_word(struct termp *p, const char *word) while ('\0' != *word) { if ('\\' != *word) { - if (TERMP_SKIPCHAR & p->flags) { - p->flags &= ~TERMP_SKIPCHAR; - word++; - continue; - } if (TERMP_NBRWORD & p->flags) { if (' ' == *word) { encode(p, nbrsp, 1); @@ -478,13 +474,13 @@ term_word(struct termp *p, const char *word) term_fontlast(p); continue; case ESCAPE_NOSPACE: - if (TERMP_SKIPCHAR & p->flags) - p->flags &= ~TERMP_SKIPCHAR; - else if ('\0' == *word) + if (p->flags & TERMP_BACKAFTER) + p->flags &= ~TERMP_BACKAFTER; + else if (*word == '\0') p->flags |= (TERMP_NOSPACE | TERMP_NONEWLINE); continue; case ESCAPE_SKIPCHAR: - p->flags |= TERMP_SKIPCHAR; + p->flags |= TERMP_BACKAFTER; continue; case ESCAPE_OVERSTRIKE: cp = seq + sz; @@ -494,9 +490,14 @@ term_word(struct termp *p, const char *word) continue; } encode1(p, *seq++); - if (seq < cp) - encode(p, "\b", 1); + if (seq < cp) { + if (p->flags & TERMP_BACKBEFORE) + p->flags |= TERMP_BACKAFTER; + else + p->flags |= TERMP_BACKBEFORE; + } } + continue; default: continue; } @@ -551,16 +552,16 @@ encode1(struct termp *p, int c) { enum termfont f; - if (TERMP_SKIPCHAR & p->flags) { - p->flags &= ~TERMP_SKIPCHAR; - return; - } + if (p->col + 7 >= p->maxcols) + adjbuf(p, p->col + 7); - if (p->col + 6 >= p->maxcols) - adjbuf(p, p->col + 6); - - f = p->fontq[p->fonti]; + f = (c == ASCII_HYPH || isgraph(c)) ? + p->fontq[p->fonti] : TERMFONT_NONE; + if (p->flags & TERMP_BACKBEFORE) { + p->buf[p->col++] = 8; + p->flags &= ~TERMP_BACKBEFORE; + } if (TERMFONT_UNDER == f || TERMFONT_BI == f) { p->buf[p->col++] = '_'; p->buf[p->col++] = 8; @@ -573,6 +574,10 @@ encode1(struct termp *p, int c) p->buf[p->col++] = 8; } p->buf[p->col++] = c; + if (p->flags & TERMP_BACKAFTER) { + p->flags |= TERMP_BACKBEFORE; + p->flags &= ~TERMP_BACKAFTER; + } } static void @@ -580,29 +585,8 @@ encode(struct termp *p, const char *word, size_t sz) { size_t i; - if (TERMP_SKIPCHAR & p->flags) { - p->flags &= ~TERMP_SKIPCHAR; - return; - } - - /* - * Encode and buffer a string of characters. If the current - * font mode is unset, buffer directly, else encode then buffer - * character by character. - */ - - if (p->fontq[p->fonti] == TERMFONT_NONE) { - if (p->col + sz >= p->maxcols) - adjbuf(p, p->col + sz); - for (i = 0; i < sz; i++) - p->buf[p->col++] = word[i]; - return; - } - - /* Pre-buffer, assuming worst-case. */ - - if (p->col + 1 + (sz * 5) >= p->maxcols) - adjbuf(p, p->col + 1 + (sz * 5)); + if (p->col + 2 + (sz * 5) >= p->maxcols) + adjbuf(p, p->col + 2 + (sz * 5)); for (i = 0; i < sz; i++) { if (ASCII_HYPH == word[i] || diff --git a/usr.bin/mandoc/term.h b/usr.bin/mandoc/term.h index 9a677c7b37a..47e14f8c813 100644 --- a/usr.bin/mandoc/term.h +++ b/usr.bin/mandoc/term.h @@ -1,4 +1,4 @@ -/* $OpenBSD: term.h,v 1.57 2015/04/04 17:46:58 schwarze Exp $ */ +/* $OpenBSD: term.h,v 1.58 2015/04/29 18:32:57 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2011-2015 Ingo Schwarze @@ -67,13 +67,14 @@ struct termp { int overstep; /* See termp_flushln(). */ int skipvsp; /* Vertical space to skip. */ int flags; -#define TERMP_SENTENCE (1 << 1) /* Space before a sentence. */ -#define TERMP_NOSPACE (1 << 2) /* No space before words. */ -#define TERMP_NONOSPACE (1 << 3) /* No space (no autounset). */ -#define TERMP_NBRWORD (1 << 4) /* Make next word nonbreaking. */ -#define TERMP_KEEP (1 << 5) /* Keep words together. */ -#define TERMP_PREKEEP (1 << 6) /* ...starting with the next one. */ -#define TERMP_SKIPCHAR (1 << 7) /* Skip the next character. */ +#define TERMP_SENTENCE (1 << 0) /* Space before a sentence. */ +#define TERMP_NOSPACE (1 << 1) /* No space before words. */ +#define TERMP_NONOSPACE (1 << 2) /* No space (no autounset). */ +#define TERMP_NBRWORD (1 << 3) /* Make next word nonbreaking. */ +#define TERMP_KEEP (1 << 4) /* Keep words together. */ +#define TERMP_PREKEEP (1 << 5) /* ...starting with the next one. */ +#define TERMP_BACKAFTER (1 << 6) /* Back up after next character. */ +#define TERMP_BACKBEFORE (1 << 7) /* Back up before next character. */ #define TERMP_NOBREAK (1 << 8) /* See term_flushln(). */ #define TERMP_BRIND (1 << 9) /* See term_flushln(). */ #define TERMP_DANGLE (1 << 10) /* See term_flushln(). */ -- 2.20.1