moved code from header to source files
This commit is contained in:
108
src/string.c
Executable file
108
src/string.c
Executable file
@@ -0,0 +1,108 @@
|
||||
#include "tim.h"
|
||||
|
||||
i32 tim_ztrlen(cstr s) {
|
||||
if(s == NULL)
|
||||
return 0;
|
||||
i32 n = strlen(s);
|
||||
if(n < 0)
|
||||
n = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
i32 tim_bsr8(u8 x) {
|
||||
#if defined __GNUC__ || defined __clang__
|
||||
unsigned int b = x;
|
||||
b <<= sizeof(b) * CHAR_BIT - 8;
|
||||
b |= 1 << (sizeof(b) * CHAR_BIT - 9);
|
||||
return __builtin_clz(b);
|
||||
#elif defined _MSC_VER
|
||||
unsigned long n = 0;
|
||||
unsigned long b = x;
|
||||
b <<= sizeof(b) * CHAR_BIT - 8;
|
||||
b |= 1 << (sizeof(b) * CHAR_BIT - 9);
|
||||
_BitScanReverse(&n, b);
|
||||
return n;
|
||||
#else
|
||||
i32 n = 0;
|
||||
for (; n < 8 && !(x & 128); n++, x <<= 1) {}
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
i32 tim_utf8_to_i32(cstr s) {
|
||||
s = s ? s : "";
|
||||
// use bit magic to mask out leading utf8 1s
|
||||
u32 c = s[0] & ((1 << (8 - tim_bsr8(~s[0]))) - 1);
|
||||
for (i32 i = 1; s[0] && s[i] && i < 4; i++) {
|
||||
c = (c << 6) | (s[i] & 63);
|
||||
}
|
||||
return (i32)c;
|
||||
}
|
||||
|
||||
i32 tim_utf8_len(cstr s) {
|
||||
i32 n = 0;
|
||||
for (i32 i = 0; s && s[i]; i++) {
|
||||
n += (s[i] & 192) != 128;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
i32 tim_utf8_pos(cstr s, i32 pos) {
|
||||
i32 i = 0;
|
||||
for (i32 n = 0; pos >= 0 && s && s[i]; i++) {
|
||||
n += (s[i] & 192) != 128;
|
||||
if (n == pos + 1) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
bool tim_utf8_is_wide_perhaps(const u8* s, i32 n) {
|
||||
// Character width depends on character, terminal and font. There is no
|
||||
// reliable method, however most frequently used characters are narrow.
|
||||
// Zero with characters are ignored, and hope that user input is benign.
|
||||
if (n < 3 || s[0] < 225) {
|
||||
// u+0000 - u+1000, basic latin - tibetan
|
||||
return false;
|
||||
} else if (s[0] == 226 && s[1] >= 148 && s[1] < 152) {
|
||||
// u+2500 - u+2600 box drawing, block elements, geometric shapes
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TimText tim_scan_str(cstr s) {
|
||||
if(s == NULL)
|
||||
s = "";
|
||||
TimText t = {
|
||||
.width = 0,
|
||||
.lines = (s[0] != 0),
|
||||
};
|
||||
i32 width = 0;
|
||||
for (t.size = 0; s[t.size]; t.size++) {
|
||||
char ch = s[t.size];
|
||||
i32 newline = (ch == '\n');
|
||||
width = newline ? 0 : width;
|
||||
width += (ch & 192) != 128 && (u8)ch > 31;
|
||||
t.lines += newline;
|
||||
t.width = MAX(t.width, width);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
bool tim_next_line(TimLine* l) {
|
||||
if (!l->s || !l->s[0]) {
|
||||
return false;
|
||||
}
|
||||
l->line = l->s;
|
||||
l->size = 0;
|
||||
l->width = 0;
|
||||
for (cstr s = l->s; s[0] && s[0] != '\n'; s++) {
|
||||
l->size += 1;
|
||||
l->width += (s[0] & 192) != 128 && (u8)s[0] > 31;
|
||||
}
|
||||
l->s += l->size + !!l->s[l->size];
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user