Merge line_t.vischar into line_t.len #1

This has become possible/necessary because the full truth about multi-byte
characters and/or escape sequences lives only in line_t.mbtext.
This commit is contained in:
Thomas Jensen 2021-01-30 21:03:57 +01:00
parent a6a5898341
commit 865432a2da
No known key found for this signature in database
GPG Key ID: A4ACEE270D0FB7DB
3 changed files with 26 additions and 33 deletions

View File

@ -1291,11 +1291,10 @@ static int apply_substitutions (const int mode)
return 1; return 1;
} }
input.lines[k].vischar += buf_len - input.lines[k].len;
input.lines[k].len = buf_len; input.lines[k].len = buf_len;
if (input.lines[k].vischar > input.maxline) if (input.lines[k].len > input.maxline)
input.maxline = input.lines[k].vischar; input.maxline = input.lines[k].len;
#ifdef REGEXP_DEBUG #ifdef REGEXP_DEBUG
fprintf (stderr, "input.lines[%d] == {%d, \"%s\"}\n", k, fprintf (stderr, "input.lines[%d] == {%d, \"%s\"}\n", k,
@ -1351,7 +1350,7 @@ static int has_linebreak (const uint32_t *s, const int len)
static size_t count_invisible_chars(const uint32_t *s, const size_t buflen, size_t *num_esc, char **ascii) static size_t count_invisible_chars(const uint32_t *s, const size_t buflen, size_t *num_esc, char **ascii)
{ {
size_t invis = 0; /* counts invisible characters */ size_t invis = 0; /* counts invisible column positions */
int ansipos = 0; /* progression of ansi sequence */ int ansipos = 0; /* progression of ansi sequence */
*num_esc = 0; /* counts the number of escape sequences found */ *num_esc = 0; /* counts the number of escape sequences found */
@ -1489,11 +1488,9 @@ static int read_all_input (const int use_stdin)
size_t invis = count_invisible_chars(input.lines[input.anz_lines].mbtext, strlen(buf), &num_esc, size_t invis = count_invisible_chars(input.lines[input.anz_lines].mbtext, strlen(buf), &num_esc,
&(input.lines[input.anz_lines].text)); &(input.lines[input.anz_lines].text));
input.lines[input.anz_lines].invis = invis; input.lines[input.anz_lines].invis = invis;
input.lines[input.anz_lines].vischar = len_chars - invis;
/* u32_strwidth() does not count control characters, i.e. ESC characters, for which we must correct */ /* u32_strwidth() does not count control characters, i.e. ESC characters, for which we must correct */
input.lines[input.anz_lines].len = size_t mbtext_cols = u32_strwidth(input.lines[input.anz_lines].mbtext, encoding);
u32_strwidth(input.lines[input.anz_lines].mbtext, encoding) - invis + num_esc; input.lines[input.anz_lines].len = mbtext_cols - invis + num_esc;
input.lines[input.anz_lines].num_leading_blanks = 0; input.lines[input.anz_lines].num_leading_blanks = 0;
/* /*
@ -1558,7 +1555,6 @@ static int read_all_input (const int use_stdin)
memmove(input.lines[i].text, input.lines[i].text + input.indent, memmove(input.lines[i].text, input.lines[i].text + input.indent,
input.lines[i].len - input.indent + 1); input.lines[i].len - input.indent + 1);
input.lines[i].len -= input.indent; input.lines[i].len -= input.indent;
input.lines[i].vischar -= input.indent;
u32_move(input.lines[i].mbtext, input.lines[i].mbtext + input.indent, u32_move(input.lines[i].mbtext, input.lines[i].mbtext + input.indent,
input.lines[i].num_chars - input.indent + 1); input.lines[i].num_chars - input.indent + 1);
@ -1572,12 +1568,12 @@ static int read_all_input (const int use_stdin)
* Apply regular expression substitutions * Apply regular expression substitutions
*/ */
if (opt.r == 0) { if (opt.r == 0) {
if (apply_substitutions(0) != 0) { // TODO HERE if (apply_substitutions(0) != 0) { // TODO
return 1; return 1;
} }
} }
#if 1 #if 0
/* /*
* Debugging Code: Display contents of input structure * Debugging Code: Display contents of input structure
*/ */
@ -1599,7 +1595,7 @@ static int read_all_input (const int use_stdin)
} }
} }
fprintf (stderr, "] (%d)", (int) input.lines[i].tabpos_len); fprintf (stderr, "] (%d)", (int) input.lines[i].tabpos_len);
fprintf (stderr, "\tvis=%d, invis=%d\n", (int) input.lines[i].vischar, (int) input.lines[i].invis); fprintf (stderr, "\tinvisible=%d\n", (int) input.lines[i].invis);
} }
fprintf (stderr, " Longest line: %d columns\n", (int) input.maxline); fprintf (stderr, " Longest line: %d columns\n", (int) input.maxline);
fprintf (stderr, " Indentation: %2d spaces\n", (int) input.indent); fprintf (stderr, " Indentation: %2d spaces\n", (int) input.indent);

View File

