Add str_join
This commit is contained in:
@@ -252,6 +252,18 @@ typedef unsigned __int128 U128;
|
||||
#define MemAppend(dst, src, len) mempcpy(dst, src, len)
|
||||
#define MemCompare(first, second, len) memcmp(first, second, len)
|
||||
|
||||
static INLINE U8 *MemFind(U8 *mem, U64 mem_len, U8 *needle, U64 needle_len)
|
||||
{
|
||||
if (needle_len > mem_len) {
|
||||
return NULL;
|
||||
}
|
||||
for (U64 i = 0 ; i + needle_len <= mem_len; i++) {
|
||||
if (MemCompare(&mem[i], needle, needle_len) == 0) {
|
||||
return &mem[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
// atomics
|
||||
#define Atomic(type) _Atomic(type)
|
||||
#define AtomicSub(ptr, val) __atomic_fetch_sub((ptr), (val), __ATOMIC_SEQ_CST)
|
||||
|
||||
+29
@@ -470,7 +470,35 @@ void string_test_misc(void)
|
||||
Str str4_trim = str_ascii_trim(str4);
|
||||
printf("str4_trim: '%.*s'\n", str4_trim.len, str4_trim.str);
|
||||
|
||||
S64 found = str_substr(str1, S("World"));
|
||||
printf("1. found %ld\n", found);
|
||||
found = str_substr(str_empty(), S("World"));
|
||||
printf("2. found %ld\n", found);
|
||||
found = str_substr(str_empty(), S(""));
|
||||
printf("3. found %ld\n", found);
|
||||
found = str_substr(str1, S(" "));
|
||||
printf("4. found %ld\n", found);
|
||||
|
||||
}
|
||||
void string_test_join(void)
|
||||
{
|
||||
TRACEF("\n");
|
||||
Arena arena;
|
||||
arena_init(&arena, &ArenaOptions_Default);
|
||||
Allocator allocator = arena_allocator(&arena);
|
||||
Str strs[3] = {S("1"), S("two"), S("3-3")};
|
||||
StrVec vec = STRVEC_STATIC_INITIALIZER(strs);
|
||||
|
||||
Str str = str_join(&allocator, vec, S("/"));
|
||||
printf("str_join 1 '%.*s'\n", str.len, str.str);
|
||||
str = str_join(&allocator, vec, S(""));
|
||||
printf("str_join 2 '%.*s'\n", str.len, str.str);
|
||||
vec.len = 0;
|
||||
str = str_join(&allocator, vec, S("/"));
|
||||
printf("str_join 2 '%.*s'\n", str.len, str.str);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
arena_test_1();
|
||||
@@ -486,6 +514,7 @@ int main(int argc, char *argv[])
|
||||
string_test_1();
|
||||
string_split_test_1();
|
||||
string_test_misc();
|
||||
string_test_join();
|
||||
|
||||
}
|
||||
|
||||
|
||||
+45
-4
@@ -32,9 +32,7 @@ Str str_concat(Allocator *alloc, Str first, Str second)
|
||||
Str str_push(Allocator *alloc, Str str)
|
||||
{
|
||||
U8 *mem = (U8 *)allocator_push(alloc, str.len, 1);
|
||||
if (!str_is_empty(str)) {
|
||||
MemCopy(mem, str.str, str.len);
|
||||
}
|
||||
MemCopy(mem, str.str, str.len);
|
||||
|
||||
return str_create(mem, str.len);
|
||||
}
|
||||
@@ -80,8 +78,21 @@ Str str_ascii_trim(Str str)
|
||||
return new_str;
|
||||
}
|
||||
|
||||
S64 str_substr(Str haystack, Str to_find)
|
||||
S64 str_substr(Str haystack, Str needle)
|
||||
{
|
||||
if (needle.len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (needle.len == 0) {
|
||||
return str_find_byte(haystack, needle.str[0]);
|
||||
}
|
||||
|
||||
U8 *found = MemFind(haystack.str, haystack.len, needle.str, needle.len);
|
||||
if (found != NULL) {
|
||||
return (S64)(found - haystack.str);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -112,3 +123,33 @@ void str_split(Str str, Str separators, StrVec *vec)
|
||||
vec->len++;
|
||||
}
|
||||
}
|
||||
|
||||
Str str_join(Allocator *allocator, StrVec strings, Str separator)
|
||||
{
|
||||
|
||||
U32 str_len = 0;
|
||||
|
||||
for (U32 i = 0; i < strings.len; i++) {
|
||||
str_len += strings.strings[i].len;
|
||||
}
|
||||
if (strings.len > 0) {
|
||||
str_len += separator.len * (strings.len - 1);
|
||||
}
|
||||
|
||||
U8 *joined_str = allocator_push(allocator, str_len, 1);
|
||||
if (strings.len > 0) {
|
||||
U32 pos = 0;
|
||||
Str *str = &strings.strings[0];
|
||||
MemCopy(&joined_str[pos], str->str, str->len);
|
||||
pos += str->len;
|
||||
for (U32 i = 1; i < strings.len; i++) {
|
||||
str = &strings.strings[i];
|
||||
MemCopy(&joined_str[pos], separator.str, separator.len);
|
||||
pos += separator.len;
|
||||
MemCopy(&joined_str[pos], str->str, str->len);
|
||||
pos += str->len;
|
||||
}
|
||||
}
|
||||
|
||||
return str_create(joined_str, str_len);
|
||||
}
|
||||
|
||||
+7
-4
@@ -9,7 +9,7 @@ struct Str {
|
||||
|
||||
Str str_empty(void);
|
||||
Str str_slice(Str str, U32 start, U32 len);
|
||||
S64 str_substr(Str haystack, Str to_find);
|
||||
S64 str_substr(Str haystack, Str needle);
|
||||
|
||||
Str str_concat(Allocator *alloc, Str first, Str second);
|
||||
Str str_push(Allocator *alloc, Str str);
|
||||
@@ -99,12 +99,15 @@ struct StrVec {
|
||||
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_STATIC_INITIALIZER(strings_) STRVEC_INITIALIZER((strings_), ArraySize(strings_), ArraySize(strings_))
|
||||
#define STRVEC_STATIC_INITIALIZER_EMPTY(strings_) STRVEC_INITIALIZER((strings_), 0, ArraySize(strings_))
|
||||
#define STRVEC_INITIALIZER(strings_, len_, max_len_) {.strings = (strings_), .len = (len_), .max_len = (max_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)
|
||||
StrVec var_name = STRVEC_STATIC_INITIALIZER_EMPTY(var_name##_strvec_array.strings)
|
||||
|
||||
void str_split(Str str, Str separators, StrVec *vec);
|
||||
Str str_join(Allocator *allocator, StrVec strings, Str separator);
|
||||
|
||||
Reference in New Issue
Block a user