Ascii trim

This commit is contained in:
2026-07-27 19:45:00 +02:00
parent 8534075307
commit bd008c51fe
4 changed files with 116 additions and 11 deletions
+1
View File
@@ -250,6 +250,7 @@ typedef unsigned __int128 U128;
#define MemMove(dst, src, len) memmove(dst, src, len)
#define MemCopy(dst, src, len) memcpy(dst, src, len)
#define MemAppend(dst, src, len) mempcpy(dst, src, len)
#define MemCompare(first, second, len) memcmp(first, second, len)
// atomics
#define Atomic(type) _Atomic(type)
+32 -4
View File
@@ -416,7 +416,7 @@ void string_test_1(void)
{
TRACEF("\n");
Str str1 = S_("Hello");
Str str1 = S("Hello");
printf("str1: %.*s len %d\n", str1.len, str1.str, str1.len);
U64 str1_index_of_l = str_find_byte(str1, 'l');
U64 str1_index_of_g = str_find_byte(str1, 'g');
@@ -424,7 +424,7 @@ void string_test_1(void)
MARENA_DEFINE(arena, 512, 1);
Allocator alloc = marena_allocator(&arena);
Str str2 = str_dup(&alloc, S_(" World"));
Str str2 = str_dup(&alloc, S(" World"));
Str str3 = str_concat(&alloc, str1, str2);
printf("str3: %.*s len %d\n", str3.len, str3.str, str3.len);
}
@@ -433,8 +433,8 @@ void string_split_test_1(void)
{
TRACEF("\n");
Str str1 = S_("a:bb|ccc");
Str sep = S_("|:");
Str str1 = S("a:bb|ccc");
Str sep = S("|:");
STRVEC_DEFINE(strings, 16);
str_split(str1, sep, &strings);
@@ -443,7 +443,34 @@ void string_split_test_1(void)
printf("split %u: '%.*s'\n", i, str->len, str->str);
}
}
void string_test_misc(void)
{
TRACEF("\n");
Str str1 = S("Hello World");
bool prefix1 = str_starts_with(str1, S("He"));
bool prefix2 = str_starts_with(str1, S(""));
bool prefix3 = str_starts_with(str1, S("false"));
bool suffix1 = str_ends_with(str1, S("orld"));
bool suffix2 = str_ends_with(str1, S(""));
bool suffix3 = str_ends_with(str1, S("false"));
printf("matches: %d %d %d %d %d %d\n", prefix1, prefix2, prefix3, suffix1, suffix2, suffix3);
Str str2 = S(" Hello World\t \n");
Str str2_trim = str_ascii_trim(str2);
printf("str2_trim: '%.*s'\n", str2_trim.len, str2_trim.str);
printf("str2_trim == str1: %d\n", str_eq(str1, str2_trim));
Str str3 = str_empty();
Str str3_trim = str_ascii_trim(str3);
printf("str3_trim: '%.*s'\n", str3_trim.len, str3_trim.str);
Str str4 = S(" \t\t ");
Str str4_trim = str_ascii_trim(str4);
printf("str4_trim: '%.*s'\n", str4_trim.len, str4_trim.str);
}
int main(int argc, char *argv[])
{
arena_test_1();
@@ -458,6 +485,7 @@ int main(int argc, char *argv[])
apool_test_miniarena();
string_test_1();
string_split_test_1();
string_test_misc();
}
+48 -4
View File
@@ -7,7 +7,7 @@ Str str_empty(void)
return str;
}
Str str_substr(Str str, U32 start, U32 len)
Str str_slice(Str str, U32 start, U32 len)
{
Assert(start < str.len);
Assert(len <= str.len);
@@ -16,7 +16,6 @@ Str str_substr(Str str, U32 start, U32 len)
return new_str;
}
Str str_concat(Allocator *alloc, Str first, Str second)
{
Str str;
@@ -43,6 +42,51 @@ Str str_push(Allocator *alloc, Str str)
return *new_str;
}
static INLINE bool char_is_ascii_whitespace(U8 byte)
{
return byte == ' ' || byte == '\t' || byte == '\v' || byte == '\f' || byte == '\r' || byte == '\n';
}
Str str_ascii_trim_left(Str str)
{
U8 *start = str.str;
U8 *end = str.str + str.len;
while (start != end) {
if (!char_is_ascii_whitespace(*start)) {
break;
}
start++;
}
return str_create(start, (U32)(end - start));
}
Str str_ascii_trim_right(Str str)
{
U8 *start = str.str;
U8 *end = str.str + str.len;
while (start != end) {
if (!char_is_ascii_whitespace(*(end - 1))) {
break;
}
end--;
}
return str_create(start, (U32)(end - start));
}
Str str_ascii_trim(Str str)
{
Str new_str = str_ascii_trim_left(str);
new_str = str_ascii_trim_right(new_str);
return new_str;
}
S64 str_substr(Str haystack, Str to_find)
{
}
// split @str on any byte in @separators, place split strings in @vec
void str_split(Str str, Str separators, StrVec *vec)
{
@@ -58,14 +102,14 @@ void str_split(Str str, Str separators, StrVec *vec)
break;
}
Str sub_str = str_substr(str, start_pos, i - start_pos);
Str sub_str = str_slice(str, start_pos, i - start_pos);
vec->strings[vec->len] = sub_str;
vec->len++;
start_pos = i + 1;
}
}
if (start_pos < str.len && vec->len < vec->max_len) {
Str sub_str = str_substr(str, start_pos, str.len - start_pos);
Str sub_str = str_slice(str, start_pos, str.len - start_pos);
vec->strings[vec->len] = sub_str;
vec->len++;
}
+35 -3
View File
@@ -8,15 +8,29 @@ struct Str {
};
Str str_empty(void);
Str str_substr(Str str, U32 start, U32 len);
Str str_slice(Str str, U32 start, U32 len);
S64 str_substr(Str haystack, Str to_find);
Str str_concat(Allocator *alloc, Str first, Str second);
Str str_push(Allocator *alloc, Str str);
Str str_ascii_trim(Str str);
Str str_ascii_trim_left(Str str);
Str str_ascii_trim_right(Str str);
#define str_from_lit(str) str_create(((U8 *)str), sizeof(str) -1)
#define S_(str) str_from_lit(str)
#define S(str) str_from_lit(str)
#define cstr_len(str) (U32)strlen(str)
#define str_dup(alloc, str) str_push((alloc), (str))
static INLINE bool str_eq(Str first, Str second)
{
if (first.len != second.len) {
return false;
}
return MemCompare(first.str, second.str, first.len) == 0;
}
static INLINE bool str_is_empty(Str str)
{
return str.len == 0;
@@ -51,10 +65,28 @@ static INLINE S64 str_find_byte(Str str, U8 byte)
return -1;
}
static INLINE bool str_starts_with(Str str, Str prefix)
{
if (prefix.len > str.len) {
return false;
}
return MemCompare(str.str, prefix.str, prefix.len) == 0;
}
static INLINE bool str_ends_with(Str str, Str suffix)
{
if (suffix.len > str.len) {
return false;
}
U32 start = str.len - suffix.len;
return MemCompare(&str.str[start], suffix.str, suffix.len) == 0;
}
static INLINE Str str_skip(Str str, U32 len)
{
U32 skip_len = Min(str.len, len);
Str new_str = str_substr(str, skip_len, str.len - skip_len);
Str new_str = str_slice(str, skip_len, str.len - skip_len);
return new_str;
}