summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc/term.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2017-06-07 02:13:53 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2017-06-07 02:13:53 +0000
commitdb7806de444fc6253645c590616d4f1ffd3cf300 (patch)
tree0a4b17294759a5fcb6c82e35185a84eb6347b6f0 /usr.bin/mandoc/term.c
parent358cd1eb4d75ea6e72031ca9015decfa013a4b1f (diff)
The \h escape sequence provides another method for moving backwards,
and after that, previously written output gets overwritten, but overwriting with blanks does *not* erase previously written content. Yes, manual pages exist that are crazy enough to rely on that...
Diffstat (limited to 'usr.bin/mandoc/term.c')
-rw-r--r--usr.bin/mandoc/term.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c
index b6ca1459fd1..a7316d1ade6 100644
--- a/usr.bin/mandoc/term.c
+++ b/usr.bin/mandoc/term.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: term.c,v 1.124 2017/06/04 22:43:50 schwarze Exp $ */
+/* $OpenBSD: term.c,v 1.125 2017/06/07 02:13:52 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -115,13 +115,13 @@ term_flushln(struct termp *p)
vis = vend = 0;
i = 0;
- while (i < p->col) {
+ while (i < p->lastcol) {
/*
* Handle literal tab characters: collapse all
* subsequent tabs into a single huge set of spaces.
*/
ntab = 0;
- while (i < p->col && p->buf[i] == '\t') {
+ while (i < p->lastcol && p->buf[i] == '\t') {
vend = term_tab_next(vis);
vbl += vend - vis;
vis = vend;
@@ -136,7 +136,7 @@ term_flushln(struct termp *p)
* space is printed according to regular spacing rules).
*/
- for (j = i, jhy = 0; j < p->col; j++) {
+ for (j = i, jhy = 0; j < p->lastcol; j++) {
if (' ' == p->buf[j] || '\t' == p->buf[j])
break;
@@ -191,14 +191,14 @@ term_flushln(struct termp *p)
}
/* Write out the [remaining] word. */
- for ( ; i < p->col; i++) {
+ for ( ; i < p->lastcol; i++) {
if (vend > bp && jhy > 0 && i > jhy)
break;
if ('\t' == p->buf[i])
break;
if (' ' == p->buf[i]) {
j = i;
- while (i < p->col && ' ' == p->buf[i])
+ while (i < p->lastcol && ' ' == p->buf[i])
i++;
dv = (i - j) * (*p->width)(p, ' ');
vbl += dv;
@@ -241,7 +241,7 @@ term_flushln(struct termp *p)
else
vis = 0;
- p->col = 0;
+ p->col = p->lastcol = 0;
p->minbl = p->trailspace;
p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE | TERMP_NOPAD);
@@ -285,7 +285,7 @@ term_newln(struct termp *p)
{
p->flags |= TERMP_NOSPACE;
- if (p->col || p->viscol)
+ if (p->lastcol || p->viscol)
term_flushln(p);
}
@@ -554,10 +554,12 @@ term_word(struct termp *p, const char *word)
}
}
/* Trim trailing backspace/blank pair. */
- if (p->col > 2 &&
- (p->buf[p->col - 1] == ' ' ||
- p->buf[p->col - 1] == '\t'))
- p->col -= 2;
+ if (p->lastcol > 2 &&
+ (p->buf[p->lastcol - 1] == ' ' ||
+ p->buf[p->lastcol - 1] == '\t'))
+ p->lastcol -= 2;
+ if (p->col > p->lastcol)
+ p->col = p->lastcol;
continue;
default:
continue;
@@ -602,7 +604,10 @@ bufferc(struct termp *p, char c)
}
if (p->col + 1 >= p->maxcols)
adjbuf(p, p->col + 1);
- p->buf[p->col++] = c;
+ if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
+ p->buf[p->col] = c;
+ if (p->lastcol < ++p->col)
+ p->lastcol = p->col;
}
/*
@@ -644,7 +649,10 @@ encode1(struct termp *p, int c)
p->buf[p->col++] = c;
p->buf[p->col++] = 8;
}
- p->buf[p->col++] = c;
+ if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
+ p->buf[p->col] = c;
+ if (p->lastcol < ++p->col)
+ p->lastcol = p->col;
if (p->flags & TERMP_BACKAFTER) {
p->flags |= TERMP_BACKBEFORE;
p->flags &= ~TERMP_BACKAFTER;
@@ -670,7 +678,10 @@ encode(struct termp *p, const char *word, size_t sz)
isgraph((unsigned char)word[i]))
encode1(p, word[i]);
else {
- p->buf[p->col++] = word[i];
+ if (p->lastcol <= p->col ||
+ (word[i] != ' ' && word[i] != ASCII_NBRSP))
+ p->buf[p->col] = word[i];
+ p->col++;
/*
* Postpone the effect of \z while handling
@@ -684,6 +695,8 @@ encode(struct termp *p, const char *word, size_t sz)
}
}
}
+ if (p->lastcol < p->col)
+ p->lastcol = p->col;
}
void