version 1.281, 2019/06/03 20:23:41 |
version 1.287, 2022/08/15 10:22:14 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
|
* Copyright (c) 2010-2022 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org> |
|
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
Line 38 static void bufferc(struct termp *, char); |
|
Line 38 static void bufferc(struct termp *, char); |
|
static void encode(struct termp *, const char *, size_t); |
static void encode(struct termp *, const char *, size_t); |
static void encode1(struct termp *, int); |
static void encode1(struct termp *, int); |
static void endline(struct termp *); |
static void endline(struct termp *); |
static void term_field(struct termp *, size_t, size_t, |
static void term_field(struct termp *, size_t, size_t); |
size_t, size_t); |
|
static void term_fill(struct termp *, size_t *, size_t *, |
static void term_fill(struct termp *, size_t *, size_t *, |
size_t); |
size_t); |
|
|
Line 59 term_setcol(struct termp *p, size_t maxtcol) |
|
Line 58 term_setcol(struct termp *p, size_t maxtcol) |
|
void |
void |
term_free(struct termp *p) |
term_free(struct termp *p) |
{ |
{ |
|
term_tab_free(); |
for (p->tcol = p->tcols; p->tcol < p->tcols + p->maxtcol; p->tcol++) |
for (p->tcol = p->tcols; p->tcol < p->tcols + p->maxtcol; p->tcol++) |
free(p->tcol->buf); |
free(p->tcol->buf); |
free(p->tcols); |
free(p->tcols); |
Line 127 term_flushln(struct termp *p) |
|
Line 127 term_flushln(struct termp *p) |
|
* and with the BRNEVER flag, never break it at all. |
* and with the BRNEVER flag, never break it at all. |
*/ |
*/ |
|
|
vtarget = p->flags & TERMP_BRNEVER ? SIZE_MAX : |
vtarget = (p->flags & TERMP_NOBREAK) == 0 ? vfield : |
(p->flags & TERMP_NOBREAK) == 0 ? vfield : |
|
p->maxrmargin > p->viscol + vbl ? |
p->maxrmargin > p->viscol + vbl ? |
p->maxrmargin - p->viscol - vbl : 0; |
p->maxrmargin - p->viscol - vbl : 0; |
|
|
Line 137 term_flushln(struct termp *p) |
|
Line 136 term_flushln(struct termp *p) |
|
* If there is whitespace only, print nothing. |
* If there is whitespace only, print nothing. |
*/ |
*/ |
|
|
term_fill(p, &nbr, &vbr, vtarget); |
term_fill(p, &nbr, &vbr, |
|
p->flags & TERMP_BRNEVER ? SIZE_MAX : vtarget); |
if (nbr == 0) |
if (nbr == 0) |
break; |
break; |
|
|
Line 156 term_flushln(struct termp *p) |
|
Line 156 term_flushln(struct termp *p) |
|
|
|
/* Finally, print the field content. */ |
/* Finally, print the field content. */ |
|
|
term_field(p, vbl, nbr, vbr, vtarget); |
term_field(p, vbl, nbr); |
|
|
/* |
/* |
* If there is no text left in the field, exit the loop. |
* If there is no text left in the field, exit the loop. |
Line 268 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
Line 268 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
vis -= (*p->width)(p, p->tcol->buf[ic - 1]); |
vis -= (*p->width)(p, p->tcol->buf[ic - 1]); |
continue; |
continue; |
|
|
case '\t': /* Normal ASCII whitespace. */ |
|
case ' ': |
case ' ': |
case ASCII_BREAK: /* Escape \: (breakpoint). */ |
case ASCII_BREAK: /* Escape \: (breakpoint). */ |
switch (p->tcol->buf[ic]) { |
vn = vis; |
case '\t': |
if (p->tcol->buf[ic] == ' ') |
vn = term_tab_next(vis); |
vn += (*p->width)(p, ' '); |
break; |
|
case ' ': |
|
vn = vis + (*p->width)(p, ' '); |
|
break; |
|
case ASCII_BREAK: |
|
vn = vis; |
|
break; |
|
default: |
|
abort(); |
|
} |
|
/* Can break at the end of a word. */ |
/* Can break at the end of a word. */ |
if (breakline || vn > vtarget) |
if (breakline || vn > vtarget) |
break; |
break; |
Line 317 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
Line 306 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
*vbr = vis; |
*vbr = vis; |
continue; |
continue; |
|
|
case ASCII_NBRSP: /* Non-breakable space. */ |
default: |
p->tcol->buf[ic] = ' '; |
switch (p->tcol->buf[ic]) { |
/* FALLTHROUGH */ |
case '\t': |
default: /* Printable character. */ |
vis = term_tab_next(vis); |
|
break; |
|
case ASCII_NBRSP: /* Non-breakable space. */ |
|
p->tcol->buf[ic] = ' '; |
|
/* FALLTHROUGH */ |
|
default: /* Printable character. */ |
|
vis += (*p->width)(p, p->tcol->buf[ic]); |
|
break; |
|
} |
graph = 1; |
graph = 1; |
vis += (*p->width)(p, p->tcol->buf[ic]); |
|
if (vis > vtarget && *nbr > 0) |
if (vis > vtarget && *nbr > 0) |
return; |
return; |
continue; |
continue; |
Line 345 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
Line 341 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
/* |
/* |
* Print the contents of one field |
* Print the contents of one field |
* with an indentation of vbl visual columns, |
* with an indentation of vbl visual columns, |
* an input string length of nbr characters, |
* and an input string length of nbr characters. |
* an output width of vbr visual columns, |
|
* and a desired field width of vtarget visual columns. |
|
*/ |
*/ |
static void |
static void |
term_field(struct termp *p, size_t vbl, size_t nbr, size_t vbr, size_t vtarget) |
term_field(struct termp *p, size_t vbl, size_t nbr) |
{ |
{ |
size_t ic; /* Character position in the input buffer. */ |
size_t ic; /* Character position in the input buffer. */ |
size_t vis; /* Visual position of the current character. */ |
size_t vis; /* Visual position of the current character. */ |
Line 592 term_word(struct termp *p, const char *word) |
|
Line 586 term_word(struct termp *p, const char *word) |
|
uc = *seq; |
uc = *seq; |
break; |
break; |
case ESCAPE_FONTBOLD: |
case ESCAPE_FONTBOLD: |
|
case ESCAPE_FONTCB: |
term_fontrepl(p, TERMFONT_BOLD); |
term_fontrepl(p, TERMFONT_BOLD); |
continue; |
continue; |
case ESCAPE_FONTITALIC: |
case ESCAPE_FONTITALIC: |
|
case ESCAPE_FONTCI: |
term_fontrepl(p, TERMFONT_UNDER); |
term_fontrepl(p, TERMFONT_UNDER); |
continue; |
continue; |
case ESCAPE_FONTBI: |
case ESCAPE_FONTBI: |
term_fontrepl(p, TERMFONT_BI); |
term_fontrepl(p, TERMFONT_BI); |
continue; |
continue; |
case ESCAPE_FONT: |
case ESCAPE_FONT: |
case ESCAPE_FONTCW: |
case ESCAPE_FONTCR: |
case ESCAPE_FONTROMAN: |
case ESCAPE_FONTROMAN: |
term_fontrepl(p, TERMFONT_NONE); |
term_fontrepl(p, TERMFONT_NONE); |
continue; |
continue; |
Line 628 term_word(struct termp *p, const char *word) |
|
Line 624 term_word(struct termp *p, const char *word) |
|
encode(p, "utf8", 4); |
encode(p, "utf8", 4); |
continue; |
continue; |
case ESCAPE_HORIZ: |
case ESCAPE_HORIZ: |
|
if (p->flags & TERMP_BACKAFTER) { |
|
p->flags &= ~TERMP_BACKAFTER; |
|
continue; |
|
} |
if (*seq == '|') { |
if (*seq == '|') { |
seq++; |
seq++; |
uc = -p->col; |
uc = -p->col; |
Line 636 term_word(struct termp *p, const char *word) |
|
Line 636 term_word(struct termp *p, const char *word) |
|
if (a2roffsu(seq, &su, SCALE_EM) == NULL) |
if (a2roffsu(seq, &su, SCALE_EM) == NULL) |
continue; |
continue; |
uc += term_hen(p, &su); |
uc += term_hen(p, &su); |
if (uc > 0) |
if (uc >= 0) { |
while (uc-- > 0) |
while (uc > 0) { |
bufferc(p, ASCII_NBRSP); |
uc -= term_len(p, 1); |
else if (p->col > (size_t)(-uc)) |
if (p->flags & TERMP_BACKBEFORE) |
|
p->flags &= ~TERMP_BACKBEFORE; |
|
else |
|
bufferc(p, ASCII_NBRSP); |
|
} |
|
continue; |
|
} |
|
if (p->flags & TERMP_BACKBEFORE) { |
|
p->flags &= ~TERMP_BACKBEFORE; |
|
assert(p->col > 0); |
|
p->col--; |
|
} |
|
if (p->col >= (size_t)(-uc)) { |
p->col += uc; |
p->col += uc; |
else { |
} else { |
uc += p->col; |
uc += p->col; |
p->col = 0; |
p->col = 0; |
if (p->tcol->offset > (size_t)(-uc)) { |
if (p->tcol->offset > (size_t)(-uc)) { |