commit c2d8641f019cbee5c629a8db4c616a98d1e6c434
parent 3d5e51bcd0e3e3e078ce4a86ff380339bbbb0e0d
Author: Benno Schulenberg <bensberg@telfort.nl>
Date: Mon, 21 Oct 2019 12:21:46 +0200
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.
Diffstat:
5 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/src/chars.c b/src/chars.c
@@ -332,6 +332,35 @@ int parse_mbchar(const char *buf, char *chr, size_t *col)
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
* before the one at pos. */
size_t step_left(const char *buf, size_t pos)
diff --git a/src/proto.h b/src/proto.h
@@ -217,6 +217,7 @@ char *make_mbchar(long chr, int *chr_mb_len);
int char_length(const char *pointer);
size_t mbstrlen(const char *s);
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_right(const char *buf, size_t pos);
int mbstrcasecmp(const char *s1, const char *s2);
diff --git a/src/text.c b/src/text.c
@@ -1579,7 +1579,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl)
break;
}
- charlen = parse_mbchar(line, NULL, &column);
+ charlen = advance_over(line, &column);
line += charlen;
index += charlen;
}
diff --git a/src/utils.c b/src/utils.c
@@ -379,7 +379,7 @@ size_t actual_x(const char *text, size_t column)
/* The current accumulated span, in columns. */
while (*text != '\0') {
- int charlen = parse_mbchar(text, NULL, &width);
+ int charlen = advance_over(text, &width);
if (width > column)
break;
@@ -400,7 +400,7 @@ size_t wideness(const char *text, size_t maxlen)
return 0;
while (*text != '\0') {
- size_t charlen = parse_mbchar(text, NULL, &width);
+ size_t charlen = advance_over(text, &width);
if (maxlen <= charlen)
break;
@@ -418,7 +418,7 @@ size_t breadth(const char *text)
size_t span = 0;
while (*text != '\0')
- text += parse_mbchar(text, NULL, &span);
+ text += advance_over(text, &span);
return span;
}
diff --git a/src/winio.c b/src/winio.c
@@ -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. */
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. */
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);
- text += parse_mbchar(text, NULL, &column);
+ text += advance_over(text, &column);
}
/* 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
* after that blank -- if it doesn't overshoot the screen's edge. */
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)
return last_blank_col;