More string stuff

This commit is contained in:
2026-07-26 22:55:29 +02:00
parent 207d141ddf
commit 8534075307
3 changed files with 185 additions and 0 deletions
+35
View File
@@ -3,6 +3,7 @@
#include "mini_arena.h" #include "mini_arena.h"
#include "platform.h" #include "platform.h"
#include "pool.h" #include "pool.h"
#include "string.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -411,6 +412,38 @@ void apool_test_autogrow(void)
} }
void string_test_1(void)
{
TRACEF("\n");
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');
printf("str1: index of l %ld, index of g: %ld\n", str1_index_of_l, str1_index_of_g);
MARENA_DEFINE(arena, 512, 1);
Allocator alloc = marena_allocator(&arena);
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);
}
void string_split_test_1(void)
{
TRACEF("\n");
Str str1 = S_("a:bb|ccc");
Str sep = S_("|:");
STRVEC_DEFINE(strings, 16);
str_split(str1, sep, &strings);
for (U32 i = 0; i < strings.len; i++) {
Str *str = &strings.strings[i];
printf("split %u: '%.*s'\n", i, str->len, str->str);
}
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
arena_test_1(); arena_test_1();
@@ -423,6 +456,8 @@ int main(int argc, char *argv[])
apool_test(); apool_test();
apool_test_autogrow(); apool_test_autogrow();
apool_test_miniarena(); apool_test_miniarena();
string_test_1();
string_split_test_1();
} }
+72
View File
@@ -0,0 +1,72 @@
#include "string.h"
Str str_empty(void)
{
static const U8 empty_;
static const Str str = {(U8 *)&empty_, 0};
return str;
}
Str str_substr(Str str, U32 start, U32 len)
{
Assert(start < str.len);
Assert(len <= str.len);
Str new_str = str_create(&str.str[start], len);
return new_str;
}
Str str_concat(Allocator *alloc, Str first, Str second)
{
Str str;
str.len = first.len + second.len;
str.str = allocator_push(alloc, str.len, 1);;
MemCopy(str.str, first.str, first.len);
MemCopy(&str.str[first.len], second.str, second.len);
return str;
}
Str str_push(Allocator *alloc, Str str)
{
U8 *mem = (U8 *)allocator_push(alloc, sizeof(Str) + str.len, alignof(Str));
Str *new_str = (Str *)mem;
new_str->len = str.len;
new_str->str = &mem[sizeof(Str)];
if (!str_is_empty(str)) {
MemCopy(new_str->str, str.str, str.len);
}
return *new_str;
}
// split @str on any byte in @separators, place split strings in @vec
void str_split(Str str, Str separators, StrVec *vec)
{
if (vec->max_len == 0 || str.len == 0) {
return;
}
U32 start_pos = 0;
for (U32 i = 0; i < str.len; i++) {
U8 byte = str.str[i];
if (str_find_byte(separators, byte) != -1) {
if (vec->len >= vec->max_len) {
break;
}
Str sub_str = str_substr(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);
vec->strings[vec->len] = sub_str;
vec->len++;
}
}
+78
View File
@@ -0,0 +1,78 @@
#pragma once
#include "base_core.h"
typedef struct Str Str;
struct Str {
U8 *str;
U32 len;
};
Str str_empty(void);
Str str_substr(Str str, U32 start, U32 len);
Str str_concat(Allocator *alloc, Str first, Str second);
Str str_push(Allocator *alloc, Str str);
#define str_from_lit(str) str_create(((U8 *)str), sizeof(str) -1)
#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_is_empty(Str str)
{
return str.len == 0;
}
static INLINE Str str_create(U8 *start, U32 len)
{
Str str = {start, len};
return str;
}
static INLINE Str str_from_cstr(const char *cstr)
{
Str str = str_create((U8 *)cstr, cstr_len(cstr));
return str;
}
static INLINE Str str_push_cstr(Allocator *alloc, const char *cstr)
{
Str str = str_from_cstr(cstr);
return str_push(alloc, str);
}
static INLINE S64 str_find_byte(Str str, U8 byte)
{
for (U32 i = 0; i < str.len; i++) {
if (str.str[i] == byte) {
return i;
}
}
return -1;
}
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);
return new_str;
}
// String Vector
typedef struct StrVec StrVec;
struct StrVec {
Str *strings;
U32 len;
U32 max_len;
};
#define STRVEC_STATIC_INITIALIZER(strings_) STRVEC_INITIALIZER((strings_), ArraySize(strings_))
#define STRVEC_INITIALIZER(strings_, len_) {.strings = (strings_), .len = 0, .max_len = (len_)}
#define STRVEC_DEFINE(var_name, len_) \
struct { \
Str strings[len_];\
} var_name##_strvec_array; \
StrVec var_name = STRVEC_STATIC_INITIALIZER(var_name##_strvec_array.strings)
void str_split(Str str, Str separators, StrVec *vec);