Archeus 0.0.0
A C library and game engine that focuses on documentation
Loading...
Searching...
No Matches
string.c
Go to the documentation of this file.
1#include "arc/std/string.h"
2
3#include "arc/std/bool.h"
4#include "arc/std/errno.h"
5#include <stdint.h>
6#include <string.h>
7#include <stdlib.h>
8
9void ARC_String_Create(ARC_String **string, char *data, uint64_t length){
10 //check if the size is too big to create and error if so
11 if(length == ~(uint64_t)0){
13 ARC_DEBUG_LOG_ERROR("ARC_String_Create(string, data, length), length was max uint64_t which is bigger than allowed");
14 *string = NULL;
15 return;
16 }
17
18 //create the string container and malloc the char array (this will allways be bigger than zero so there will be no issue if zero is passed in)
19 *string = (ARC_String *)malloc(sizeof(ARC_String));
20 (*string)->data = (char *)malloc(sizeof(char) * (length + 1));
21 (*string)->length = length;
22
23 //if the string has a size, copy the string
24 if(length > 0){
25 strncpy((*string)->data, data, length);
26 }
27
28 //set the end of the string to \0 (to mirror how cstrings work)
29 (*string)->data[length] = '\0';
30}
31
32void ARC_String_CreateWithStrlen(ARC_String **string, char *data){
33 //create the string passing in the strlen of data for the length
34 ARC_String_Create(string, data, strlen(data));
35}
36
37void ARC_String_CreateEmpty(ARC_String **string, uint64_t length){
38 //check if the size is too big to create and error if so
39 if(length == ~(uint64_t)0){
41 ARC_DEBUG_LOG_ERROR("ARC_String_Create(string, data, length), length was max uint64_t which is bigger than allowed");
42 *string = NULL;
43 return;
44 }
45
46 //create the string container and initialize data with all 0s for the size
47 *string = (ARC_String *)malloc(sizeof(ARC_String));
48 (*string)->data = (char *)calloc(sizeof(char), length + 1);
49 (*string)->length = length;
50}
51
53 //check if the string's data exists and if so free it
54 if(string->data != NULL){
55 free(string->data);
56 }
57
58 //free the string itself
59 free(string);
60}
61
62void ARC_String_Copy(ARC_String **copy, ARC_String *original){
63 if(!original){
65 *copy = NULL;
66 return;
67 }
68
69 ARC_String_Create(copy, original->data, original->length);
70}
71
72void ARC_String_CopySubstring(ARC_String **substring, ARC_String *original, uint64_t start, uint64_t length){
73 if(!original){
75 *substring = NULL;
76 return;
77 }
78
79 if(length == 0){
80 *substring = NULL;
81 return;
82 }
83
84 if(start + length > original->length){
86 *substring = NULL;
87 return;
88 }
89
90 char data[length];
91 for(uint32_t i = 0; i < length; i++){
92 data[i] = 0;
93 }
94
95 strncpy(data, original->data + start, length);
96
97 ARC_String_Create(substring, data, length);
98}
99
100void ARC_String_ReplaceWithSubstring(ARC_String **string, uint64_t start, uint64_t length){
101 ARC_String *substring;
102 ARC_String_CopySubstring(&substring, *string, start, length);
103
104 //if error or substring is null free memory and return
105 if(arc_errno || substring == NULL){
106 if(substring != NULL){
107 ARC_String_Destroy(substring);
108 }
109 return;
110 }
111
112 ARC_String_Destroy(*string);
113 *string = substring;
114}
115
116void ARC_String_RemoveSubstring(ARC_String **newString, ARC_String *original, ARC_String *substring){
117 uint64_t index = ARC_String_Find(original, substring);
118 if(arc_errno){
119 newString = NULL;
120 return;
121 }
122
123 ARC_String_RemoveSection(newString, original, index, original->length);
124}
125
127 ARC_String_AppendCString(string, append->data, append->length);
128}
129
130void ARC_String_AppendCString(ARC_String **string, const char *cstring, uint64_t length){
131 char *data = (char *)malloc(sizeof(char) * ((*string)->length + length + 1));
132
133 strncpy(data, (*string)->data, (*string)->length);
134 strncpy(data + (*string)->length, cstring, length);
135 data[(*string)->length + length] = '\0';
136
137 free((*string)->data);
138
139 (*string)->data = data;
140 (*string)->length = (*string)->length + length;
141}
142
143void ARC_String_AppendCStringWithStrlen(ARC_String **string, const char *cstring){
144 ARC_String_AppendCString(string, cstring, strlen(cstring));
145}
146
148 if(first->length != second->length){
149 return ARC_False;
150 }
151
152 if(strncmp(first->data, second->data, first->length)){
153 return ARC_False;
154 }
155
156 return ARC_True;
157}
158
159ARC_Bool ARC_String_EqualsCString(ARC_String *string, const char *cstring, uint64_t length){
160 if(string->length != length){
161 return ARC_False;
162 }
163
164 if(strncmp(string->data, cstring, string->length)){
165 return ARC_False;
166 }
167
168 return ARC_True;
169}
170
172 return ARC_String_EqualsCString(string, cstring, strlen(cstring));
173}
174
176 return ARC_String_SubstringEqualsCString(first, offset, second->data, second->length);
177}
178
179ARC_Bool ARC_String_SubstringEqualsCString(ARC_String *string, uint64_t offset, const char *cstring, uint64_t length){
180 if(string->length - offset < length){
181 return ARC_False;
182 }
183
184 if(strncmp(string->data + offset, cstring, length)){
185 return ARC_False;
186 }
187
188 return ARC_True;
189}
190
191//TODO: fix this
193 for(uint64_t length = string->length; length; length--){
194 if(string->data[length - 1] >= 'a' && string->data[length - 1] <= 'z'){
195 continue;
196 }
197
198 if(string->data[length - 1] >= 'A' && string->data[length - 1] <= 'Z'){
199 continue;
200 }
201
202 return ARC_True;
203 }
204
205 return ARC_False;
206}
207
209 for(uint64_t index = 0; index < string->length; index++){
210 if(string->data[index] < '0' || string->data[index] > '9'){
211 return ARC_False;
212 }
213 }
214
215 return ARC_True;
216}
217
219 return (uint64_t) strtoul(string->data, NULL, 10);
220}
221
223 return (int64_t) strtol(string->data, NULL, 10);
224}
225
227 return strtod(string->data, NULL);
228}
229
230
231uint64_t ARC_String_Find(ARC_String *string, ARC_String *substring){
232 if(!string || !substring){
233 ARC_DEBUG_LOG_ERROR("ARC_String_Find(string, substring), string or substring was null");
235 return ~(uint64_t)0;
236 }
237
238 if(substring->length > string->length){
239 return ~(uint64_t)0;
240 }
241
242 uint64_t max = string->length - (substring->length - 1);
243 for(uint64_t i = 0; max; i++, max--){
244 if(!strncmp(string->data + i, substring->data, substring->length)){
245 return i;
246 }
247 }
248
249 return ~(uint64_t)0;
250}
251
252uint64_t ARC_String_FindCString(ARC_String *string, const char *cstring, uint64_t length){
253 if(!string || !cstring){
255 ARC_DEBUG_LOG_ERROR("ARC_String_FindCString(string, cstring, length), string or cstring was null");
256 return ~(uint64_t)0;
257 }
258
259 if(string->length < length){
260 return ~(uint64_t)0;
261 }
262
263 uint64_t max = string->length - (length - 1);
264 for(uint64_t i = 0; i < max; i++){
265 if(!strncmp(string->data + i, cstring, length)){
266 return i + 1;
267 }
268 }
269
270 return ~(uint64_t)0;
271}
272
273uint64_t ARC_String_FindCStringWithStrlen(ARC_String *string, const char *cstring){
274 return ARC_String_FindCString(string, cstring, strlen(cstring));
275}
276
277uint64_t ARC_String_FindBack(ARC_String *string, ARC_String *substring){
278 if(!string || !substring){
280 ARC_DEBUG_LOG_ERROR("ARC_String_FindBack(string, substring), string or substring was null");
281 return ~(uint64_t)0;
282 }
283
284 if(substring->length > string->length){
285 return ~(uint64_t)0;
286 }
287
288 uint64_t max = string->length - (substring->length - 1);
289 for(; max; max--){
290 if(!strncmp(string->data + (max - 1), substring->data, substring->length)){
291 return max;
292 }
293 }
294
295 return ~(uint64_t)0;
296}
297
298uint64_t ARC_String_FindBackCString(ARC_String *string, const char *cstring, uint64_t length){
299 if(!string || !cstring){
301 ARC_DEBUG_LOG_ERROR("ARC_String_FindBack(string, substring), string or substring was null");
302 return ~(uint64_t)0;
303 }
304
305 if(length > string->length){
306 return ~(uint64_t)0;
307 }
308
309 uint64_t max = string->length - (length - 1);
310 for(; max; max--){
311 if(!strncmp(string->data + (max - 1), cstring, length)){
312 return max;
313 }
314 }
315
316 return ~(uint64_t)0;
317}
318
319uint64_t ARC_String_FindBackCStringWithStrlen(ARC_String *string, const char *cstring){
320 return ARC_String_FindBackCString(string, cstring, strlen(cstring));
321}
322
323void ARC_String_StripEnds(ARC_String **stripped, ARC_String *original, char charToStrip){
324 if(!original){
326 *stripped = NULL;
327 return;
328 }
329
330 if(!original->length){
332 *stripped = NULL;
333 return;
334 }
335
336 uint64_t length = original->length - 1;
337 for(; length; length--){
338 if(strncmp(original->data + (length - 1), &charToStrip, 1)){
339 break;
340 }
341 }
342
343 if(!length){
345 *stripped = NULL;
346 return;
347 }
348
349 uint64_t start = 0;
350 for(; start <= length; start++){
351 if(strncmp(original->data + start, &charToStrip, 1)){
352 break;
353 }
354 }
355
356 if(start == length){
358 *stripped = NULL;
359 return;
360 }
361
362 length -= start;
363 ARC_String_Create(stripped, original->data + start, length);
364}
365
367 if(!original){
369 *stripped = NULL;
370 return;
371 }
372
373 if(!original->length){
375 *stripped = NULL;
376 return;
377 }
378
379 uint64_t length = 0;
380 for(uint64_t i = 0; i < original->length; i++){
381 if(original->data[i] == ' '){
382 continue;
383 }
384
385 if(original->data[i] == '\n'){
386 continue;
387 }
388
389 if(original->data[i] == '\t'){
390 continue;
391 }
392
393 if(original->data[i] == '\r'){
394 continue;
395 }
396
397 length++;
398 }
399
400 if(!length){
402 *stripped = NULL;
403 return;
404 }
405
406 length++;
407 char data[length];
408 for(uint32_t i = 0; i < length; i++){
409 data[i] = 0;
410 }
411
412 uint64_t start = 0;
413 for(uint64_t i = 0; i < length; i++){
414 if(original->data[i] == ' '){
415 continue;
416 }
417
418 if(original->data[i] == '\n'){
419 continue;
420 }
421
422 if(original->data[i] == '\t'){
423 continue;
424 }
425
426 if(original->data[i] == '\r'){
427 continue;
428 }
429
430 data[start] = original->data[i];
431 start++;
432 }
433
434 ARC_String_Create(stripped, data, length);
435}
436
438 uint64_t index;
439 for(uint64_t i = 0; i < original->length; i++){
440 if(original->data[i] == ' '){
441 continue;
442 }
443
444 if(original->data[i] == '\n'){
445 continue;
446 }
447
448 if(original->data[i] == '\t'){
449 continue;
450 }
451
452 if(original->data[i] == '\r'){
453 continue;
454 }
455
456 index = i;
457 break;
458 }
459
460 uint64_t endIndex;
461 for(uint64_t i = original->length;; i--){
462 if(original->data[i - 1] == ' '){
463 continue;
464 }
465
466 if(original->data[i - 1] == '\n'){
467 continue;
468 }
469
470 if(original->data[i - 1] == '\t'){
471 continue;
472 }
473
474 if(original->data[i - 1] == '\r'){
475 continue;
476 }
477
478 endIndex = i;
479 break;
480 }
481
482 ARC_String_CopySubstring(stripped, original, index, endIndex - index);
483}
484
485void ARC_String_Merge(ARC_String **combined, ARC_String *first, ARC_String *second){
486 char data[first->length + second->length];
487 for(uint32_t i = 0; i < first->length; i++){
488 data[i] = first->data[i];
489 }
490
491 for(uint32_t i = 0; i < second->length; i++){
492 data[i + first->length] = second->data[i];
493 }
494
495 ARC_String_Create(combined, data, first->length + second->length);
496}
497
498
499void ARC_String_RemoveSection(ARC_String **newString, ARC_String *original, uint64_t removeIndex, uint64_t removeLength){
500 if(removeIndex == 0 && removeIndex + removeLength >= original->length){
501 ARC_String_Copy(newString, original);
502 return;
503 }
504
505 if(removeIndex == 0){
506 ARC_String_CopySubstring(newString, original, removeLength, original->length - removeLength);
507 return;
508 }
509
510 if(removeIndex + removeLength >= original->length){
511 ARC_String_CopySubstring(newString, original, 0, removeIndex);
512 return;
513 }
514
515 ARC_String *first, *second;
516 ARC_String_CopySubstring(&first , original, 0 , removeIndex );
517 ARC_String_CopySubstring(&second, original, removeIndex + removeLength, original->length - (removeIndex + removeLength));
518
519 ARC_String_Merge(newString, first, second);
520
521 ARC_String_Destroy(first );
522 ARC_String_Destroy(second);
523}
524
525void ARC_String_ReplaceMatching(ARC_String **string, ARC_String *pattern, ARC_String *replacement){
526 ARC_String *copyReplaced;
527 ARC_String_CopyReplaceMatching(&copyReplaced, *string, pattern, replacement);
528
529 if(arc_errno != 0 || copyReplaced == NULL){
530 return;
531 }
532
533 ARC_String_Destroy(*string);
534 *string = copyReplaced;
535}
536
537void ARC_String_CopyReplaceMatching(ARC_String **newString, ARC_String *original, ARC_String *pattern, ARC_String *replacement){
538 //TODO: probs want to check if the replacement goes over a uint64_t size
539 if(original == NULL || pattern == NULL || replacement == NULL){
541 ARC_DEBUG_LOG_ERROR("ARC_String_CopyReplaceMatching(newString, original, pattern, replacement), original, pattern, or replacement was null");
542 return;
543 }
544
545 uint64_t numberOfMatches = 0;
546 for(uint64_t originalIndex = 0; originalIndex < original->length; originalIndex++){
547 if(ARC_String_SubstringEquals(original, originalIndex, pattern)){
548 numberOfMatches++;
549 originalIndex += pattern->length - 1;
550 }
551 }
552
553 //no matches were found, but that isn't an error, so copy and return
554 if(numberOfMatches == 0){
555 ARC_String_Copy(newString, original);
556 return;
557 }
558
559 (*newString) = (ARC_String *)malloc(sizeof(ARC_String));
560 (*newString)->length = original->length + (replacement->length - pattern->length);
561 (*newString)->data = (char *)malloc(sizeof(char *) * original->length + 1);
562
563 for(uint64_t originalIndex = 0, newIndex = 0; originalIndex < original->length; originalIndex++, newIndex++){
564 if(ARC_String_SubstringEquals(original, originalIndex, pattern)){
565 for(uint64_t replacementIndex = 0; replacementIndex < replacement->length; replacementIndex++){
566 (*newString)->data[newIndex + replacementIndex] = replacement->data[replacementIndex];
567 }
568
569 originalIndex += pattern->length - 1;
570 newIndex += replacement->length - 1;
571 continue;
572 }
573
574 (*newString)->data[newIndex] = original->data[originalIndex];
575 }
576
577 (*newString)->data[(*newString)->length] = '\0';
578}
579
580void ARC_String_ReplaceMatchingCString(ARC_String **string, char *patternCString, uint64_t patternLength, char *replacementCString, uint64_t replacementLength){
581 //TODO: probs want to check if the replacement goes over a uint64_t size
582 if(*string == NULL || patternCString == NULL || replacementCString == NULL){
584 ARC_DEBUG_LOG_ERROR("ARC_String_ReplaceMatchingCString(string, patternCString, patternLength, replacementCString, replacementLength), *string, patternCString, or replacementCString was null");
585 return;
586 }
587
588 ARC_String *original = *string;
589
590 uint64_t numberOfMatches = 0;
591 for(uint64_t originalIndex = 0; originalIndex < original->length; originalIndex++){
592 if(ARC_String_SubstringEqualsCString(original, originalIndex, patternCString, patternLength)){
593 numberOfMatches++;
594 originalIndex += patternLength - 1;
595 }
596 }
597
598 //no matches were found, but that isn't an error, so nothing to do, return
599 if(numberOfMatches == 0){
600 return;
601 }
602
603 (*string) = (ARC_String *)malloc(sizeof(ARC_String));
604 (*string)->length = original->length + (replacementLength - patternLength);
605 (*string)->data = (char *)malloc(sizeof(char *) * original->length + 1);
606
607 for(uint64_t originalIndex = 0, newIndex = 0; originalIndex < original->length; originalIndex++, newIndex++){
608 if(ARC_String_SubstringEqualsCString(original, originalIndex, patternCString, patternLength)){
609 for(uint64_t replacementIndex = 0; replacementIndex < replacementLength; replacementIndex++){
610 (*string)->data[newIndex + replacementIndex] = replacementCString[replacementIndex];
611 }
612
613 originalIndex += patternLength - 1;
614 newIndex += replacementLength - 1;
615 continue;
616 }
617
618 (*string)->data[newIndex] = original->data[originalIndex];
619 }
620
621 (*string)->data[(*string)->length] = '\0';
622
623 //cleanup
624 ARC_String_Destroy(original);
625}
626
627void ARC_String_ReplaceMatchingCStringWithStrlen(ARC_String **string, char *patternCString, char *replacementCString){
628 ARC_String_ReplaceMatchingCString(string, patternCString, strlen(patternCString), replacementCString, strlen(replacementCString));
629}
630
#define ARC_False
Definition bool.h:12
#define ARC_True
Definition bool.h:11
#define ARC_Bool
Definition bool.h:10
int32_t arc_errno
Definition errno.c:5
#define ARC_ERRNO_OVERFLOW
Definition errno.h:10
#define ARC_ERRNO_NULL
Definition errno.h:6
#define ARC_DEBUG_LOG_ERROR(STR)
Definition errno.h:39
#define ARC_ERRNO_DATA
Definition errno.h:7
uint64_t ARC_String_ToUint64_t(ARC_String *string)
converst substring from string to uint64_t
Definition string.c:218
void ARC_String_StripEndsWhitespace(ARC_String **stripped, ARC_String *original)
strips the whitespace from the ends of a string
Definition string.c:437
void ARC_String_RemoveSubstring(ARC_String **newString, ARC_String *original, ARC_String *substring)
copy a subtring from a givin ARC_String
Definition string.c:116
int64_t ARC_String_ToInt64_t(ARC_String *string)
converst substring from string to int64_t
Definition string.c:222
void ARC_String_AppendCStringWithStrlen(ARC_String **string, const char *cstring)
appends to an ARC_String with an ARC_String
Definition string.c:143
void ARC_String_Merge(ARC_String **combined, ARC_String *first, ARC_String *second)
merges two strings together
Definition string.c:485
uint64_t ARC_String_FindCStringWithStrlen(ARC_String *string, const char *cstring)
takes given cstring and gives position of first matching
Definition string.c:273
ARC_Bool ARC_String_EqualsCString(ARC_String *string, const char *cstring, uint64_t length)
check if ARC_String and cstring match
Definition string.c:159
void ARC_String_CopySubstring(ARC_String **substring, ARC_String *original, uint64_t start, uint64_t length)
copy a subtring from a givin ARC_String
Definition string.c:72
uint64_t ARC_String_FindBack(ARC_String *string, ARC_String *substring)
takes a given string, and assigns index and length for position of last matching substring
Definition string.c:277
uint64_t ARC_String_FindBackCStringWithStrlen(ARC_String *string, const char *cstring)
takes a given cstring and give position of last matching
Definition string.c:319
void ARC_String_CreateWithStrlen(ARC_String **string, char *data)
creates ARC_String type with strinlen
Definition string.c:32
void ARC_String_AppendCString(ARC_String **string, const char *cstring, uint64_t length)
appends to an ARC_String with an ARC_String
Definition string.c:130
void ARC_String_Create(ARC_String **string, char *data, uint64_t length)
creates ARC_String type
Definition string.c:9
void ARC_String_CopyReplaceMatching(ARC_String **newString, ARC_String *original, ARC_String *pattern, ARC_String *replacement)
replaces characters in a copy of a string matching the given pattern
Definition string.c:537
uint64_t ARC_String_FindBackCString(ARC_String *string, const char *cstring, uint64_t length)
takes a given cstring and give position of last matching
Definition string.c:298
ARC_Bool ARC_String_EqualsCStringWithStrlen(ARC_String *string, const char *cstring)
check if ARC_String and cstring match
Definition string.c:171
void ARC_String_Copy(ARC_String **copy, ARC_String *original)
copy a ARC_String
Definition string.c:62
void ARC_String_ReplaceMatchingCStringWithStrlen(ARC_String **string, char *patternCString, char *replacementCString)
replaces characters in string matching the given pattern
Definition string.c:627
ARC_Bool ARC_String_SubstringEquals(ARC_String *first, uint64_t offset, ARC_String *second)
check if substring of first equals second string
Definition string.c:175
void ARC_String_Append(ARC_String **string, ARC_String *append)
appends to an ARC_String with an ARC_String
Definition string.c:126
ARC_Bool ARC_String_SubstringEqualsCString(ARC_String *string, uint64_t offset, const char *cstring, uint64_t length)
check if ARC_String and cstring match
Definition string.c:179
uint64_t ARC_String_FindCString(ARC_String *string, const char *cstring, uint64_t length)
takes given cstring and gives position of first matching
Definition string.c:252
void ARC_String_CreateEmpty(ARC_String **string, uint64_t length)
creates an empty ARC_String type, useful if you want to add to the string over time without having to...
Definition string.c:37
void ARC_String_StripWhitespace(ARC_String **stripped, ARC_String *original)
strips whitespace from a ARC_String
Definition string.c:366
ARC_Bool ARC_String_Equals(ARC_String *first, ARC_String *second)
checks if two strings are the same
Definition string.c:147
ARC_Bool ARC_String_IsAlpha(ARC_String *string)
checks if string is alphabetic
Definition string.c:192
void ARC_String_Destroy(ARC_String *string)
destroys ARC_String type
Definition string.c:52
uint64_t ARC_String_Find(ARC_String *string, ARC_String *substring)
takes a given string, and assigns index and length for position of first matching substring
Definition string.c:231
void ARC_String_ReplaceMatchingCString(ARC_String **string, char *patternCString, uint64_t patternLength, char *replacementCString, uint64_t replacementLength)
replaces characters in string matching the given pattern
Definition string.c:580
double ARC_String_ToDouble(ARC_String *string)
converst substring from string to double
Definition string.c:226
void ARC_String_ReplaceWithSubstring(ARC_String **string, uint64_t start, uint64_t length)
replaces a string with a section of itself
Definition string.c:100
void ARC_String_StripEnds(ARC_String **stripped, ARC_String *original, char charToStrip)
strips the ends based on a given char
Definition string.c:323
void ARC_String_RemoveSection(ARC_String **newString, ARC_String *original, uint64_t removeIndex, uint64_t removeLength)
copy a subtring from a givin ARC_String
Definition string.c:499
ARC_Bool ARC_String_IsNumeric(ARC_String *string)
checks if string is made out of only numbers
Definition string.c:208
void ARC_String_ReplaceMatching(ARC_String **string, ARC_String *pattern, ARC_String *replacement)
replaces characters in string matching the given pattern
Definition string.c:525
substring position within a string
Definition string.h:14
uint64_t length
Definition string.h:16
char * data
Definition string.h:15