From 97a4df95a60687d2040853e2215cd46d4e712710 Mon Sep 17 00:00:00 2001 From: Odweta Date: Wed, 7 Feb 2024 11:10:31 +0100 Subject: [PATCH] at least strings and vectors of ints work, not much else though... contributions welcome --- Makefile | 7 ++++ demo.c | 29 ++++++++++----- include/list.h | 4 +++ include/string.h | 2 ++ include/vector.h | 2 ++ src/list.c | 34 ++++++++++++++++++ src/string.c | 94 ++++++++++++++++++++++++++++++++++-------------- src/vector.c | 50 +++++++++++++++++++++++--- 8 files changed, 183 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index 2266f7c..be71c15 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,13 @@ default: demo demo: demo.c libvector.so libfile.so liblist.so libutil.so sudo $(CC) $(CFLAGS) -o $@ $< $(PATCH) $(INCLUDEDIR) $(LIBSPATH) $(LIBS) +trydemo: + @make > /dev/null + @make install > /dev/null + @make > /dev/null + ./demo + @make cleanrepo > /dev/null + libvector.so: src/vector.c sudo $(CC) -c -fpic $< -o /usr/lib/odweta/vector.o sudo $(CC) -shared -o /usr/lib/odweta/$@ /usr/lib/odweta/vector.o diff --git a/demo.c b/demo.c index 97d5192..21c647b 100644 --- a/demo.c +++ b/demo.c @@ -1,21 +1,32 @@ +#include +#include #include #include int main() { - string_t *s = string_from("test string"); - string_t *s2 = string_from("another test"); + vector_t *v = vector_new(INT); - vector_t *v = vector_new(STRING); - - vector_push(v, s); - vector_push(v, s2); + vector_push(v, &(int){33}); + vector_push(v, &(int){35}); + vector_push(v, &(int){34}); vector_print(v); - string_cleanup(s); - string_cleanup(s2); - vector_cleanup(v); + string_t *s = string_new(); + + string_println(s); + + string_push_chars(s, "this is a test"); + + string_println(s); + + compare_e cmp = string_compare(s, string_from("this is a test")); + + printf("cmp -> %s\n", (cmp == EQUAL) ? "equal" : "not equal"); + + string_cleanup(s); + return 0; } diff --git a/include/list.h b/include/list.h index 720ce66..3eaa876 100644 --- a/include/list.h +++ b/include/list.h @@ -30,6 +30,10 @@ void list_cleanup(list_t *self); / void *list_pop(list_t *self); // popping the last value of the list and returning it +void list_deep_copy(list_t *src, list_t *dst); + +vector_t *list_get_at_vector(list_t *self, int index); + void list_insert_at(list_t *self, int index, type_e type, void *element); // inserts an element at a given index void list_remove_at(list_t *self, int index); diff --git a/include/string.h b/include/string.h index 63b8d4a..fe11eb9 100644 --- a/include/string.h +++ b/include/string.h @@ -15,6 +15,8 @@ string_t *string_from(char *chars); // create a new s bool_t string_push_chars(string_t *self, char *chars); // append a char_sequence to a string bool_t string_push(string_t *self, string_t *other); // append a string to a string +void string_deep_copy(string_t *src, string_t *dst); + compare_e string_compare(string_t *left, string_t* right); // compare two strings void string_print(string_t *self); // print a string diff --git a/include/vector.h b/include/vector.h index d3ab42e..59440a9 100644 --- a/include/vector.h +++ b/include/vector.h @@ -35,6 +35,8 @@ void *vector_get_at(vector_t *self, int index); // get an element at the giv void vector_remove_at(vector_t *self, int index); +void vector_deep_copy(vector_t *src, vector_t *dst); + void _vector_print_recursive(vector_t *self, int depth); diff --git a/src/list.c b/src/list.c index 258ed0a..0c7ac51 100644 --- a/src/list.c +++ b/src/list.c @@ -119,6 +119,28 @@ void list_show(list_t *self) { printf("]\n"); } +void list_deep_copy(list_t *src, list_t *dst) { + if (src == NULL) { + dst = NULL; + return; + } + + list_t *dest = list_new(); + if (dest == NULL) { + // Handle memory allocation failure + dst = NULL; + return; + } + + for (int i = 0; i < src->size; i++) { + // Perform deep copy of each element in the source list + vector_t *element_copy = list_get_at_vector(src, i); + list_push(dest, element_copy->type, element_copy); + } + + dst = dest; +} + void list_cleanup(list_t *self) { vector_cleanup((vector_t *)self->data); free(self); @@ -193,3 +215,15 @@ void *list_get_at(list_t *self, int index) { return vector_get_at((vector_t *)vector_get_at(self->data, index), 0); } } + +vector_t *list_get_at_vector(list_t *self, int index) { + if (self->size == 0) { + //fprintf(stderr, "list is empty\n"); + return NULL; + } else if (index >= self->size || index < 0) { + //fprintf(stderr, "index out of range\n"); + return NULL; + } else { + return (vector_t *)vector_get_at(self->data, index); + } +} diff --git a/src/string.c b/src/string.c index 60a3cac..94fc10d 100644 --- a/src/string.c +++ b/src/string.c @@ -3,12 +3,13 @@ #include #include +#include size_t chars_length(char *chars) { int i = 0; while (*(chars + (i++)) != '\0'); - return i; + return i-1; } @@ -16,52 +17,91 @@ size_t chars_length(char *chars) { string_t *string_new() { string_t *s = (string_t *)malloc(sizeof(string_t)); - - s->content = (char *)malloc(sizeof(char)); - if (s->content == NULL) { + if (s == NULL) { return NULL; } - s->content = &(char){'\0'}; + s->content = (char *)malloc(sizeof(char)); + if (s->content == NULL) { + free(s); // Free the previously allocated memory for string_t structure + return NULL; + } + + *(s->content) = '\0'; // Initialize to empty string s->length = 0; return s; } string_t *string_from(char *chars) { + // Allocate memory for the string_t structure string_t *s = (string_t *)malloc(sizeof(string_t)); - s->content = (char *)malloc(sizeof(chars)); + if (s == NULL) { + return NULL; + } + + // Calculate the length of the input string + int len = chars_length(chars); + + // Allocate memory for the content + s->content = (char *)malloc((len + 1) * sizeof(char)); // Add 1 for null terminator if (s->content == NULL) { + free(s); // Free previously allocated memory for string_t structure return NULL; } - int i = 0; - while (*(chars + i) != '\0') { - char *tmp = realloc(s->content, sizeof(s->content) + sizeof(char)); - if (tmp == NULL) { - return NULL; - } - s->content = tmp; - *(s->content + i) = *(chars + i); - i++; + // Copy the characters + for (int i = 0; i < len; i++) { + s->content[i] = chars[i]; } - char *tmp = realloc(s->content, sizeof(s->content) + sizeof(char)); - if (tmp == NULL) { - return NULL; - } - s->content = tmp; - *(s->content + (++i)) = '\0'; - s->length = (int)chars_length(s->content)-1; // -1 because \0 + // Null-terminate the string + s->content[len] = '\0'; + + // Update the length + s->length = len; return s; } +void string_deep_copy(string_t *src, string_t* dst) { + if (src == NULL) { + dst = NULL; + return; + } + + // Allocate memory for the new string + string_t *dest = string_new(); + if (dest == NULL) { + // Handle memory allocation failure + dst = NULL; + return; + } + + // Allocate memory for the content of the new string + dest->content = (char *)malloc((src->length + 1) * sizeof(char)); + if (dest->content == NULL) { + // Handle memory allocation failure + string_cleanup(dest); + dst = NULL; + return; + } + + // Copy the content of the source string + strcpy(dest->content, src->content); + + // Update the length of the new string + dest->length = src->length; + + dst = dest; +} + bool_t string_push_chars(string_t *self, char *chars) { int i = self->length; int j = 0; while (*(chars + j) != '\0') { - char *tmp = realloc(self->content, sizeof(self->content) + sizeof(char)); + // Calculate the new size of the string content, including the additional character + char *tmp = realloc(self->content, (i + 1) * sizeof(char)); if (tmp == NULL) { return FALSE; } @@ -71,7 +111,7 @@ bool_t string_push_chars(string_t *self, char *chars) { j++; } - self->length = (int)chars_length(self->content)-1; + self->length = (int)chars_length(self->content) - 1; return TRUE; } @@ -118,6 +158,8 @@ bool_t string_is_empty(string_t *self) { } void string_cleanup(string_t *self) { - free(self->content); - free(self); + if (self != NULL) { + free(self->content); // Free content + free(self); // Free string_t structure + } } \ No newline at end of file diff --git a/src/vector.c b/src/vector.c index 1f2033e..5da36c2 100644 --- a/src/vector.c +++ b/src/vector.c @@ -196,6 +196,48 @@ vector_t *vector_new(type_e type) { return self; } +void vector_deep_copy(vector_t *src, vector_t *dst) { + if (src->type != dst->type) { + // Handle type mismatch + dst = NULL; + return; + } + + for (int i = 0; i < src->size; i++) { + void *element_copy = NULL; + + switch (src->type) { + case INT: + case FLOAT: + case CHAR: + case BOOL: + element_copy = malloc(sizeof(union { int x; float y; char z; bool_t w; })); // Adjust size as needed + memcpy(element_copy, (src->data) + i, src->element_size); + break; + case STRING: + string_deep_copy((string_t *)(src->data + i * src->element_size), (string_t *)element_copy); + break; + case VECTOR: + vector_deep_copy((vector_t *)(src->data + i * src->element_size), (vector_t *)element_copy); + break; + case LIST: + list_deep_copy((list_t *)(src->data + i * src->element_size), (list_t *)element_copy); + break; + } + + if (element_copy == NULL) { + vector_cleanup(dst); + return; + } + + // Push the deep-copied element into the destination vector + vector_push(dst, element_copy); + + // Free the memory allocated for the element copy + free(element_copy); + } +} + void vector_push(vector_t *self, void* element) { void *tmp = realloc(self->data, (self->size + 1) * self->element_size); self->data = tmp; @@ -217,16 +259,16 @@ void vector_push(vector_t *self, void* element) { break; case VECTOR: // Copy the vector data from the element to the vector - memcpy((vector_t *)(self->data) + self->size, (vector_t *)element, sizeof(vector_t)); + vector_deep_copy((vector_t *)element, ((vector_t *)(self->data) + self->size)); break; case LIST: - memcpy((vector_t*)(self->data) + self->size, (list_t*)element, sizeof(list_t)); + list_deep_copy((list_t*)element, ((list_t *)(self->data) + self->size)); break; case BOOL: *((bool_t *)(self->data) + self->size) = *((bool_t *)element); break; case STRING: - memcpy((vector_t*)(self->data) + self->size, (string_t*)element, sizeof(string_t)); + string_deep_copy((string_t *)element, ((string_t *)(self->data) + self->size)); break; default: return; @@ -250,7 +292,7 @@ void *vector_pop(vector_t *self) { if (self->capacity == 0) self->capacity = 1; - return (self->data) + self->size-1; + return (self->data) + self->size; } else { // cannot pop when there is no value in the vector return NULL;