Common: don't inline ffUtf8CharLenWidth

This commit is contained in:
Carter Li
2026-06-02 14:01:59 +08:00
parent 54f18982ac
commit 15c6014c04
3 changed files with 83 additions and 77 deletions
+1
View File
@@ -421,6 +421,7 @@ set(LIBFASTFETCH_SRC
src/common/impl/path.c
src/common/impl/FFPlatform.c
src/common/impl/smbios.c
src/common/impl/strutil.c
src/detection/bluetoothradio/bluetoothradio.c
src/detection/bootmgr/bootmgr.c
src/detection/chassis/chassis.c
+80
View File
@@ -0,0 +1,80 @@
#include "common/strutil.h"
uint8_t ffUtf8CharLenWidth(const char* str, uint32_t length, uint8_t* width) {
if (__builtin_expect(length == 0 || *str == '\0', false)) {
if (width) {
*width = 0;
}
return 0;
}
unsigned char first = (unsigned char) *str;
if (__builtin_expect(first < 0x80, true)) {
if (width) {
*width = 1;
}
return 1;
}
uint8_t bytes;
if ((first & 0xE0) == 0xC0) {
bytes = 2;
} else if ((first & 0xF0) == 0xE0) {
bytes = 3;
} else if ((first & 0xF8) == 0xF0) {
bytes = 4;
} else {
if (width) {
*width = 1;
}
return 1;
}
if (length < bytes) {
if (width) {
*width = 1;
}
return 1;
}
for (uint8_t i = 1; i < bytes; ++i) {
unsigned char continuation = (unsigned char) str[i];
if (continuation == '\0' || (continuation & 0xC0) != 0x80) {
if (width) {
*width = 1;
}
return 1;
}
}
uint32_t ucs = (uint32_t) (first & ((1U << (8 - bytes)) - 1));
for (uint8_t i = 1; i < bytes; ++i) {
ucs <<= 6;
ucs |= (uint32_t) ((unsigned char) str[i] & 0x3F);
}
int wcWidth = mk_wcwidth(ucs);
if (width) {
*width = (uint8_t) (wcWidth < 0 ? 0 : wcWidth);
}
return bytes;
}
uint32_t ffUtf8StrWidth(const char* str, uint32_t length) {
uint32_t result = 0;
const char* ptr = str;
while (length > 0 && *ptr != '\0') {
uint8_t width = 0;
uint8_t bytes = ffUtf8CharLenWidth(ptr, length, &width);
if (__builtin_expect(bytes == 0, false)) {
break;
}
result += width;
ptr += bytes;
length -= bytes;
}
return result > 0 ? result : (uint32_t) (ptr - str);
}
+2 -77
View File
@@ -82,84 +82,9 @@ static inline bool ffCharIsDigit(char c) {
// Parse one UTF-8 character, returning consumed byte count and display width.
// Invalid / incomplete sequence falls back to one-byte width=1.
// If the Unicode codepoint is non-printable, width becomes 0.
static inline uint8_t ffUtf8CharLenWidth(const char* str, uint32_t length, uint8_t* width) {
if (__builtin_expect(length == 0 || *str == '\0', false)) {
if (width) {
*width = 0;
}
return 0;
}
uint8_t ffUtf8CharLenWidth(const char* str, uint32_t length, uint8_t* width);
unsigned char first = (unsigned char) *str;
if (__builtin_expect(first < 0x80, true)) {
if (width) {
*width = 1;
}
return 1;
}
uint8_t bytes;
if ((first & 0xE0) == 0xC0) {
bytes = 2;
} else if ((first & 0xF0) == 0xE0) {
bytes = 3;
} else if ((first & 0xF8) == 0xF0) {
bytes = 4;
} else {
if (width) {
*width = 1;
}
return 1;
}
if (length < bytes) {
if (width) {
*width = 1;
}
return 1;
}
for (uint8_t i = 1; i < bytes; ++i) {
unsigned char continuation = (unsigned char) str[i];
if (continuation == '\0' || (continuation & 0xC0) != 0x80) {
if (width) {
*width = 1;
}
return 1;
}
}
uint32_t ucs = (uint32_t) (first & ((1U << (8 - bytes)) - 1));
for (uint8_t i = 1; i < bytes; ++i) {
ucs <<= 6;
ucs |= (uint32_t) ((unsigned char) str[i] & 0x3F);
}
int wcWidth = mk_wcwidth(ucs);
if (width) {
*width = (uint8_t) (wcWidth < 0 ? 0 : wcWidth);
}
return bytes;
}
static inline uint32_t ffUtf8StrWidth(const char* str, uint32_t length) {
uint32_t result = 0;
const char* ptr = str;
while (length > 0 && *ptr != '\0') {
uint8_t width = 0;
uint8_t bytes = ffUtf8CharLenWidth(ptr, length, &width);
if (__builtin_expect(bytes == 0, false)) {
break;
}
result += width;
ptr += bytes;
length -= bytes;
}
return result > 0 ? result : (uint32_t) (ptr - str);
}
uint32_t ffUtf8StrWidth(const char* str, uint32_t length);
static inline bool ffCharIsHexDigit(char c) {
return ffCharIsDigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');