demake 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/demake +296 -26
- data/lib/apps/example/demake/auto_bits.rb +59 -0
- data/lib/apps/example/demake/auto_list.rb +60 -0
- data/lib/apps/example/src/Makefile +6 -0
- data/lib/apps/oreo/oreo_test.txt +0 -0
- data/lib/apps/oreo/src/Makefile +6 -0
- data/lib/data/libsrc/auto_bits.c +41 -0
- data/lib/data/libsrc/auto_bits.h +212 -4
- data/lib/data/libsrc/auto_bits.rb +9 -0
- data/lib/data/libsrc/auto_list.rb +9 -0
- data/lib/data/libsrc/auto_string.c +300 -0
- data/lib/data/libsrc/auto_string.h +1023 -0
- data/lib/data/libsrc/auto_string_clamp_test.c +52 -0
- data/lib/data/libsrc/defines.h +29 -3
- data/lib/data/libsrc/memory_arena.c +32 -0
- data/lib/data/libsrc/memory_arena.h +345 -0
- data/lib/data/libsrc/memory_arena_test.c +173 -0
- data/lib/data/libsrc/simple_linked_list.c +42 -22
- data/lib/data/libsrc/simple_linked_list.h +140 -56
- data/lib/data/libsrc/typedefs.h +5 -3
- data/lib/to_plural.rb +126 -0
- metadata +47 -15
- data/lib/data/libsrc/simple_linked_list +0 -0
- data/lib/data/libsrc/smart_alloc.h +0 -45
|
@@ -0,0 +1,1023 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
auto_string.h -- *Full Library* Header File
|
|
4
|
+
|
|
5
|
+
Used to create string based areas / regions of memory and views
|
|
6
|
+
|
|
7
|
+
- Uses basic 32-bit integers as identifiers for lifetimes / arenas
|
|
8
|
+
- Automatically expands when new allocations don't fit existing
|
|
9
|
+
- Automatically zeros data blocks upon reset / free
|
|
10
|
+
|
|
11
|
+
See the end of this file for an example.
|
|
12
|
+
|
|
13
|
+
Public Functions:
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#ifndef AUTO_STRING_H_Minaswan /* Prevent multiple inclusions */
|
|
19
|
+
#define AUTO_STRING_H_Minaswan
|
|
20
|
+
#define AUTO_STRING_VERSION "0.1.0"
|
|
21
|
+
#ifndef TYPEDEFS_H_Minaswan /* Prevents multiple inclusions */
|
|
22
|
+
#define TYPEDEFS_H_Minaswan
|
|
23
|
+
#define TYPEDEFS_VERSION "0.1.1"
|
|
24
|
+
#include <stdint.h>
|
|
25
|
+
|
|
26
|
+
typedef uint8_t b8; /* Booleans */
|
|
27
|
+
typedef uint16_t b16;
|
|
28
|
+
typedef uint32_t b32;
|
|
29
|
+
typedef uint64_t b64;
|
|
30
|
+
|
|
31
|
+
typedef char c8; /* Characters */
|
|
32
|
+
typedef const char cc8;
|
|
33
|
+
typedef unsigned char uc8;
|
|
34
|
+
typedef char as8; /* Auto string */
|
|
35
|
+
|
|
36
|
+
typedef uint8_t u8; /* Unsigned Numbers */
|
|
37
|
+
typedef uint16_t u16;
|
|
38
|
+
typedef uint32_t u32;
|
|
39
|
+
typedef uint64_t u64;
|
|
40
|
+
|
|
41
|
+
typedef int8_t i8; /* Signed Numbers */
|
|
42
|
+
typedef int16_t i16;
|
|
43
|
+
typedef int32_t i32;
|
|
44
|
+
typedef int64_t i64;
|
|
45
|
+
|
|
46
|
+
typedef float f32; /* Floating Point Numbers */
|
|
47
|
+
typedef double f64;
|
|
48
|
+
#endif /* TYPEDEFS_H_Minaswan */
|
|
49
|
+
|
|
50
|
+
#ifndef DEFINES_H_Minaswan /* Prevents multiple inclusions */
|
|
51
|
+
#define DEFINES_H_Minaswan
|
|
52
|
+
#define DEFINES_VERSION "0.1.1"
|
|
53
|
+
#ifndef NULL
|
|
54
|
+
#define NULL ((void *) 0)
|
|
55
|
+
#endif
|
|
56
|
+
#ifndef FALSE
|
|
57
|
+
#define FALSE 0
|
|
58
|
+
#endif
|
|
59
|
+
#ifndef TRUE
|
|
60
|
+
#define TRUE 1
|
|
61
|
+
#endif
|
|
62
|
+
#ifndef NO
|
|
63
|
+
#define NO 0
|
|
64
|
+
#endif
|
|
65
|
+
#ifndef YES
|
|
66
|
+
#define YES 1
|
|
67
|
+
#endif
|
|
68
|
+
#ifndef OFF
|
|
69
|
+
#define OFF 0
|
|
70
|
+
#endif
|
|
71
|
+
#ifndef ON
|
|
72
|
+
#define ON 1
|
|
73
|
+
#endif
|
|
74
|
+
#ifndef MIN
|
|
75
|
+
#define MIN(x, y) (x) < (y) ? (x) : (y)
|
|
76
|
+
#endif
|
|
77
|
+
#ifndef MAX
|
|
78
|
+
#define MAX(x, y) (x) > (y) ? (x) : (y)
|
|
79
|
+
#endif
|
|
80
|
+
#ifndef KB
|
|
81
|
+
#define KB(x) ((u64)(x) * 1024)
|
|
82
|
+
#endif
|
|
83
|
+
#ifndef MB
|
|
84
|
+
#define MB(x) ((u64)(x) * 1024 * 1024)
|
|
85
|
+
#endif
|
|
86
|
+
#ifndef GB
|
|
87
|
+
#define GB(x) ((u64)(x) * 1024 * 1024 * 1024)
|
|
88
|
+
#endif
|
|
89
|
+
#ifndef TO_UPPER_CASE
|
|
90
|
+
#define TO_UPPER_CASE(x) (((uc8)(x) >= (uc8)'a' && (uc8)(x) <= (uc8)'z') ? \
|
|
91
|
+
(uc8)((uc8)(x) - (uc8)'a' + (uc8)'A') : (uc8)(x))
|
|
92
|
+
#endif
|
|
93
|
+
#ifndef TO_LOWER_CASE
|
|
94
|
+
#define TO_LOWER_CASE(x) (((uc8)(x) >= (uc8)'A' && (uc8)(x) <= (uc8)'Z') ? \
|
|
95
|
+
(uc8)((uc8)(x) - (uc8)'A' + (uc8)'a') : (uc8)(x))
|
|
96
|
+
#endif
|
|
97
|
+
#ifndef IS_WHITE_SPACE
|
|
98
|
+
#define IS_WHITE_SPACE(x) ((uc8)(x) == ' ' || (uc8)(x) - (uc8)'\t' < 5)
|
|
99
|
+
#endif
|
|
100
|
+
#endif /* DEFINES_H_Minaswan */
|
|
101
|
+
|
|
102
|
+
#include <stdio.h>
|
|
103
|
+
#include <stdlib.h>
|
|
104
|
+
#include <string.h>
|
|
105
|
+
|
|
106
|
+
#ifndef _SCOPE_ /* _SCOPE_ is short and can be easily redefined */
|
|
107
|
+
#define _SCOPE_WAS_NOT_PREDEFINED_
|
|
108
|
+
/*
|
|
109
|
+
#define _SCOPE_ extern
|
|
110
|
+
#define _SCOPE_ static
|
|
111
|
+
*/
|
|
112
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
113
|
+
#define _SCOPE_ static __inline__
|
|
114
|
+
#elif defined(_MSC_VER)
|
|
115
|
+
#define _SCOPE_ static __inline
|
|
116
|
+
#else
|
|
117
|
+
#define _SCOPE_ static inline
|
|
118
|
+
#endif
|
|
119
|
+
#endif
|
|
120
|
+
|
|
121
|
+
#define NO_AUTO_STRING 0
|
|
122
|
+
|
|
123
|
+
struct auto_view_data {
|
|
124
|
+
u64 length;
|
|
125
|
+
c8 *data;
|
|
126
|
+
c8 clamp;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/* These all use the global i32 auto_string_arena variable */
|
|
130
|
+
_SCOPE_ as8 *auto_string_new(cc8 *string, b8 thin);
|
|
131
|
+
_SCOPE_ as8 *auto_string_extra(cc8 *string, i64 extra_capacity);
|
|
132
|
+
_SCOPE_ as8 *auto_string_substring(cc8 *string, u64 position, u64 length, b8 thin);
|
|
133
|
+
_SCOPE_ void auto_string_free(void);
|
|
134
|
+
_SCOPE_ void auto_string_reset(void);
|
|
135
|
+
|
|
136
|
+
/* Public Functions */
|
|
137
|
+
_SCOPE_ b8 is_auto_string(cc8 *string);
|
|
138
|
+
_SCOPE_ b8 auto_string_contains(cc8 *string, cc8 *sub_string);
|
|
139
|
+
_SCOPE_ b8 auto_string_match(cc8 *string, cc8 *string2);
|
|
140
|
+
_SCOPE_ b8 auto_string_match_no_case(cc8 *string, cc8 *string2);
|
|
141
|
+
_SCOPE_ b8 auto_string_prefixed(cc8 *string, cc8 *prefix);
|
|
142
|
+
_SCOPE_ b8 auto_string_prefixed_no_case(cc8 *string, cc8 *prefix);
|
|
143
|
+
_SCOPE_ b8 auto_view_match(struct auto_view_data *view, cc8 *string);
|
|
144
|
+
_SCOPE_ b8 auto_view_match_no_case(struct auto_view_data *view, cc8 *string);
|
|
145
|
+
_SCOPE_ b8 auto_views_match(struct auto_view_data *view,
|
|
146
|
+
struct auto_view_data *view2);
|
|
147
|
+
_SCOPE_ b8 auto_views_match_no_case(struct auto_view_data *view,
|
|
148
|
+
struct auto_view_data *view2);
|
|
149
|
+
_SCOPE_ as8 *auto_string_by_id_new(i32 identifier, cc8 *string, b8 thin);
|
|
150
|
+
_SCOPE_ as8 *auto_string_by_id_extra(i32 identifier, cc8 *string, i64 extra_capacity);
|
|
151
|
+
_SCOPE_ as8 *auto_string_by_id_substring(i32 identifier, cc8 *string, u64 position, u64 length, b8 thin);
|
|
152
|
+
_SCOPE_ as8 *auto_string_add(c8 *string, cc8 *add_string);
|
|
153
|
+
_SCOPE_ u32 auto_string_init(i64 capacity);
|
|
154
|
+
_SCOPE_ i32 find_auto_string_identifier(cc8 *string);
|
|
155
|
+
_SCOPE_ i32 find_next_auto_string_identifier(void);
|
|
156
|
+
_SCOPE_ u64 find_string_length(cc8 *string);
|
|
157
|
+
_SCOPE_ u64 auto_string_length(cc8 *string);
|
|
158
|
+
_SCOPE_ u64 auto_string_available(cc8 *string);
|
|
159
|
+
_SCOPE_ struct auto_view_data auto_view(cc8 *string);
|
|
160
|
+
_SCOPE_ c8 *auto_view_clamp(struct auto_view_data *view);
|
|
161
|
+
_SCOPE_ c8 *auto_view_unclamp(struct auto_view_data *view);
|
|
162
|
+
_SCOPE_ void auto_view_slice(struct auto_view_data *view, u64 start, u64 end);
|
|
163
|
+
_SCOPE_ void auto_view_chop_left(struct auto_view_data *view, u64 length);
|
|
164
|
+
_SCOPE_ void auto_view_chop_right(struct auto_view_data *view, u64 length);
|
|
165
|
+
_SCOPE_ void auto_view_trim_left(struct auto_view_data *view);
|
|
166
|
+
_SCOPE_ void auto_view_trim_right(struct auto_view_data *view);
|
|
167
|
+
_SCOPE_ void auto_view_trim(struct auto_view_data *view);
|
|
168
|
+
_SCOPE_ void auto_view_print(struct auto_view_data *view);
|
|
169
|
+
_SCOPE_ void auto_string_update(as8 *string);
|
|
170
|
+
_SCOPE_ void auto_string_by_id_reset(u32 identifier);
|
|
171
|
+
_SCOPE_ void auto_string_reset_all(void);
|
|
172
|
+
_SCOPE_ void auto_string_by_id_free(u32 identifier);
|
|
173
|
+
_SCOPE_ void auto_string_free_all(void);
|
|
174
|
+
_SCOPE_ void auto_string_show(void);
|
|
175
|
+
|
|
176
|
+
#ifdef AUTO_STRING_IMPLEMENTATION /* Effectively auto_string.c */
|
|
177
|
+
#ifndef DEFAULT_AUTO_STRING_CAPACITY
|
|
178
|
+
#define DEFAULT_AUTO_STRING_CAPACITY 512
|
|
179
|
+
#endif
|
|
180
|
+
|
|
181
|
+
#ifndef AUTO_VIEW
|
|
182
|
+
#define AUTO_VIEW(view) (u32)(view).length, (view).data
|
|
183
|
+
#endif
|
|
184
|
+
#ifndef AUTO_PVIEW
|
|
185
|
+
#define AUTO_PVIEW(view) (u32)(view)->length, (view)->data
|
|
186
|
+
#endif
|
|
187
|
+
|
|
188
|
+
struct auto_string_data {
|
|
189
|
+
struct auto_string_data *next;
|
|
190
|
+
u64 capacity;
|
|
191
|
+
u64 position;
|
|
192
|
+
u32 identifier;
|
|
193
|
+
c8 guard[4];
|
|
194
|
+
c8 *data;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
#ifndef NO_AUTO_STRING_HELPERS
|
|
198
|
+
/* -- auto_view -- shortcuts -- */
|
|
199
|
+
#define as_contains auto_string_contains
|
|
200
|
+
#define as_match auto_string_match
|
|
201
|
+
#define as_match_no_case auto_string_match_no_case
|
|
202
|
+
#define as_equal auto_string_match
|
|
203
|
+
#define as_equal_no_case auto_string_match_no_case
|
|
204
|
+
#define as_prefixed auto_string_prefixed
|
|
205
|
+
#define as_prefixed_no_case auto_string_prefixed_no_case
|
|
206
|
+
#define as_starts_with auto_string_prefixed
|
|
207
|
+
#define as_starts_with_no_case auto_string_prefixed_no_case
|
|
208
|
+
#define as_new auto_string_new
|
|
209
|
+
#define as_add auto_string_add
|
|
210
|
+
#define as_extra auto_string_extra
|
|
211
|
+
#define as_by_id_new auto_string_by_id_new
|
|
212
|
+
#define as_by_id_extra auto_string_by_id_extra
|
|
213
|
+
#define as_by_id_substring auto_string_by_id_substring
|
|
214
|
+
#define as_substring auto_string_substring
|
|
215
|
+
#define as_init auto_string_init
|
|
216
|
+
#define as_length auto_string_length
|
|
217
|
+
#define as_available auto_string_available
|
|
218
|
+
#define as_update auto_string_update
|
|
219
|
+
#define as_reset auto_string_reset
|
|
220
|
+
#define as_reset_all auto_string_reset_all
|
|
221
|
+
#define as_free auto_string_free
|
|
222
|
+
#define as_free_all auto_string_free_all
|
|
223
|
+
#define as_show auto_string_show
|
|
224
|
+
#define find_as_id find_auto_string_identifier
|
|
225
|
+
#define find_next_as_id find_next_auto_string_identifier
|
|
226
|
+
|
|
227
|
+
typedef struct auto_string_data AutoString;
|
|
228
|
+
|
|
229
|
+
/* -- auto_view -- shortcuts -- */
|
|
230
|
+
#define VIEW "%.*s"
|
|
231
|
+
#define VIEW_WIDTH(x) "%"#x".*s"
|
|
232
|
+
#define A_VIEW(view) AUTO_VIEW(view)
|
|
233
|
+
#define A_PVIEW(view) AUTO_PVIEW(view)
|
|
234
|
+
|
|
235
|
+
#define a_view auto_view
|
|
236
|
+
#define av_match auto_view_match
|
|
237
|
+
#define av_match_no_case auto_view_match_no_case
|
|
238
|
+
#define av_chop_left auto_view_chop_left
|
|
239
|
+
#define av_chop_right auto_view_chop_right
|
|
240
|
+
#define av_trim_left auto_view_trim_left
|
|
241
|
+
#define av_trim_right auto_view_trim_right
|
|
242
|
+
#define av_trim auto_view_trim
|
|
243
|
+
#define av_slice auto_view_slice
|
|
244
|
+
#define av_print auto_view_print
|
|
245
|
+
#define avs_match auto_views_match
|
|
246
|
+
#define avs_match_no_case auto_views_match_no_case
|
|
247
|
+
|
|
248
|
+
typedef struct auto_view_data AutoView;
|
|
249
|
+
#endif
|
|
250
|
+
|
|
251
|
+
i32 auto_string_arena = 0;
|
|
252
|
+
struct auto_string_data *auto_string_list = NULL;
|
|
253
|
+
|
|
254
|
+
_SCOPE_ u32 auto_string_init(i64 capacity)
|
|
255
|
+
{
|
|
256
|
+
struct auto_string_data *as = NULL, *next = NULL;
|
|
257
|
+
|
|
258
|
+
if(capacity == 0)
|
|
259
|
+
capacity = DEFAULT_AUTO_STRING_CAPACITY;
|
|
260
|
+
else if(capacity < 0) /* Negative is multiples of default */
|
|
261
|
+
capacity *= -DEFAULT_AUTO_STRING_CAPACITY;
|
|
262
|
+
as = calloc(1, sizeof(struct auto_string_data) + capacity);
|
|
263
|
+
if(as == NULL)
|
|
264
|
+
return NO_AUTO_STRING;
|
|
265
|
+
as->capacity = capacity;
|
|
266
|
+
as->position = 0;
|
|
267
|
+
if(auto_string_arena)
|
|
268
|
+
as->identifier = auto_string_arena;
|
|
269
|
+
else
|
|
270
|
+
as->identifier = find_next_auto_string_identifier();
|
|
271
|
+
as->guard[0] = 'o'; /* Used primarily to detect auto strings */
|
|
272
|
+
as->guard[1] = 't';
|
|
273
|
+
as->guard[2] = 'u';
|
|
274
|
+
as->guard[3] = 'a';
|
|
275
|
+
as->data = (c8 *)as + sizeof(struct auto_string_data);
|
|
276
|
+
*as->data = '\0';
|
|
277
|
+
as->next = NULL;
|
|
278
|
+
if(!auto_string_list)
|
|
279
|
+
auto_string_list = as;
|
|
280
|
+
else {
|
|
281
|
+
next = auto_string_list;
|
|
282
|
+
while(next && next->next)
|
|
283
|
+
next = next->next;
|
|
284
|
+
next->next = as;
|
|
285
|
+
}
|
|
286
|
+
return as->identifier;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
_SCOPE_ as8 *auto_string_by_id_extra(i32 identifier, cc8 *string, i64 extra_capacity)
|
|
290
|
+
{
|
|
291
|
+
struct auto_string_data *as = NULL, *next = NULL;
|
|
292
|
+
u64 capacity = 0, length = 0;
|
|
293
|
+
|
|
294
|
+
if(!identifier && auto_string_arena)
|
|
295
|
+
identifier = auto_string_arena;
|
|
296
|
+
else if(!identifier)
|
|
297
|
+
identifier = find_next_auto_string_identifier();
|
|
298
|
+
if(string) {
|
|
299
|
+
length = auto_string_length(string);
|
|
300
|
+
/* Negative extra capacity becames a multiple of the original string length */
|
|
301
|
+
if(extra_capacity < 0)
|
|
302
|
+
extra_capacity *= -length;
|
|
303
|
+
} else {
|
|
304
|
+
/* Negative extra capacity becames a multiple of the default */
|
|
305
|
+
if(extra_capacity < 0)
|
|
306
|
+
extra_capacity *= -DEFAULT_AUTO_STRING_CAPACITY;
|
|
307
|
+
}
|
|
308
|
+
capacity = length;
|
|
309
|
+
capacity += extra_capacity;
|
|
310
|
+
for(as = auto_string_list; as; as = as->next) {
|
|
311
|
+
if(as->identifier == identifier) {
|
|
312
|
+
if(as->capacity >= capacity && as->position == 0) {
|
|
313
|
+
as->position += capacity;
|
|
314
|
+
as->capacity -= capacity;
|
|
315
|
+
as->guard[0] = 'o'; /* Used primarily to detect auto strings */
|
|
316
|
+
as->guard[1] = 't';
|
|
317
|
+
as->guard[2] = 'u';
|
|
318
|
+
as->guard[3] = 'a';
|
|
319
|
+
if(string && length > 0) {
|
|
320
|
+
length = 0;
|
|
321
|
+
while(length < capacity) {
|
|
322
|
+
*(as->data + length) = *(string + length);
|
|
323
|
+
length++;
|
|
324
|
+
}
|
|
325
|
+
*(as->data + length + 1) = '\0';
|
|
326
|
+
}
|
|
327
|
+
return(as->data);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/* Didn't find an auto_string or we found an auto_string but it didn't have space */
|
|
332
|
+
as = calloc(1, sizeof(struct auto_string_data) + capacity + 1);
|
|
333
|
+
if(as == NULL)
|
|
334
|
+
return NO_AUTO_STRING;
|
|
335
|
+
as->capacity = extra_capacity;
|
|
336
|
+
as->position = length;
|
|
337
|
+
as->identifier = identifier;
|
|
338
|
+
as->guard[0] = 'o';
|
|
339
|
+
as->guard[1] = 't';
|
|
340
|
+
as->guard[2] = 'u';
|
|
341
|
+
as->guard[3] = 'a';
|
|
342
|
+
as->data = (c8 *)as + sizeof(struct auto_string_data);
|
|
343
|
+
as->next = NULL;
|
|
344
|
+
if(!auto_string_list)
|
|
345
|
+
auto_string_list = as;
|
|
346
|
+
else {
|
|
347
|
+
next = auto_string_list;
|
|
348
|
+
while(next && next->next)
|
|
349
|
+
next = next->next;
|
|
350
|
+
next->next = as;
|
|
351
|
+
}
|
|
352
|
+
if(string && length > 0) {
|
|
353
|
+
length = 0;
|
|
354
|
+
while(length < capacity) {
|
|
355
|
+
*(as->data + length) = *(string + length);
|
|
356
|
+
length++;
|
|
357
|
+
}
|
|
358
|
+
*(as->data + length + 1) = '\0';
|
|
359
|
+
}
|
|
360
|
+
return as->data;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
_SCOPE_ as8 *auto_string_extra(cc8 *string, i64 extra_capacity)
|
|
364
|
+
{
|
|
365
|
+
return auto_string_by_id_extra(auto_string_arena, string, extra_capacity);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
_SCOPE_ as8 *auto_string_by_id_new(i32 identifier, cc8 *string, b8 thin)
|
|
369
|
+
{
|
|
370
|
+
u64 length = 0, extra_capacity = 0;
|
|
371
|
+
|
|
372
|
+
if(string)
|
|
373
|
+
length = auto_string_length(string);
|
|
374
|
+
if(length <= DEFAULT_AUTO_STRING_CAPACITY)
|
|
375
|
+
extra_capacity = DEFAULT_AUTO_STRING_CAPACITY - length;
|
|
376
|
+
else {
|
|
377
|
+
extra_capacity = length / DEFAULT_AUTO_STRING_CAPACITY;
|
|
378
|
+
extra_capacity *= DEFAULT_AUTO_STRING_CAPACITY;
|
|
379
|
+
}
|
|
380
|
+
if(thin)
|
|
381
|
+
extra_capacity = 0;
|
|
382
|
+
return auto_string_by_id_extra(identifier, string, extra_capacity);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
_SCOPE_ as8 *auto_string_new(cc8 *string, b8 thin)
|
|
386
|
+
{
|
|
387
|
+
return auto_string_by_id_new(auto_string_arena, string, thin);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
_SCOPE_ as8 *auto_string_by_id_substring(i32 identifier, cc8 *string, u64 position, u64 length, b8 thin)
|
|
391
|
+
{
|
|
392
|
+
struct auto_string_data *as = NULL;
|
|
393
|
+
u64 string_length = auto_string_length(string);
|
|
394
|
+
u64 substring_length = 0, capacity = 0;
|
|
395
|
+
c8 *substring = NULL;
|
|
396
|
+
|
|
397
|
+
if(!string || length == 0 || string_length <= position)
|
|
398
|
+
return NULL;
|
|
399
|
+
|
|
400
|
+
substring_length = auto_string_length(string);
|
|
401
|
+
substring_length -= position;
|
|
402
|
+
if(length > substring_length)
|
|
403
|
+
length = substring_length;
|
|
404
|
+
if(length < DEFAULT_AUTO_STRING_CAPACITY)
|
|
405
|
+
capacity = DEFAULT_AUTO_STRING_CAPACITY;
|
|
406
|
+
else {
|
|
407
|
+
capacity = length / DEFAULT_AUTO_STRING_CAPACITY;
|
|
408
|
+
capacity *= DEFAULT_AUTO_STRING_CAPACITY;
|
|
409
|
+
}
|
|
410
|
+
if(thin)
|
|
411
|
+
capacity = length;
|
|
412
|
+
substring_length = length;
|
|
413
|
+
substring = auto_string_by_id_extra(identifier, "", capacity);
|
|
414
|
+
while(length) {
|
|
415
|
+
*(substring + length - 1) = *(string + position + length);
|
|
416
|
+
length--;
|
|
417
|
+
}
|
|
418
|
+
*(substring + substring_length + 1) = '\0';
|
|
419
|
+
as = (struct auto_string_data *)(substring - sizeof(struct auto_string_data));
|
|
420
|
+
as->capacity -= substring_length;
|
|
421
|
+
as->position += substring_length;
|
|
422
|
+
|
|
423
|
+
return substring;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
_SCOPE_ as8 *auto_string_substring(cc8 *string, u64 position, u64 length, b8 thin)
|
|
427
|
+
{
|
|
428
|
+
return auto_string_by_id_substring(auto_string_arena, string, position, length, thin);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
_SCOPE_ as8 *auto_string_add(c8 *string, cc8 *add_string) /* b8 thin? */
|
|
432
|
+
{
|
|
433
|
+
struct auto_string_data *as = NULL;
|
|
434
|
+
u64 length = 0, add_length = auto_string_length(add_string);
|
|
435
|
+
i32 identifier = 0;
|
|
436
|
+
as8 *new_string = NULL;
|
|
437
|
+
|
|
438
|
+
if(!add_string)
|
|
439
|
+
return string;
|
|
440
|
+
|
|
441
|
+
if(is_auto_string(string)) {
|
|
442
|
+
as = (struct auto_string_data *)(string - sizeof(struct auto_string_data));
|
|
443
|
+
if(as->capacity >= add_length) {
|
|
444
|
+
while(length <= add_length) {
|
|
445
|
+
*(string + as->position + length) = *(add_string + length);
|
|
446
|
+
length++;
|
|
447
|
+
}
|
|
448
|
+
*(string + as->position + add_length + 1) = '\0';
|
|
449
|
+
as->capacity -= add_length;
|
|
450
|
+
as->position += add_length;
|
|
451
|
+
return string;
|
|
452
|
+
} else {
|
|
453
|
+
identifier = find_auto_string_identifier(string);
|
|
454
|
+
new_string = auto_string_by_id_extra(identifier, string, add_length);
|
|
455
|
+
return auto_string_add(new_string, add_string);
|
|
456
|
+
}
|
|
457
|
+
} else if(is_auto_string(add_string)) {
|
|
458
|
+
identifier = find_auto_string_identifier(add_string);
|
|
459
|
+
new_string = auto_string_by_id_extra(identifier, string, add_length);
|
|
460
|
+
return auto_string_add(new_string, add_string);
|
|
461
|
+
}
|
|
462
|
+
new_string = auto_string_by_id_extra(auto_string_arena, string, add_length);
|
|
463
|
+
return auto_string_add(new_string, add_string);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
_SCOPE_ void auto_string_update(as8 *string)
|
|
467
|
+
{
|
|
468
|
+
struct auto_string_data *as = NULL;
|
|
469
|
+
u64 length = find_string_length(string); /* manual count */
|
|
470
|
+
|
|
471
|
+
if(!string || !is_auto_string(string))
|
|
472
|
+
return;
|
|
473
|
+
|
|
474
|
+
for(as = auto_string_list; as; as = as->next) {
|
|
475
|
+
if(as->data && as->data <= string &&
|
|
476
|
+
as->data + as->position >= string) {
|
|
477
|
+
if(as->position < length) {
|
|
478
|
+
as->capacity -= length - as->position;
|
|
479
|
+
as->position = length;
|
|
480
|
+
} else if(as->position > length) {
|
|
481
|
+
as->capacity += as->position - length;
|
|
482
|
+
as->position = length;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
_SCOPE_ i32 find_auto_string_identifier(cc8 *string)
|
|
489
|
+
{
|
|
490
|
+
struct auto_string_data *as = NULL;
|
|
491
|
+
|
|
492
|
+
if(!string)
|
|
493
|
+
return 0;
|
|
494
|
+
|
|
495
|
+
for(as = auto_string_list; as; as = as->next) {
|
|
496
|
+
if(as->data && as->data <= string &&
|
|
497
|
+
as->data + as->position >= string)
|
|
498
|
+
return as->identifier;
|
|
499
|
+
}
|
|
500
|
+
return 0;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
_SCOPE_ i32 find_next_auto_string_identifier(void)
|
|
504
|
+
{
|
|
505
|
+
struct auto_string_data *as = NULL;
|
|
506
|
+
u32 next_identifier = 0;
|
|
507
|
+
|
|
508
|
+
for(as = auto_string_list; as; as = as->next) {
|
|
509
|
+
if(as->identifier > next_identifier)
|
|
510
|
+
next_identifier = as->identifier;
|
|
511
|
+
}
|
|
512
|
+
next_identifier++;
|
|
513
|
+
return next_identifier;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
_SCOPE_ b8 is_auto_string(cc8 *string)
|
|
517
|
+
{
|
|
518
|
+
struct auto_string_data *as = NULL;
|
|
519
|
+
|
|
520
|
+
if(!string)
|
|
521
|
+
return FALSE;
|
|
522
|
+
as = (struct auto_string_data *)(string - sizeof(struct auto_string_data));
|
|
523
|
+
if(as && as->guard[3] == 'a' &&
|
|
524
|
+
as->guard[2] == 'u' &&
|
|
525
|
+
as->guard[1] == 't' &&
|
|
526
|
+
as->guard[0] == 'o')
|
|
527
|
+
return TRUE;
|
|
528
|
+
return FALSE;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
_SCOPE_ u64 find_string_length(cc8 *string)
|
|
532
|
+
{
|
|
533
|
+
u64 length = 0;
|
|
534
|
+
|
|
535
|
+
while(*(string + length) != '\0')
|
|
536
|
+
length++;
|
|
537
|
+
return length;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
_SCOPE_ b8 auto_string_contains(cc8 *string, cc8 *sub_string)
|
|
541
|
+
{
|
|
542
|
+
cc8 *haystack = NULL, *needle = NULL, *hay = NULL;
|
|
543
|
+
|
|
544
|
+
if(string == sub_string)
|
|
545
|
+
return TRUE;
|
|
546
|
+
if(!string || !sub_string)
|
|
547
|
+
return FALSE;
|
|
548
|
+
for(haystack = string; *haystack; ++haystack) {
|
|
549
|
+
needle = sub_string;
|
|
550
|
+
hay = haystack;
|
|
551
|
+
while(*needle && *hay && *needle++ == *hay++);
|
|
552
|
+
if(*needle == '\0')
|
|
553
|
+
return TRUE;
|
|
554
|
+
}
|
|
555
|
+
return FALSE;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
_SCOPE_ b8 auto_string_match(cc8 *string, cc8 *string2)
|
|
559
|
+
{
|
|
560
|
+
u64 length = auto_string_length(string);
|
|
561
|
+
u64 length2 = auto_string_length(string2);
|
|
562
|
+
|
|
563
|
+
if(string == string2)
|
|
564
|
+
return TRUE;
|
|
565
|
+
if(length != length2)
|
|
566
|
+
return FALSE;
|
|
567
|
+
while(*string++ && *string2++ && *string == *string2);
|
|
568
|
+
if(*string || *string2)
|
|
569
|
+
return FALSE;
|
|
570
|
+
return TRUE;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
_SCOPE_ b8 auto_string_match_no_case(cc8 *string, cc8 *string2)
|
|
574
|
+
{
|
|
575
|
+
u64 length = auto_string_length(string);
|
|
576
|
+
u64 length2 = auto_string_length(string2);
|
|
577
|
+
|
|
578
|
+
if(string == string2)
|
|
579
|
+
return TRUE;
|
|
580
|
+
if(length != length2)
|
|
581
|
+
return FALSE;
|
|
582
|
+
while(*string++ && *string2++ && TO_LOWER_CASE(*string) == TO_LOWER_CASE(*string2));
|
|
583
|
+
if(*string || *string2)
|
|
584
|
+
return FALSE;
|
|
585
|
+
return TRUE;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
_SCOPE_ b8 auto_string_prefixed(cc8 *string, cc8 *prefix)
|
|
589
|
+
{
|
|
590
|
+
u64 length = auto_string_length(string);
|
|
591
|
+
u64 prefix_length = auto_string_length(prefix);
|
|
592
|
+
|
|
593
|
+
if(string == prefix)
|
|
594
|
+
return TRUE;
|
|
595
|
+
if(prefix_length > length)
|
|
596
|
+
return FALSE;
|
|
597
|
+
while(*string && *prefix && *string++ == *prefix++);
|
|
598
|
+
if(!*prefix)
|
|
599
|
+
return TRUE;
|
|
600
|
+
return FALSE;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
_SCOPE_ b8 auto_string_prefixed_no_case(cc8 *string, cc8 *prefix)
|
|
604
|
+
{
|
|
605
|
+
u64 length = auto_string_length(string);
|
|
606
|
+
u64 prefix_length = auto_string_length(prefix);
|
|
607
|
+
|
|
608
|
+
if(string == prefix)
|
|
609
|
+
return TRUE;
|
|
610
|
+
if(prefix_length > length)
|
|
611
|
+
return FALSE;
|
|
612
|
+
while(*string++ && *prefix++ && TO_LOWER_CASE(*string) == TO_LOWER_CASE(*prefix));
|
|
613
|
+
if(!*prefix)
|
|
614
|
+
return TRUE;
|
|
615
|
+
return FALSE;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
_SCOPE_ b8 auto_view_match(struct auto_view_data *view, cc8 *string)
|
|
619
|
+
{
|
|
620
|
+
u64 length = 0;
|
|
621
|
+
|
|
622
|
+
if(!view || !string)
|
|
623
|
+
return FALSE;
|
|
624
|
+
length = view->length;
|
|
625
|
+
while(length > 0) {
|
|
626
|
+
length--;
|
|
627
|
+
if(*(string + length) != *(view->data + length))
|
|
628
|
+
return FALSE;
|
|
629
|
+
}
|
|
630
|
+
if(length > 0)
|
|
631
|
+
return FALSE;
|
|
632
|
+
return TRUE;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
_SCOPE_ b8 auto_views_match(struct auto_view_data *view,
|
|
636
|
+
struct auto_view_data *view2)
|
|
637
|
+
{
|
|
638
|
+
u64 length = 0;
|
|
639
|
+
|
|
640
|
+
if(!view && !view2)
|
|
641
|
+
return TRUE;
|
|
642
|
+
if(!view || !view2)
|
|
643
|
+
return FALSE;
|
|
644
|
+
length = view->length;
|
|
645
|
+
if(length != view2->length)
|
|
646
|
+
return FALSE;
|
|
647
|
+
if(length == 0)
|
|
648
|
+
return TRUE;
|
|
649
|
+
if(view->data == view2->data)
|
|
650
|
+
return TRUE;
|
|
651
|
+
while(length > 0) {
|
|
652
|
+
length--;
|
|
653
|
+
if(*(view->data + length) != *(view2->data + length))
|
|
654
|
+
return FALSE;
|
|
655
|
+
}
|
|
656
|
+
return TRUE;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
_SCOPE_ b8 auto_views_match_no_case(struct auto_view_data *view,
|
|
660
|
+
struct auto_view_data *view2)
|
|
661
|
+
{
|
|
662
|
+
u64 length = 0;
|
|
663
|
+
|
|
664
|
+
if(!view && !view2)
|
|
665
|
+
return TRUE;
|
|
666
|
+
if(!view || !view2)
|
|
667
|
+
return FALSE;
|
|
668
|
+
length = view->length;
|
|
669
|
+
if(length != view2->length)
|
|
670
|
+
return FALSE;
|
|
671
|
+
if(length == 0)
|
|
672
|
+
return TRUE;
|
|
673
|
+
if(view->data == view2->data)
|
|
674
|
+
return TRUE;
|
|
675
|
+
while(length > 0) {
|
|
676
|
+
length--;
|
|
677
|
+
if(TO_LOWER_CASE(*(view->data + length)) != TO_LOWER_CASE(*(view2->data + length)))
|
|
678
|
+
return FALSE;
|
|
679
|
+
}
|
|
680
|
+
return TRUE;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
_SCOPE_ b8 auto_view_match_no_case(struct auto_view_data *view, cc8 *string)
|
|
684
|
+
{
|
|
685
|
+
u64 length = 0;
|
|
686
|
+
|
|
687
|
+
if(!view || !string)
|
|
688
|
+
return FALSE;
|
|
689
|
+
|
|
690
|
+
length = view->length;
|
|
691
|
+
while(length > 0) {
|
|
692
|
+
length--;
|
|
693
|
+
if(TO_LOWER_CASE(*(string + length)) != TO_LOWER_CASE(*(view->data + length)))
|
|
694
|
+
return FALSE;
|
|
695
|
+
}
|
|
696
|
+
return TRUE;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
_SCOPE_ b8 auto_view_prefixed(struct auto_view_data *view, cc8 *prefix)
|
|
700
|
+
{
|
|
701
|
+
u64 length = auto_string_length(prefix);
|
|
702
|
+
|
|
703
|
+
if(!view || !prefix || !length || length > view->length)
|
|
704
|
+
return FALSE;
|
|
705
|
+
while(length > 0) {
|
|
706
|
+
length--;
|
|
707
|
+
if(*(prefix + length) != *(view->data + length))
|
|
708
|
+
return FALSE;
|
|
709
|
+
}
|
|
710
|
+
return TRUE;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
_SCOPE_ b8 auto_view_prefixed_no_case(struct auto_view_data *view, cc8 *prefix)
|
|
714
|
+
{
|
|
715
|
+
u64 length = auto_string_length(prefix);
|
|
716
|
+
|
|
717
|
+
if(!view || !prefix || !length || length > view->length)
|
|
718
|
+
return FALSE;
|
|
719
|
+
while(length > 0) {
|
|
720
|
+
length--;
|
|
721
|
+
if(*(prefix + length) != *(view->data + length))
|
|
722
|
+
return FALSE;
|
|
723
|
+
}
|
|
724
|
+
return TRUE;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
_SCOPE_ void auto_view_print(struct auto_view_data *view)
|
|
728
|
+
{
|
|
729
|
+
u64 length = 0;
|
|
730
|
+
|
|
731
|
+
if(!view || !view->length)
|
|
732
|
+
return;
|
|
733
|
+
while(length < view->length) {
|
|
734
|
+
putchar(*(view->data + length));
|
|
735
|
+
length++;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
_SCOPE_ u64 auto_string_length(cc8 *string)
|
|
740
|
+
{
|
|
741
|
+
struct auto_string_data *as = NULL;
|
|
742
|
+
|
|
743
|
+
if(!string)
|
|
744
|
+
return 0;
|
|
745
|
+
if(is_auto_string(string)) { /* length = as->position */
|
|
746
|
+
as = (struct auto_string_data *)(string - sizeof(struct auto_string_data));
|
|
747
|
+
return as->position;
|
|
748
|
+
}
|
|
749
|
+
return find_string_length(string);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
_SCOPE_ u64 auto_string_available(cc8 *string)
|
|
753
|
+
{
|
|
754
|
+
struct auto_string_data *as = NULL;
|
|
755
|
+
|
|
756
|
+
if(!string)
|
|
757
|
+
return 0;
|
|
758
|
+
if(is_auto_string(string)) { /* available = as->capacity */
|
|
759
|
+
as = (struct auto_string_data *)(string - sizeof(struct auto_string_data));
|
|
760
|
+
return as->capacity;
|
|
761
|
+
}
|
|
762
|
+
return 0;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
_SCOPE_ struct auto_view_data auto_view(cc8 *string)
|
|
766
|
+
{
|
|
767
|
+
struct auto_view_data view = { 0 };
|
|
768
|
+
|
|
769
|
+
view.length = auto_string_length(string);
|
|
770
|
+
view.data = (c8 *)string;
|
|
771
|
+
view.clamp = '\0';
|
|
772
|
+
|
|
773
|
+
return view;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/*
|
|
777
|
+
!!! IMPORTANT NOTE ON CLAMP !!!
|
|
778
|
+
|
|
779
|
+
This works:
|
|
780
|
+
|
|
781
|
+
c8 my_string[] = "This will work. Pretty cool, right?";
|
|
782
|
+
|
|
783
|
+
!!! ** You can't clamp on: *char literals !!!
|
|
784
|
+
!!! !!!
|
|
785
|
+
!!! ** Only clamp on: char[] and heap !!!
|
|
786
|
+
!!! !!!
|
|
787
|
+
!!! This will segfault: !!!
|
|
788
|
+
|
|
789
|
+
c8 *my_string2 = "This will segfault if you try to clamp it. Unfortunately.";
|
|
790
|
+
|
|
791
|
+
view2 = auto_view(my_string2);
|
|
792
|
+
auto_view_chop_right(&view2, 15);
|
|
793
|
+
|
|
794
|
+
This will segfault:
|
|
795
|
+
|
|
796
|
+
auto_view_clamp(&view2));
|
|
797
|
+
|
|
798
|
+
*/
|
|
799
|
+
|
|
800
|
+
_SCOPE_ c8 *auto_view_clamp(struct auto_view_data *view)
|
|
801
|
+
{
|
|
802
|
+
if(view->data && *(view->data + view->length)) {
|
|
803
|
+
view->clamp = *(view->data + view->length);
|
|
804
|
+
*(view->data + view->length) = '\0';
|
|
805
|
+
}
|
|
806
|
+
return view->data;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
_SCOPE_ c8 *auto_view_unclamp(struct auto_view_data *view)
|
|
810
|
+
{
|
|
811
|
+
if(view->data && view->clamp) {
|
|
812
|
+
*(view->data + view->length) = view->clamp;
|
|
813
|
+
view->clamp = '\0';
|
|
814
|
+
}
|
|
815
|
+
return view->data;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
_SCOPE_ void auto_view_slice(struct auto_view_data *view, u64 start, u64 end)
|
|
819
|
+
{
|
|
820
|
+
if(start > view->length || start > end) {
|
|
821
|
+
view->length = 0;
|
|
822
|
+
view->data = "";
|
|
823
|
+
view->clamp = 0;
|
|
824
|
+
} else {
|
|
825
|
+
view->data += start;
|
|
826
|
+
view->length = end;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
_SCOPE_ void auto_view_chop_left(struct auto_view_data *view, u64 length)
|
|
831
|
+
{
|
|
832
|
+
if(view->length <= length) {
|
|
833
|
+
view->length = 0;
|
|
834
|
+
view->data = "";
|
|
835
|
+
} else {
|
|
836
|
+
view->length -= length;
|
|
837
|
+
view->data += length;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
_SCOPE_ void auto_view_chop_right(struct auto_view_data *view, u64 length)
|
|
842
|
+
{
|
|
843
|
+
if(view->length <= length) {
|
|
844
|
+
view->length = 0;
|
|
845
|
+
view->data = "";
|
|
846
|
+
} else
|
|
847
|
+
view->length -= length;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
_SCOPE_ void auto_view_trim_left(struct auto_view_data *view)
|
|
851
|
+
{
|
|
852
|
+
while(*view->data && IS_WHITE_SPACE(*view->data)) {
|
|
853
|
+
view->data++;
|
|
854
|
+
view->length--;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
_SCOPE_ void auto_view_trim_right(struct auto_view_data *view)
|
|
859
|
+
{
|
|
860
|
+
while(*(view->data + view->length - 1) && IS_WHITE_SPACE(*(view->data + view->length - 1)))
|
|
861
|
+
view->length--;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
_SCOPE_ void auto_view_trim(struct auto_view_data *view)
|
|
865
|
+
{
|
|
866
|
+
auto_view_trim_left(view);
|
|
867
|
+
auto_view_trim_right(view);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
_SCOPE_ void auto_string_memory_wipe(void *data, u64 capacity)
|
|
871
|
+
{
|
|
872
|
+
volatile unsigned char *volatile_data = (volatile unsigned char *)data;
|
|
873
|
+
|
|
874
|
+
if(!volatile_data || !data || capacity == 0)
|
|
875
|
+
return;
|
|
876
|
+
|
|
877
|
+
capacity -= 1; /* 0-based */
|
|
878
|
+
while(capacity--)
|
|
879
|
+
*volatile_data++ = 0;
|
|
880
|
+
*volatile_data = 0;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
_SCOPE_ void auto_string_by_id_reset(u32 identifier)
|
|
884
|
+
{
|
|
885
|
+
struct auto_string_data *as = NULL;
|
|
886
|
+
|
|
887
|
+
for(as = auto_string_list; as; as = as->next) {
|
|
888
|
+
if(as->identifier == identifier) {
|
|
889
|
+
as->capacity += as->position;
|
|
890
|
+
auto_string_memory_wipe(as->data, as->capacity);
|
|
891
|
+
as->position = 0;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
_SCOPE_ void auto_string_reset(void)
|
|
897
|
+
{
|
|
898
|
+
auto_string_by_id_reset(auto_string_arena);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
_SCOPE_ void auto_string_reset_all(void)
|
|
902
|
+
{
|
|
903
|
+
struct auto_string_data *as = NULL;
|
|
904
|
+
|
|
905
|
+
for(as = auto_string_list; as; as = as->next) {
|
|
906
|
+
as->capacity += as->position;
|
|
907
|
+
auto_string_memory_wipe(as->data, as->capacity);
|
|
908
|
+
as->position = 0;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
_SCOPE_ void auto_string_by_id_free(u32 identifier)
|
|
913
|
+
{
|
|
914
|
+
struct auto_string_data *as = NULL, *next = NULL;
|
|
915
|
+
|
|
916
|
+
as = auto_string_list;
|
|
917
|
+
while(as && as->identifier == identifier) {
|
|
918
|
+
next = as->next;
|
|
919
|
+
auto_string_memory_wipe(as->data, as->capacity + as->position);
|
|
920
|
+
free(as);
|
|
921
|
+
auto_string_list = as = next;
|
|
922
|
+
}
|
|
923
|
+
for(; as; as = next) {
|
|
924
|
+
next = as->next;
|
|
925
|
+
while(next && next->identifier == identifier) {
|
|
926
|
+
if(next->next)
|
|
927
|
+
as->next = next->next;
|
|
928
|
+
else
|
|
929
|
+
as->next = NULL;
|
|
930
|
+
auto_string_memory_wipe(next->data, next->capacity + next->position);
|
|
931
|
+
free(next);
|
|
932
|
+
next = as->next;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
_SCOPE_ void auto_string_free(void)
|
|
938
|
+
{
|
|
939
|
+
auto_string_by_id_free(auto_string_arena);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
_SCOPE_ void auto_string_free_all(void)
|
|
943
|
+
{
|
|
944
|
+
struct auto_string_data *as = NULL, *next = NULL;
|
|
945
|
+
|
|
946
|
+
for(as = auto_string_list; as; as = next) {
|
|
947
|
+
next = as->next;
|
|
948
|
+
auto_string_memory_wipe(as->data, as->capacity + as->position);
|
|
949
|
+
free(as);
|
|
950
|
+
}
|
|
951
|
+
auto_string_list = NULL;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
_SCOPE_ void auto_string_show(void)
|
|
955
|
+
{
|
|
956
|
+
struct auto_string_data *as = NULL;
|
|
957
|
+
u32 top_identifier = 0, identifier = 0;
|
|
958
|
+
b8 found = FALSE;
|
|
959
|
+
|
|
960
|
+
for(as = auto_string_list; as; as = as->next) {
|
|
961
|
+
if(as->identifier > top_identifier)
|
|
962
|
+
top_identifier = as->identifier;
|
|
963
|
+
}
|
|
964
|
+
if(!top_identifier)
|
|
965
|
+
printf("No auto strings are currently created.\n");
|
|
966
|
+
else {
|
|
967
|
+
printf("---------------------------------------------------------------------------------\n");
|
|
968
|
+
printf("Id Used Unused Total Location / Data (Version: %s)\n", AUTO_STRING_VERSION);
|
|
969
|
+
printf("---------------------------------------------------------------------------------\n");
|
|
970
|
+
while(identifier <= top_identifier) {
|
|
971
|
+
for(as = auto_string_list; as; as = as->next) {
|
|
972
|
+
if(as->identifier == identifier) {
|
|
973
|
+
if(!found)
|
|
974
|
+
printf("%-6d %-10ld %-10ld %-10ld %p %-30.30s\n", as->identifier, as->position,
|
|
975
|
+
as->capacity, as->position + as->capacity, as->data,
|
|
976
|
+
as->data);
|
|
977
|
+
else
|
|
978
|
+
printf(" %-4d %-10ld %-10ld %-10ld %p %-30.30s\n", as->identifier, as->position,
|
|
979
|
+
as->capacity, as->position + as->capacity, as->data,
|
|
980
|
+
as->data);
|
|
981
|
+
found = TRUE;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
identifier++;
|
|
985
|
+
found = FALSE;
|
|
986
|
+
}
|
|
987
|
+
printf("---------------------------------------------------------------------------------\n");
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
#else
|
|
991
|
+
extern i32 auto_string_arena = 0;
|
|
992
|
+
#endif /* AUTO_STRING_IMPLEMENTATION */
|
|
993
|
+
#if defined(_SCOPE_WAS_NOT_PREDEFINED_)
|
|
994
|
+
#undef _SCOPE_WAS_NOT_PREDEFINED_
|
|
995
|
+
#undef _SCOPE_
|
|
996
|
+
#endif
|
|
997
|
+
#endif /* AUTO_STRING_H_Minaswan */
|
|
998
|
+
|
|
999
|
+
/*
|
|
1000
|
+
Example:
|
|
1001
|
+
|
|
1002
|
+
#define AUTO_STRING_IMPLEMENTATION
|
|
1003
|
+
#include "auto_string.h"
|
|
1004
|
+
|
|
1005
|
+
i32 main(i32 argc, c8 *argv[])
|
|
1006
|
+
{
|
|
1007
|
+
i32 identifier = 0;
|
|
1008
|
+
c8 *data = NULL;
|
|
1009
|
+
|
|
1010
|
+
identifier = auto_string_init(MB(4));
|
|
1011
|
+
|
|
1012
|
+
data = auto_string_add("hello", 1);
|
|
1013
|
+
|
|
1014
|
+
auto_string_show();
|
|
1015
|
+
auto_string_reset(identifier);
|
|
1016
|
+
auto_string_free(identifier);
|
|
1017
|
+
auto_string_free_all();
|
|
1018
|
+
auto_string_show();
|
|
1019
|
+
|
|
1020
|
+
return 0;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
*/
|