aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/term.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2015-04-29 18:35:00 +0000
committerIngo Schwarze <schwarze@openbsd.org>2015-04-29 18:35:00 +0000
commit5aae14345a405f370fc687547d918a084ce6e53f (patch)
treead82ff35550789fe183a85983e962d69bf324bad /term.c
parentbc2734def665102468b1f7b8f30738fd94f658a4 (diff)
downloadmandoc-5aae14345a405f370fc687547d918a084ce6e53f.tar.gz
mandoc-5aae14345a405f370fc687547d918a084ce6e53f.tar.zst
mandoc-5aae14345a405f370fc687547d918a084ce6e53f.zip
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).
Diffstat (limited to 'term.c')
-rw-r--r--term.c70
1 files changed, 27 insertions, 43 deletions
diff --git a/term.c b/term.c
index 68f3ea04..79d116a3 100644
--- a/term.c
+++ b/term.c
@@ -1,4 +1,4 @@
-/* $Id: term.c,v 1.247 2015/04/04 17:47:18 schwarze Exp $ */
+/* $Id: term.c,v 1.248 2015/04/29 18:35:00 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -265,6 +265,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;
@@ -417,11 +418,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);
@@ -480,13 +476,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;
@@ -496,9 +492,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;
}
@@ -553,16 +554,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;
@@ -575,6 +576,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
@@ -582,29 +587,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] ||