chars: add a faster version of the character-parsing function

It elides a parameter that is always NULL, and elides two ifs
that always take the same path.
master
Benno Schulenberg 2019-10-21 12:21:46 +02:00
parent 3d5e51bcd0
commit c2d8641f01
5 changed files with 37 additions and 7 deletions

View File

@ -332,6 +332,35 @@ int parse_mbchar(const char *buf, char *chr, size_t *col)
return length; return length;
} }
/* Return the length (in bytes) of the character at the start of
* the given string, and add this character's width to *column. */
int advance_over(const char *string, size_t *column)
{
int charlen;
#ifdef ENABLE_UTF8
if ((signed char)*string < 0) {
charlen = mblen(string, MAXCHARLEN);
if (charlen <= 0)
charlen = 1;
} else
#endif
charlen = 1;
if (*string == '\t')
*column += tabsize - *column % tabsize;
else if (is_cntrl_mbchar(string))
*column += 2;
else if (charlen == 1)
*column += 1;
#ifdef ENABLE_UTF8
else
*column += mbwidth(string);
#endif
return charlen;
}
/* Return the index in buf of the beginning of the multibyte character /* Return the index in buf of the beginning of the multibyte character
* before the one at pos. */ * before the one at pos. */
size_t step_left(const char *buf, size_t pos) size_t step_left(const char *buf, size_t pos)

View File

@ -217,6 +217,7 @@ char *make_mbchar(long chr, int *chr_mb_len);
int char_length(const char *pointer); int char_length(const char *pointer);
size_t mbstrlen(const char *s); size_t mbstrlen(const char *s);
int parse_mbchar(const char *buf, char *chr, size_t *col); int parse_mbchar(const char *buf, char *chr, size_t *col);
int advance_over(const char *string, size_t *column);
size_t step_left(const char *buf, size_t pos); size_t step_left(const char *buf, size_t pos);
size_t step_right(const char *buf, size_t pos); size_t step_right(const char *buf, size_t pos);
int mbstrcasecmp(const char *s1, const char *s2); int mbstrcasecmp(const char *s1, const char *s2);

View File

@ -1579,7 +1579,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl)
break; break;
} }
charlen = parse_mbchar(line, NULL, &column); charlen = advance_over(line, &column);
line += charlen; line += charlen;
index += charlen; index += charlen;
} }

View File

@ -379,7 +379,7 @@ size_t actual_x(const char *text, size_t column)
/* The current accumulated span, in columns. */ /* The current accumulated span, in columns. */
while (*text != '\0') { while (*text != '\0') {
int charlen = parse_mbchar(text, NULL, &width); int charlen = advance_over(text, &width);
if (width > column) if (width > column)
break; break;
@ -400,7 +400,7 @@ size_t wideness(const char *text, size_t maxlen)
return 0; return 0;
while (*text != '\0') { while (*text != '\0') {
size_t charlen = parse_mbchar(text, NULL, &width); size_t charlen = advance_over(text, &width);
if (maxlen <= charlen) if (maxlen <= charlen)
break; break;
@ -418,7 +418,7 @@ size_t breadth(const char *text)
size_t span = 0; size_t span = 0;
while (*text != '\0') while (*text != '\0')
text += parse_mbchar(text, NULL, &span); text += advance_over(text, &span);
return span; return span;
} }

View File

@ -3045,7 +3045,7 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
/* First find the place in text where the current chunk starts. */ /* First find the place in text where the current chunk starts. */
while (*text != '\0' && column < leftedge) while (*text != '\0' && column < leftedge)
text += parse_mbchar(text, NULL, &column); text += advance_over(text, &column);
/* Now find the place in text where this chunk should end. */ /* Now find the place in text where this chunk should end. */
while (*text != '\0' && column <= goal_column) { while (*text != '\0' && column <= goal_column) {
@ -3056,7 +3056,7 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
} }
breaking_col = (*text == '\t' ? goal_column : column); breaking_col = (*text == '\t' ? goal_column : column);
text += parse_mbchar(text, NULL, &column); text += advance_over(text, &column);
} }
/* If we didn't overshoot the limit, we've found a breaking point; /* If we didn't overshoot the limit, we've found a breaking point;
@ -3069,7 +3069,7 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
/* If we're softwrapping at blanks and we found at least one blank, break /* If we're softwrapping at blanks and we found at least one blank, break
* after that blank -- if it doesn't overshoot the screen's edge. */ * after that blank -- if it doesn't overshoot the screen's edge. */
if (farthest_blank != NULL) { if (farthest_blank != NULL) {
parse_mbchar(farthest_blank, NULL, &last_blank_col); advance_over(farthest_blank, &last_blank_col);
if (last_blank_col <= goal_column) if (last_blank_col <= goal_column)
return last_blank_col; return last_blank_col;