aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/term.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-06-07 02:14:09 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-06-07 02:14:09 +0000
commit13dededd58fd94c0507d28f08661caa187f9d989 (patch)
treecaaea1e74e6ec6d16298a1071845a03be99075a0 /term.c
parent51dbcefc64890d499c9774c7fc75ddfc3fa3cda0 (diff)
downloadmandoc-13dededd58fd94c0507d28f08661caa187f9d989.tar.gz
mandoc-13dededd58fd94c0507d28f08661caa187f9d989.tar.zst
mandoc-13dededd58fd94c0507d28f08661caa187f9d989.zip
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 'term.c')
-rw-r--r--term.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/term.c b/term.c
index f971ff67..5aebbe45 100644
--- a/term.c
+++ b/term.c
@@ -1,4 +1,4 @@
-/* $Id: term.c,v 1.264 2017/06/04 22:44:15 schwarze Exp $ */
+/* $Id: term.c,v 1.265 2017/06/07 02:14:09 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -117,13 +117,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;
@@ -138,7 +138,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;
@@ -193,14 +193,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;
@@ -243,7 +243,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);
@@ -287,7 +287,7 @@ term_newln(struct termp *p)
{
p->flags |= TERMP_NOSPACE;
- if (p->col || p->viscol)
+ if (p->lastcol || p->viscol)
term_flushln(p);
}
@@ -556,10 +556,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;
@@ -604,7 +606,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;
}
/*
@@ -646,7 +651,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;
@@ -672,7 +680,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
@@ -686,6 +697,8 @@ encode(struct termp *p, const char *word, size_t sz)
}
}
}
+ if (p->lastcol < p->col)
+ p->lastcol = p->col;
}
void