summaryrefslogtreecommitdiff
path: root/Src/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/Src/utils.c b/Src/utils.c
index db4352908..733f57088 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -5323,7 +5323,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr)
char inchar, *laststart;
size_t ret;
wchar_t wc;
- int num, num_in_char;
+ int num, num_in_char, complete;
if (!isset(MULTIBYTE))
return ztrlen(ptr);
@@ -5331,6 +5331,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr)
laststart = ptr;
ret = MB_INVALID;
num = num_in_char = 0;
+ complete = 1;
memset(&mb_shiftstate, 0, sizeof(mb_shiftstate));
while (*ptr && !(eptr && ptr >= eptr)) {
@@ -5339,6 +5340,18 @@ mb_metastrlenend(char *ptr, int width, char *eptr)
else
inchar = *ptr;
ptr++;
+
+ if (complete && (inchar >= 0 && inchar <= 0x7f)) {
+ /*
+ * We rely on 7-bit US-ASCII as a subset, so skip
+ * multibyte handling if we have such a character.
+ */
+ num++;
+ laststart = ptr;
+ num_in_char = 0;
+ continue;
+ }
+
ret = mbrtowc(&wc, &inchar, 1, &mb_shiftstate);
if (ret == MB_INCOMPLETE) {
@@ -5358,6 +5371,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr)
* so we don't count characters twice.
*/
num_in_char++;
+ complete = 0;
} else {
if (ret == MB_INVALID) {
/* Reset, treat as single character */
@@ -5380,6 +5394,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr)
num++;
laststart = ptr;
num_in_char = 0;
+ complete = 1;
}
}