dynamic string implemented
MMakefile
| @@ -1,3 +1,3 @@ | |||
|---|---|---|---|
| 1 | 1 | all: | |
| 2 | - | gcc -Og -g -march=native -shared -fPIC -fstrict-aliasing vector.c -o cutils.so -flto \ | |
| 2 | + | gcc -Og -g -march=native -shared -fPIC -fstrict-aliasing vector.c dyn_string.c -o cutils.so -flto \ | |
| 3 | 3 | -Wall -Werror -Wpedantic -Wnull-dereference -Wshadow -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wstrict-overflow=5 -Wunreachable-code -Wno-unused-parameter | |
Mcutils.h
| @@ -1,4 +1,5 @@ | |||
|---|---|---|---|
| 1 | 1 | #ifndef CUTILS_H | |
| 2 | 2 | #define CUTILS_H | |
| 3 | 3 | #include <vector.h> | |
| 4 | + | #include <dyn_string.h> | |
| 4 | 5 | #endif //CUTILS_H | |
Adyn_string.c
| @@ -0,0 +1,105 @@ | |||
|---|---|---|---|
| 1 | + | #include "dyn_string.h" | |
| 2 | + | ||
| 3 | + | String* new_string(void) | |
| 4 | + | { | |
| 5 | + | String* string = malloc(sizeof(*string)); | |
| 6 | + | if(!string) | |
| 7 | + | return NULL; | |
| 8 | + | string->chars = calloc(sizeof(*string->chars)*STRING_DEFAULT_SIZE,1); | |
| 9 | + | if(!string->chars) | |
| 10 | + | { | |
| 11 | + | free(string); | |
| 12 | + | return NULL; | |
| 13 | + | } | |
| 14 | + | string->length = 0; | |
| 15 | + | string->capacity = STRING_DEFAULT_SIZE; | |
| 16 | + | ||
| 17 | + | return string; | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | bool string_append(String* string, char character) | |
| 21 | + | { | |
| 22 | + | if(!string_adjust_size(string, ++string->length)) | |
| 23 | + | return false; | |
| 24 | + | string->chars[string->length-1] = character; | |
| 25 | + | return true; | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | void string_remove(String* string, size_t index) | |
| 29 | + | { | |
| 30 | + | if(index < string->length) | |
| 31 | + | { | |
| 32 | + | memmove(string->chars+index, string->chars+index+1, (string->length-index-1)*sizeof(*string->chars)); | |
| 33 | + | string->length--; | |
| 34 | + | } | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | bool string_insert(String* string, size_t index, char character) | |
| 38 | + | { | |
| 39 | + | if(!string_adjust_size(string, string->length)) | |
| 40 | + | return false; | |
| 41 | + | ||
| 42 | + | memmove(string->chars+index+1, string->chars+index, (string->length-index)*sizeof(*string->chars)); | |
| 43 | + | string->chars[index] = character; | |
| 44 | + | string->length++; | |
| 45 | + | return true; | |
| 46 | + | } | |
| 47 | + | ||
| 48 | + | char string_at(const String* string, size_t index) | |
| 49 | + | { | |
| 50 | + | if(index >= string->length) | |
| 51 | + | return '\0'; | |
| 52 | + | else | |
| 53 | + | return string->chars[index]; | |
| 54 | + | } | |
| 55 | + | ||
| 56 | + | bool string_concat(String* string, String* other) | |
| 57 | + | { | |
| 58 | + | if(!string_adjust_size(string,string->length+other->length-1)) | |
| 59 | + | return false; | |
| 60 | + | memcpy(string->chars+string->length,other->chars,other->length); | |
| 61 | + | return true; | |
| 62 | + | } | |
| 63 | + | ||
| 64 | + | FindReturn string_find_char(const String* haystack, const char needle) | |
| 65 | + | { | |
| 66 | + | FindReturn ret; | |
| 67 | + | for(size_t i = 0; i < haystack->length; i++) | |
| 68 | + | { | |
| 69 | + | if(haystack->chars[i] == needle) | |
| 70 | + | { | |
| 71 | + | ret.found = true; | |
| 72 | + | ret.index = i; | |
| 73 | + | return ret; | |
| 74 | + | } | |
| 75 | + | } | |
| 76 | + | ret.found = false; | |
| 77 | + | return ret; | |
| 78 | + | } | |
| 79 | + | ||
| 80 | + | bool string_adjust_size(String* string, size_t size) | |
| 81 | + | { | |
| 82 | + | while(string->capacity < size) | |
| 83 | + | { | |
| 84 | + | char* tmp = string->chars; | |
| 85 | + | string->chars = realloc(string->chars, string->capacity*2*(sizeof(*string->chars))); | |
| 86 | + | if(!string->chars) | |
| 87 | + | { | |
| 88 | + | string->chars = tmp; | |
| 89 | + | return false; | |
| 90 | + | } | |
| 91 | + | string->capacity *= 2; | |
| 92 | + | } | |
| 93 | + | while(string->capacity > (size*2)) | |
| 94 | + | { | |
| 95 | + | char* tmp = string->chars; | |
| 96 | + | string->chars = realloc(string->chars, string->capacity/2*(sizeof(*string->chars))); | |
| 97 | + | if(!string->chars) | |
| 98 | + | { | |
| 99 | + | string->chars = tmp; | |
| 100 | + | return false; | |
| 101 | + | } | |
| 102 | + | string->capacity /= 2; | |
| 103 | + | } | |
| 104 | + | return true; | |
| 105 | + | } | |
Adyn_string.h
| @@ -0,0 +1,32 @@ | |||
|---|---|---|---|
| 1 | + | #ifndef DYN_STRING_H | |
| 2 | + | #define DYN_STRING_H | |
| 3 | + | #define STRING_DEFAULT_SIZE 8 | |
| 4 | + | #include <stdint.h> | |
| 5 | + | #include <stdlib.h> | |
| 6 | + | #include <string.h> | |
| 7 | + | #include <stdbool.h> | |
| 8 | + | ||
| 9 | + | typedef struct String | |
| 10 | + | { | |
| 11 | + | char* chars; | |
| 12 | + | size_t capacity; | |
| 13 | + | size_t length; | |
| 14 | + | } String; | |
| 15 | + | ||
| 16 | + | typedef struct FindReturn | |
| 17 | + | { | |
| 18 | + | bool found; | |
| 19 | + | size_t index; //if found is false, this contains rubbish | |
| 20 | + | } FindReturn; | |
| 21 | + | ||
| 22 | + | String* new_string(void); | |
| 23 | + | char string_at(const String* string, size_t index); | |
| 24 | + | bool string_append(String* string, char item); | |
| 25 | + | void string_remove(String* string, size_t index); | |
| 26 | + | bool string_adjust_size(String* string, size_t size); | |
| 27 | + | FindReturn string_find_char(const String* haystack, const char needle); | |
| 28 | + | bool string_insert(String* string, size_t index, char character); | |
| 29 | + | bool string_concat(String* string, String* other); | |
| 30 | + | ||
| 31 | + | ||
| 32 | + | #endif //DYN_STRING_H | |
Mvector.c
| @@ -12,7 +12,7 @@ Vector* new_vector(void) | |||
|---|---|---|---|
| 12 | 12 | return NULL; | |
| 13 | 13 | } | |
| 14 | 14 | vector->length = 0; | |
| 15 | - | vector->capacity = 4; | |
| 15 | + | vector->capacity = VECTOR_DEFAULT_SIZE; | |
| 16 | 16 | ||
| 17 | 17 | return vector; | |
| 18 | 18 | } | |
| @@ -84,7 +84,7 @@ FindReturn vector_find(const Vector* haystack, const void* needle, bool (*cmp)(c | |||
|---|---|---|---|
| 84 | 84 | ||
| 85 | 85 | bool vector_insert(Vector* vector, size_t index, void* item) | |
| 86 | 86 | { | |
| 87 | - | if(!vector_adjust_size(vector, ++vector->length)) | |
| 87 | + | if(!vector_adjust_size(vector, vector->length)) | |
| 88 | 88 | return false; | |
| 89 | 89 | ||
| 90 | 90 | memmove(vector->items+index+1, vector->items+index, (vector->length-index)*sizeof(*vector->items)); | |