@ -146,12 +146,13 @@ extern opt_t opt;
typedef struct { typedef struct {
size_t len; /* length of text in columns (character positions in a text terminal) */ size_t len; /* length of visible text in columns (visible character positions in a text terminal), which is the same as the length of the 'text' field */
char *text; /* ASCII line content, tabs expanded, multi-byte chars replaced with one or more 'x' */ char *text; /* ASCII line content, tabs expanded, multi-byte chars replaced with one or more 'x' */
size_t invis; /* number of invisble columns/characters (part of an ansi sequence) */
uint32_t *mbtext; /* multi-byte (original) line content, tabs expanded. We use UTF-32 in order to enable pointer arithmetic. */ uint32_t *mbtext; /* multi-byte (original) line content, tabs expanded. We use UTF-32 in order to enable pointer arithmetic. */
size_t num_chars; /* number of characters in mbtext, visible + invisible */ size_t num_chars; /* total number of characters in mbtext, visible + invisible */
size_t invis; /* number of characters part of an ansi sequence (aka "invisible") */
size_t vischar; /* number of normal printable characters (aka "visible") */
size_t *tabpos; /* tab positions in expanded work strings, or NULL if not needed */ size_t *tabpos; /* tab positions in expanded work strings, or NULL if not needed */
size_t tabpos_len; /* number of tabs in a line */ size_t tabpos_len; /* number of tabs in a line */
size_t num_leading_blanks; /* number of spaces at the start of the line after justification */ size_t num_leading_blanks; /* number of spaces at the start of the line after justification */

View File

@ -736,34 +736,32 @@ static int justify_line(line_t *line, int skew)
case 'l': case 'l':
if (opt.design->indentmode == 't') { if (opt.design->indentmode == 't') {
memmove(line->text + input.indent, p, newlen + 1); memmove(line->text + input.indent, p, newlen + 1);
line->vischar = newlen + input.indent - line->invis; line->len = newlen + input.indent;
line->len = line->vischar;
line->num_leading_blanks = input.indent; line->num_leading_blanks = input.indent;
} }
else { else {
memmove(line->text, p, newlen + 1); memmove(line->text, p, newlen + 1);
line->vischar = newlen - line->invis; line->len = newlen;
line->len = line->vischar;
line->num_leading_blanks = 0; line->num_leading_blanks = 0;
} }
break; break;
case 'c': case 'c':
if (opt.design->indentmode == 't') { if (opt.design->indentmode == 't') {
shift = (input.maxline - input.indent - newlen + line->invis) / 2 + input.indent; shift = (input.maxline - input.indent - newlen) / 2 + input.indent;
skew -= input.indent; skew -= input.indent;
if ((input.maxline - input.indent - newlen) % 2 && skew == 1) { if ((input.maxline - input.indent - newlen) % 2 && skew == 1) {
++shift; ++shift;
} }
} }
else { else {
shift = (input.maxline - newlen + line->invis) / 2; shift = (input.maxline - newlen) / 2;
if ((input.maxline - newlen + line->invis) % 2 && skew == 1) { if ((input.maxline - newlen) % 2 && skew == 1) {
++shift; ++shift;
} }
} }
newtext = (char *) calloc(shift + newlen + line->invis + 1, sizeof(char)); newtext = (char *) calloc(shift + newlen + 1, sizeof(char));
if (newtext == NULL) { if (newtext == NULL) {
perror(PROJECT); perror(PROJECT);
return 2; return 2;
@ -781,19 +779,18 @@ static int justify_line(line_t *line, int skew)
newlen, shift, spaces); newlen, shift, spaces);
#endif #endif
strncpy(newtext, spaces, shift); strncpy(newtext, spaces, shift);
strncat(newtext, p, newlen + line->invis); strncat(newtext, p, newlen);
newtext[shift + newlen + line->invis] = '\0'; newtext[shift + newlen] = '\0';
BFREE (spaces); BFREE (spaces);
BFREE (line->text); BFREE (line->text);
line->text = newtext; line->text = newtext;
line->len = shift + newlen - line->invis; line->len = shift + newlen;
line->vischar = line->len;
line->num_leading_blanks = shift; line->num_leading_blanks = shift;
break; break;
case 'r': case 'r':
shift = input.maxline - (newlen - line->invis); shift = input.maxline - newlen;
newtext = (char *) calloc(input.maxline + 1000, sizeof(char)); newtext = (char *) calloc (input.maxline+1, sizeof(char));
if (newtext == NULL) { if (newtext == NULL) {
perror(PROJECT); perror(PROJECT);
return 2; return 2;
@ -808,11 +805,10 @@ static int justify_line(line_t *line, int skew)
spaces[shift] = '\0'; spaces[shift] = '\0';
strncpy(newtext, spaces, shift); strncpy(newtext, spaces, shift);
strncat(newtext, p, newlen); strncat(newtext, p, newlen);
newtext[input.maxline + line->invis] = '\0'; newtext[input.maxline] = '\0';
BFREE (spaces); BFREE (spaces);
BFREE (line->text); BFREE (line->text);
line->text = newtext; line->text = newtext;
line->vischar = input.maxline;
line->len = input.maxline; line->len = input.maxline;
line->num_leading_blanks = shift; line->num_leading_blanks = shift;
break; break;
@ -1054,7 +1050,7 @@ int output_box(const sentry_t *thebox)
if (rc) { if (rc) {
return rc; return rc;
} }
r = input.maxline - input.lines[ti].vischar; r = input.maxline - input.lines[ti].len;
trailspc[r] = '\0'; trailspc[r] = '\0';
restored_indent = tabbify_indent(ti, indentspc, indentspclen); restored_indent = tabbify_indent(ti, indentspc, indentspclen);
if (input.lines[ti].num_leading_blanks == SIZE_MAX) { if (input.lines[ti].num_leading_blanks == SIZE_MAX) {