summaryrefslogtreecommitdiff
path: root/source/base/base_string.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/base/base_string.h')
-rw-r--r--source/base/base_string.h240
1 files changed, 240 insertions, 0 deletions
diff --git a/source/base/base_string.h b/source/base/base_string.h
new file mode 100644
index 0000000..4fdd4d5
--- /dev/null
+++ b/source/base/base_string.h
@@ -0,0 +1,240 @@
1#ifndef BASE_STRING_H
2#define BASE_STRING_H
3
4//- cstring
5
6typedef char *cstring;
7
8// - str8
9typedef struct String8 String8;
10typedef struct String16 String16;
11typedef struct String32 String32;
12
13typedef struct String8Node String8Node;
14typedef struct String16Node String16Node;
15typedef struct String32Node String32Node;
16
17typedef struct String8List String8List;
18typedef struct String16List String16List;
19typedef struct String32List String32List;
20
21//- strings
22
23struct String8 {
24 u8 *data;
25 u64 size;
26};
27
28struct String16 {
29 u16 *data;
30 u64 size;
31};
32
33struct String32 {
34 u32 *data;
35 u64 size;
36};
37
38//- nodes
39struct String8Node {
40 String8Node *next;
41 String8 value;
42};
43
44struct String16Node {
45 String16Node *next;
46 String16 string;
47};
48
49struct String32Node {
50 String32Node *next;
51 String32 value;
52};
53
54//- lists
55struct String8List {
56 String8Node *first;
57 String8Node *last;
58 u64 count;
59};
60
61struct String16List {
62 String16Node *first;
63 String16Node *last;
64 u64 count;
65};
66
67struct String32List {
68 String32Node *first;
69 String32Node *last;
70 u64 count;
71};
72
73//- nil / zero-value checks and constructors
74internal b32 is_nil_str8(String8 *a);
75internal b32 is_nil_str8_node(String8Node *a);
76internal b32 is_nil_str16(String16 *a);
77internal b32 is_nil_str16_node(String16Node *a);
78internal b32 is_nil_str32(String32 *a);
79internal b32 is_nil_str32_node(String32Node *a);
80internal String8 str8_zero();
81
82//- str8 copy / clone / append
83internal String8 str8_clone(MemArena *arena, String8 *src);
84internal void str8_copy(String8 *dest, String8 *src);
85internal b32 str8_append(String8 *dest, String8 src);
86internal b32 str8_append_char(String8 *dest, u8 src);
87internal b32 str8_insert(MemArena *arena, String8 *dest, String8 *src, u64 pos);
88
89//- str8 trim / chop
90internal void str8_trim_left(String8 *buffer);
91internal void str8_trim_right(String8 *buffer);
92internal String8 str8_chop_left(String8 buffer, u64 count);
93internal String8 str8_chop_right(String8 buffer, u64 count);
94internal b32 str8_chop_left_ptr(String8 *buffer, u64 count);
95internal b32 str8_chop_right_ptr(String8 *buffer, u64 count);
96
97//- str8 substrings, matching, search
98internal String8 str8_create_substr(String8 *buffer, u64 left_offset, u64 right_offset);
99internal b32 str8_is_match(String8 a, String8 b);
100internal b32 str8_find(String8 *buffer, u64 start_pos, String8 element, u64 *out);
101internal b32 str8_is_digit(String8 a, u64 start_pos);
102internal b32 str8_is_empty(String8 *buffer);
103
104//- str8 list
105internal void str8_list_push_node(String8List *list, String8Node *node);
106
107//- str16 / str32 chop and substrings
108internal String16 str16_chop_left(String16 buffer, u64 count);
109internal String16 str16_chop_right(String16 buffer, u64 count);
110internal String16 str16_create_substr(String16 *buffer, u64 left_offset, u64 right_offset);
111internal String32 str32_chop_left(String32 buffer, u64 count);
112internal String32 str32_chop_right(String32 buffer, u64 count);
113internal String32 str32_create_substr(String32 *buffer, u64 left_offset, u64 right_offset);
114
115//- null-termination helpers
116internal cstring null_terminate(MemArena *arena, String8 *c);
117internal String8 remove_null_terminator(MemArena *arena, String8 c);
118
119//- convert
120
121internal cstring str8_to_cstring(String8 *buffer);
122
123//- cstring character classification
124internal b32 cstring_is_digit(u8 point);
125internal b32 cstring_is_alpha(u8 point);
126internal b32 cstring_is_alpha_num(u8 point);
127internal b32 cstring_is_whitespace(u8 point);
128internal b32 cstring_is_slash(u8 point);
129internal b32 cstring_is_newline(u8 point);
130
131#define CstringIsMatch(a, b) cstring_is_match((u8 *)(a), (u8 *)(b))
132#define CstringAnyMatch(a, b) cstring_any_match((u8 *)(a), (u8 *)(b))
133
134
135//- cstring matching, length, search
136internal b32 cstring_is_match(u8 *a, u8 *b);
137internal b32 cstring_any_match(u8 *a, u8 *b);
138internal u64 cstring8_length(u8 *c);
139internal u64 cstring16_length(u16 *c);
140internal u64 cstring32_length(u32 *c);
141internal u64 cstring8_find(u8 *buffer, u8 *element);
142internal u64 cstring8_find_new_line(u8 *buffer);
143internal u64 cstring8_find_needle(u8 *buffer, u8 needle);
144
145//-
146
147#if COMPILER_GCC
148#pragma GCC diagnostic push
149#pragma GCC diagnostic ignored "-Wconversion"
150#endif
151
152//-
153ReadOnly global_variable String8 nil_str8 = {NULL, 0};
154ReadOnly global_variable String16 nil_str16 = {NULL, 0};
155ReadOnly global_variable String32 nil_str32 = {NULL, 0};
156
157ReadOnly global_variable String8Node nil_str8_node = {NULL, {}};
158ReadOnly global_variable String16Node nil_str16_node = {NULL, {}};
159ReadOnly global_variable String32Node nil_str32_node = {NULL, {}};
160ReadOnly global_variable String8List nil_str8_list = {NULL, {}};
161ReadOnly global_variable String16List nil_str16_list = {NULL, {}};
162ReadOnly global_variable String32List nil_str32_list = {NULL, {}};
163
164//- macros
165#define PushString8(arena, count) {(u8 *)(PushArrayZero(arena, u8, (count))), (u64)(count)}
166#define PushString16(arena, count) {(u16 *)(PushArrayZero(arena, u16, (count))), (u64)(count)}
167#define PushString32(arena, count) {(u32 *)(PushArrayZero(arena, u32, (count))), (u64)(count)}
168
169// TODO: is this null terminated? this is generally a concept i struggle with. when is the string
170// null terminated and when not. because in thi case I am the one passing a string "/" or something
171// like that. is that null terminated or not?
172#define ToString8(data) \
173 String8 { (u8 *)(data), (u64)(cstring8_length((u8 *)data)) }
174#define ToString16(data) \
175 String16 { (u16 *)(data), (u64)(cstring16_length((u16 *)data)) }
176#define ToString32(data) \
177 String32 { (u32 *)(data), (u64)(cstring32_length((u32 *)data)) }
178
179#define str8(buffer) ToString8(buffer)
180#define str16(buffer) ToString16(buffer)
181#define str32(buffer) ToString32(buffer)
182
183#define ToString8Size(data, size) \
184 String8 { (u8 *)(data), (u64)(size) }
185#define ToString16Size(data, size) \
186 String16 { (u16 *)(data), (u64)(size) }
187#define ToString32Size(data, size) \
188 String32 { (u32 *)(data), (u64)(size) }
189
190#define ToString8Node(string) \
191 String8Node { &nil_str8_node, string }
192#define ToString16Node(string) \
193 String16Node { &nil_str8_node, string }
194#define ToString32Node(string) \
195 String32Node { &nil_str8_node, string }
196
197#define str8_node(text) ToString8Node(str8(text))
198#define str16_node(text) ToString16Node(str16(text))
199#define str32_node(text) ToString32Node(str32(text))
200
201#define LOOP(expr, exec) for (; expr; exec)
202
203// arbitratry amount of parameters can be passed to this function
204// TODO: put the index name as a paramter so that the reference can be made later without it being
205// so hidden
206
207#define FOR_STR8_CHOP_LEFT(index, buffer, count) FOR_STR8_CHOP(index, buffer, count, str8_chop_left)
208
209#define FOR_STR8_CHOP_RIGHT(index, buffer, count) \
210 FOR_STR8_CHOP(index, buffer, count, str8_chop_right)
211
212// NOTE: we face an issue with returning an rvalue. to solve this we should only use the pointer
213// functions that we create (str8_chop_left_ptr and str8_chop_right_ptr)
214#define FOR_STR8_CHOP(index, buffer, count, function) \
215 for (u64 index = 0; (index < (buffer.size)) && ((buffer.size) > (count)); \
216 function((buffer), (count)), ++index)
217
218#define FOR_STR8_ARB_FN(expr, function, ...) LOOP(expr, function(__VA_ARGS__))
219
220#define FOR_STR8_MATCH(buffa, buffb) LOOP(str8_is_match(buffa, buffb), str8_chop_left(buffa, 1))
221
222#define FOR_STR8_NODE(str8_list, current) \
223 for (String8Node *current = str8_list->first; !is_nil_str8_node(current); \
224 current = current->next)
225
226internal b32 is_nil_str8(String8 *a);
227internal b32 is_nil_str8_node(String8Node *a);
228internal b32 is_nil_str16(String16 *a);
229internal b32 is_nil_str16_node(String16Node *a);
230internal b32 is_nil_str32(String32 *a);
231internal b32 is_nil_str32_node(String32Node *a);
232
233#if COMPILER_GCC
234#pragma GCC diagnostic pop
235#endif
236
237#define Str8Fmt "%.*s"
238#define Str8Arg(buffer) (unsigned int)((buffer).size), (char *)((buffer).data)
239
240#endif /* BASE_STRING_H */