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.
@@ -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
+ */