From e40b61a21b7b2f54c6af9891dbbff23db91daaf8 Mon Sep 17 00:00:00 2001 From: Odweta Date: Mon, 5 Feb 2024 00:16:25 +0100 Subject: [PATCH] refactoring done, small bugfixes included, vectors and lists of non-primitive types are not working though --- demo.c | 20 +- include/file.h | 33 +-- include/list.h | 24 +- include/util.h | 27 +- include/vector.h | 44 ++- src/file.c | 240 ++++++++--------- src/list.c | 333 ++++++++--------------- src/util.c | 26 +- src/vector.c | 681 +++++++++++++++++++++++------------------------ 9 files changed, 631 insertions(+), 797 deletions(-) diff --git a/demo.c b/demo.c index f6d7bb5..4761cce 100644 --- a/demo.c +++ b/demo.c @@ -1,21 +1,15 @@ -#include +#include int main() { - //printf("before init\n"); - string_t *s = string_from("test string"); + vector_t *v = vector_new(INT); - //printf("before 1st println\n"); - string_println(s); + vector_push(v, &(int){1}); + vector_push(v, &(int){2}); + vector_push(v, &(int){3}); - //printf("before pushing chars\n"); - string_push_chars(s, " appended"); + vector_print(v); - //printf("before 2nd println\n"); - string_println(s); + vector_cleanup(v); - //printf("before cleanup\n"); - string_cleanup(s); - - //printf("before end\n"); return 0; } diff --git a/include/file.h b/include/file.h index 036f82d..f345478 100644 --- a/include/file.h +++ b/include/file.h @@ -2,38 +2,39 @@ #define FILE_H #include +#include typedef struct { - char* path; // the file descriptor + char *path; // the file descriptor int length; // line count - vector_t* lines; // 2d array of chars + vector_t *lines; // 2d array of chars int not_newline_terminated; // bool: 1 = true, 0 = false } file_t; -file_t* fileInit(char* path); // initialization function +file_t *file_new(char *path); // initialization function -void fileCleanup(file_t* f); // just to be memory safe... +void file_cleanup(file_t *this); // just to be memory safe... -void filePrint(file_t* f); // prints the file as a string +void file_print(file_t *this); // prints the file as a string -char* fileToString(file_t* f); // returns a string with the file contents +char *file_to_string(file_t *this); // returns a string with the file contents -void fileWriteln(file_t* f, char* payload); // appends a given string to the file on a newline +void file_writeln(file_t *this, char *payload); // appends a given string to the file on a newline -void fileWrite(file_t* f, char* payload); // appends a given string to the file (not on a newline!) +void file_write(file_t *this, char *payload); // appends a given string to the file (not on a newline!) -void fileCopy(file_t* src, char* dst); // copy file src into file dst +void file_copy(file_t* src, char *dst); // copy file src into file dst -void fileDelete(file_t* f); // deletes a file +void file_delete(file_t *this); // deletes a file -void fileMove(file_t* src, char* dst); // moves/renames a file +void file_move(file_t* src, char *dst); // moves/renames a file -int fileExists(file_t* f); // 1 = yes, 0 = no +bool file_exists(file_t *this); // 1 = yes, 0 = no -void fileCreateEmpty(char* path); // create an empty file with the given name +void file_create(char *path); // create an empty file with the given name -void fileNumberLines(file_t* f); // prepend line numbers in front of each line in a file +void file_number_lines(file_t *this); // prepend line numbers in front of each line in a file -int fileCountWords(file_t* f); // counts the number of words in a file +int file_count_words(file_t *this); // counts the number of words in a file -#endif +#endif // FILE_H diff --git a/include/list.h b/include/list.h index 8b0b94a..82eaa71 100644 --- a/include/list.h +++ b/include/list.h @@ -16,26 +16,26 @@ typedef struct { size_t size; // number of elements that are inside the list size_t capacity; // how many elements can be put inside - vector_t* data; // vector of vectors + vector_t *data; // vector of vectors } list_t; -list_t* listInit(); // returns a new list +list_t *list_new(); // returns a new list -void listPush(list_t* l, dataType_e type, void* element); // appends an element at the end of a list +void list_push(list_t *this, type_e type, void *element); // appends an element at the end of a list -void listPrint(list_t* l); // prints a list -void _listPrintRecursive(list_t* l, int depth); +void list_show(list_t *this); // prints a list +void _list_print_recursive(list_t *this, int depth); -void listCleanup(list_t* l); // freeing pointers +void list_cleanup(list_t *this); // freeing pointers -void* listPop(list_t* l); // popping the last value of the list and returning it +void *list_pop(list_t *this); // popping the last value of the list and returning it -void listInsertAt(list_t* l, int index, dataType_e type, void* element); // inserts an element at a given index +void list_insert_at(list_t *this, int index, type_e type, void *element); // inserts an element at a given index -void listRemoveAt(list_t* l, int index); +void list_remove_at(list_t *this, int index); -void listSetAt(list_t* l, int index, dataType_e type, void* element); +void list_set_at(list_t *this, int index, type_e type, void *element); -void* listGetAt(list_t* l, int index); +void *list_get_at(list_t *this, int index); -#endif \ No newline at end of file +#endif // LIST_H \ No newline at end of file diff --git a/include/util.h b/include/util.h index 429b9c9..b81deec 100644 --- a/include/util.h +++ b/include/util.h @@ -1,7 +1,9 @@ #ifndef UTIL_H #define UTIL_H -#include +#undef bool + +typedef enum { false, true } bool; typedef enum { LESS, @@ -15,18 +17,19 @@ typedef enum { typedef long unsigned int size_t; typedef enum { - INT = 0, - FLOAT = 1, - CHAR = 2, - VECTOR = 3, // allows for multi-dimensional arrays - LIST = 4, - BOOL = 5 -} dataType_e; + INT, + FLOAT, + CHAR, + VECTOR, // allows for multi-dimensional arrays + LIST, + BOOL, + STRING +} type_e; -char* intToString(int x); // convert an int into a string +char* int_to_string(int x); // convert an int into a string -long pow(int x, int n); // x^n +long pow(int x, int n); // x^n -int maxLowerPowerOf10(int x); // biggest power of 10 that is < x +int max_lower_power_of_10(int x); // biggest power of 10 that is < x -#endif +#endif // UTIL_H diff --git a/include/vector.h b/include/vector.h index f0ec003..0835d72 100644 --- a/include/vector.h +++ b/include/vector.h @@ -4,51 +4,39 @@ #include typedef struct { - dataType_e type; + type_e type; size_t size; size_t capacity; - size_t elementSize; - void* data; + size_t element_size; + void *data; } vector_t; -vector_t* -vectorInit(dataType_e dataType); // size gets determined by the dataType and the capacity starts at 1 and x1.5 every time the vector gets filled up +vector_t *vector_new(type_e type); // size gets determined by the dataType and the capacity starts at 1 and x1.5 every time the vector gets filled up -void -vectorReset(vector_t* v); // sets the vector to its original state +void vector_reset(vector_t *this); // sets the vector to its original state -void* -vectorPop(vector_t* v); // remove one value from the end of the vector and return it +void *vector_pop(vector_t *this); // remove one value from the end of the vector and return it -void -vectorPush(vector_t* v, void* element); // push one value at the end of the vector +void vector_push(vector_t *this, void *element); // push one value at the end of the vector -void -vectorCleanup(vector_t* v); // freeing pointers +void vector_cleanup(vector_t *this); // freeing pointers -void -vectorPrint(vector_t* v); // shows the vector +void vector_print(vector_t *this); // shows the vector -void -vectorPrintAsString(vector_t* v); // show the vector as a string if the v->type is CHAR +void vector_print_as_string(vector_t *this); // show the vector as a string if the v->type is CHAR -void -vectorInsertAt(vector_t* v, int index, void* element); // inserts an element 'element' at index 'index' +void vector_insert_at(vector_t *this, int index, void *element); // inserts an element 'element' at index 'index' -void -vectorSetAt(vector_t* v, int index, void* element); // set an element's value at a given index +void vector_set_at(vector_t *this, int index, void *element); // set an element's value at a given index -char* -vectorToString(vector_t* v); // convert the vector into a regular string +char *vector_to_string(vector_t *this); // convert the vector into a regular string -void* -vectorGetAt(vector_t* v, int index); // get an element at the given index +void *vector_get_at(vector_t *this, int index); // get an element at the given index -void -vectorRemoveAt(vector_t* v, int index); +void vector_remove_at(vector_t *this, int index); -void _printVectorRecursive(vector_t* v, int depth); +void _vector_print_recursive(vector_t *this, int depth); #endif diff --git a/src/file.c b/src/file.c index 075b82a..58be7f9 100644 --- a/src/file.c +++ b/src/file.c @@ -5,14 +5,13 @@ #include #include -int -fileCountLines(file_t* f) { +int file_count_lines(file_t *this) { char ch; int lines = 0; - FILE* fd = fopen(f->path, "r"); - if (!fd) { - fprintf(stderr, "unable to count lines in file %s\n", f->path); - exit(EXIT_FAILURE); + + FILE *fd = fopen(this->path, "r"); + if (fd == NULL) { + return -1; } while ((ch = fgetc(fd)) != EOF) { @@ -26,118 +25,108 @@ fileCountLines(file_t* f) { return lines; } -void -_fileLoadLines(file_t* f) { +void _file_load_lines(file_t *this) { char ch; - FILE* fd = fopen(f->path, "r"); - if (!fd) { - fprintf(stderr, "unable to open file %s with mode \"r\"\n", f->path); + FILE *fd = fopen(this->path, "r"); + if (fd == NULL) { fclose(fd); - fileCleanup(f); - exit(EXIT_FAILURE); + file_cleanup(this); + return; } char prev; - for (int i = 0; i < f->length; i++) { - vector_t* line = vectorInit(CHAR); // Create a new vector for each line + for (int i = 0; i < this->length; i++) { + vector_t *line = vector_new(CHAR); // Create a new vector for each line while ((ch = fgetc(fd)) != '\n' && ch != EOF) { - vectorPush(line, &ch); + vector_push(line, &ch); } // Skip the newline character if it exists if (ch == '\n') { - char* empty = ""; - vectorPush(line, empty); + char *empty = ""; + vector_push(line, empty); } - vectorPush(f->lines, line); + vector_push(this->lines, line); prev = ch; - // Don't free the line vector here, as it's now owned by the f->lines vector + // Don't free the line vector here, as it's now owned by the this->lines vector } if (prev != '\n') { - f->not_newline_terminated = 1; // \n is NOT at the end of a file + this->not_newline_terminated = 1; // \n is NOT at the end of a file } else { - f->not_newline_terminated = 0; // \n IS at the end of a file + this->not_newline_terminated = 0; // \n IS at the end of a file } fclose(fd); } -char* -fileToString(file_t* f) { - return (char *)vectorToString(f->lines); +char *file_to_string(file_t *this) { + return vector_to_string(this->lines); } -int -fileExists(file_t* f) { - FILE* fd = fopen(f->path, "r"); - if (!fd) { - return 0; // file does not exist - } else { - return 1; // file exists - } +bool file_exists(file_t *this) { + FILE *fd = fopen(this->path, "r"); + + bool retval = (fd == NULL) ? false : true; + fclose(fd); + + return retval; } -void -fileCreateEmpty(char* path) { +void file_create(char *path) { fclose(fopen(path, "w")); } -file_t* -fileInit(char* path) { - file_t* f = malloc(sizeof(file_t)); - if (!f) { - fprintf(stderr, "failed to allocate memory for the file\n"); - exit(EXIT_FAILURE); +file_t *file_new(char *path) { + file_t *this = (file_t *)malloc(sizeof(file_t)); + if (this == NULL) { + return NULL; } - f->path = path; + this->path = path; - if (fileExists(f) == 0) { - // if file 'f' does not exist - fileCreateEmpty(f->path); - return fileInit(f->path); + if (file_exists(this) == false) { + // if file 'this' does not exist + file_create(this->path); + return file_new(this->path); } - f->length = fileCountLines(f); + this->length = file_count_lines(this); - f->lines = vectorInit(VECTOR); // vector of vectors of chars = vector of strings - _fileLoadLines(f); + this->lines = vector_new(VECTOR); // vector of vectors of chars = vector of strings + _file_load_lines(this); - return f; + return this; } -void -fileCleanup(file_t* f) { - if (f->not_newline_terminated == 1) { - FILE* fd = fopen(f->path, "a"); +void file_cleanup(file_t *this) { + if (this->not_newline_terminated == 1) { + FILE *fd = fopen(this->path, "a"); fprintf(fd, "\n"); fclose(fd); - f->not_newline_terminated = 0; // just for piece of mind + this->not_newline_terminated = 0; // just for piece of mind } - vectorCleanup(f->lines); - free(f); + + vector_cleanup(this->lines); + free(this); } -void -filePrint(file_t* f) { - for (int i = 0; i < f->length; i++) { - vectorPrintAsString((vector_t *)vectorGetAt(f->lines, i)); +void file_print(file_t *this) { + for (int i = 0; i < this->length; i++) { + vector_print_as_string((vector_t *)vector_get_at(this->lines, i)); } } -void -fileWriteln(file_t* f, char* payload) { - FILE* fd = fopen(f->path, "a"); - if (!fd) { - fprintf(stderr, "unable to open file %s with mode \"a\"\n", f->path); +void file_writeln(file_t *this, char *payload) { + FILE *fd = fopen(this->path, "a"); + if (fd == NULL) { fclose(fd); - fileCleanup(f); - exit(EXIT_FAILURE); + file_cleanup(this); + return; } fprintf(fd, "%s\n", payload); @@ -145,29 +134,28 @@ fileWriteln(file_t* f, char* payload) { fclose(fd); // Update the file structure without re-initializing - if (f->not_newline_terminated == 0) { - vector_t* line = vectorInit(CHAR); + if (this->not_newline_terminated == 0) { + vector_t *line = vector_new(CHAR); for (int i = 0; i < strlen(payload); i++) { - vectorPush(line, &payload[i]); + vector_push(line, &payload[i]); } - vectorPush(f->lines, line); - f->length++; - f->not_newline_terminated = 0; - } else if (f->not_newline_terminated == 1) { + vector_push(this->lines, line); + this->length++; + this->not_newline_terminated = 0; + } else if (this->not_newline_terminated == 1) { for (int i = 0; i < strlen(payload); i++) { - vectorPush((vector_t *)vectorGetAt(f->lines, f->length-1), &payload[i]); + vector_push((vector_t *)vector_get_at(this->lines, this->length-1), &payload[i]); } - f->not_newline_terminated = 0; + this->not_newline_terminated = 0; } } -void -fileWrite(file_t* f, char* payload) { - FILE* fd = fopen(f->path, "a"); - if (!fd) { - fprintf(stderr, "unable to open file %s with mode \"a\"\n", f->path); +void file_write(file_t *this, char *payload) { + FILE *fd = fopen(this->path, "a"); + if (fd) { + fprintf(stderr, "unable to open file %s with mode \"a\"\n", this->path); fclose(fd); - fileCleanup(f); + file_cleanup(this); exit(EXIT_FAILURE); } @@ -176,28 +164,26 @@ fileWrite(file_t* f, char* payload) { fclose(fd); // Update the file structure without re-initializing - vector_t* line = vectorInit(CHAR); + vector_t *line = vector_new(CHAR); for (int i = 0; i < strlen(payload); i++) { - vectorPush(line, &payload[i]); + vector_push(line, &payload[i]); } - vectorPush(f->lines, line); - f->length++; - f->not_newline_terminated = 1; + vector_push(this->lines, line); + this->length++; + this->not_newline_terminated = 1; } -void -fileCopy(file_t* src, char* dst) { - FILE* fd = fopen(dst, "w"); - if (!fd) { - fprintf(stderr, "could not open file for writing\n"); +void file_copy(file_t *src, char *dst) { + FILE *fd = fopen(dst, "w"); + if (fd == NULL) { fclose(fd); - exit(EXIT_FAILURE); + return; } char ch; for (int i = 0; i < src->length; i++) { - for (int j = 0; j < ((vector_t *)vectorGetAt(src->lines, i))->size; j++) { - ch = *((char *)vectorGetAt((vector_t *)vectorGetAt(src->lines, i), j)); + for (int j = 0; j < ((vector_t *)vector_get_at(src->lines, i))->size; j++) { + ch = *((char *)vector_get_at((vector_t *)vector_get_at(src->lines, i), j)); fprintf(fd, "%c", ch); } fprintf(fd, "\n"); @@ -206,68 +192,56 @@ fileCopy(file_t* src, char* dst) { fclose(fd); } -void -fileDelete(file_t* f) { - int retval = remove(f->path); // try to remove/delete a file - - if (retval != 0) { // if it could not do so, raise an error - fprintf(stderr, "could not delete file\n"); - // fileCleanup(f); // don't know if this is necessary... :shrug: - // exit(EXIT_FAILURE); - } - - fileCleanup(f); +void file_delete(file_t *this) { + if (remove(this->path) == 0) + file_cleanup(this); } -void -fileMove(file_t* src, char* dst) { - fileCopy(src, dst); +void file_move(file_t *src, char *dst) { + file_copy(src, dst); - fileDelete(src); + file_delete(src); } -void -fileNumberLines(file_t* f) { - FILE* fd = fopen(f->path, "w"); - if (!fd) { - fprintf(stderr, "could not open file for writing\n"); +void file_number_lines(file_t *this) { + FILE *fd = fopen(this->path, "w"); + if (fd == NULL) { fclose(fd); - exit(EXIT_FAILURE); + return; } - int mlp = maxLowerPowerOf10(f->length); + int mlp = max_lower_power_of_10(this->length); - for (int i = 0; i < f->length; i++) { + for (int i = 0; i < this->length; i++) { // print to the file descriptor - fprintf(fd, "%d %s\n", i+1, (char*)vectorToString((vector_t *)vectorGetAt(f->lines, i))); + fprintf(fd, "%d %s\n", i+1, vector_to_string((vector_t *)vector_get_at(this->lines, i))); - // print to f->lines - vectorInsertAt((vector_t*)vectorGetAt(f->lines, i), 0, &(char){' '}); - char* string = intToString(i+1); + // print to this->lines + vector_insert_at((vector_t*)vector_get_at(this->lines, i), 0, &(char){' '}); + char *string = int_to_string(i+1); for (int j = strlen(string)-1; j >= 0; j--) { - vectorInsertAt((vector_t*)vectorGetAt(f->lines, i), 0, &(char){string[j]}); + vector_insert_at((vector_t*)vector_get_at(this->lines, i), 0, &(char){string[j]}); } // prepend the correct amount of ' ' - for (int j = 0; j < strlen(intToString(mlp))-strlen(intToString(i+1)); j++) { - vectorInsertAt((vector_t*)vectorGetAt(f->lines, i), 0, &(char){' '}); + for (int j = 0; j < strlen(int_to_string(mlp))-strlen(int_to_string(i+1)); j++) { + vector_insert_at((vector_t*)vector_get_at(this->lines, i), 0, &(char){' '}); } } fclose(fd); } -int -fileCountWords(file_t* f) { +int file_count_words(file_t *this) { int num_words = 0; char prev; - for (int i = 0; i < f->length; i++) { - for (int j = 0; j < ((vector_t*)vectorGetAt(f->lines, i))->size; j++) { - char ch = *((char*)vectorGetAt((vector_t*)vectorGetAt(f->lines, i), j)); + for (int i = 0; i < this->length; i++) { + for (int j = 0; j < ((vector_t*)vector_get_at(this->lines, i))->size; j++) { + char ch = *((char*)vector_get_at((vector_t*)vector_get_at(this->lines, i), j)); if ( (ch == ' ' && prev != ' ') || - (i == f->length-1 && j == ((vector_t*)vectorGetAt(f->lines, i))->size-1) || - (j == ((vector_t*)vectorGetAt(f->lines, i))->size-1 && j != 0) + (i == this->length-1 && j == ((vector_t*)vector_get_at(this->lines, i))->size-1) || + (j == ((vector_t*)vector_get_at(this->lines, i))->size-1 && j != 0) ) { num_words++; } diff --git a/src/list.c b/src/list.c index 4af6a2b..e3a0a65 100644 --- a/src/list.c +++ b/src/list.c @@ -1,152 +1,140 @@ #include #include #include +#include #include #include #include #define init_error_exit(l) fprintf(stderr, "could not init list\n"); free(l); exit(EXIT_FAILURE) -list_t* -listInit() { - list_t* l = malloc(sizeof(list_t)); - if (!l) { - init_error_exit(l); +list_t *list_new() { + list_t *this = (list_t *)malloc(sizeof(list_t)); + if (this == NULL) { + init_error_exit(this); } - l->data = (vector_t *)vectorInit(VECTOR); - if (!l->data) { - init_error_exit(l); + this->data = (vector_t *)vector_new(VECTOR); + if (this->data == NULL) { + init_error_exit(this); } - l->size = 0; - l->capacity = 1; + this->size = 0; + this->capacity = 1; - return l; + return this; } -void -listPush(list_t* l, dataType_e type, void* element) { - vector_t* newVec; - switch (type) { - case INT: - newVec = vectorInit(INT); - vectorPush(newVec, element); - vectorPush((vector_t *)l->data, newVec); - break; - case FLOAT: - newVec = vectorInit(FLOAT); - vectorPush(newVec, element); - vectorPush((vector_t *)l->data, newVec); - break; - case CHAR: - newVec = vectorInit(CHAR); - vectorPush(newVec, element); - vectorPush((vector_t *)l->data, newVec); - break; - case VECTOR: - newVec = vectorInit(VECTOR); - vectorPush(newVec, element); - vectorPush((vector_t *)l->data, newVec); - break; - case LIST: - newVec = vectorInit(LIST); - vectorPush(newVec, element); - vectorPush((vector_t *)l->data, newVec); - break; - default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); - } +void list_push(list_t *this, type_e type, void *element) { + vector_t *new_vec = vector_new(type); - l->size += 1; - if (l->size == l->capacity) { - l->capacity *= 2; + vector_push(new_vec, element); + vector_push((vector_t *)this->data, new_vec); + + this->size += 1; + if (this->size == this->capacity) { + this->capacity *= 2; } } -void -_listPrintRecursive(list_t* l, int depth) { - fprintf(stdout, "["); +void _list_print_recursive(list_t *this, int depth) { + printf("["); + int i; - for (i = 0; i < l->size; i++) { - vector_t *ithVec = (vector_t *)vectorGetAt((vector_t *)l->data, i); + for (i = 0; i < this->size; i++) { + vector_t *ith_vec = (vector_t *)vector_get_at((vector_t *)this->data, i); - switch (ithVec->type) { + switch (ith_vec->type) { case INT: - printf("%d", *((int *)vectorGetAt(ithVec, 0))); + printf("%d", *((int *)vector_get_at(ith_vec, 0))); break; case FLOAT: - printf("%f", *((float *)vectorGetAt(ithVec, 0))); + printf("%f", *((float *)vector_get_at(ith_vec, 0))); break; case CHAR: - printf("'%c'", *((char *)vectorGetAt(ithVec, 0))); + printf("'%c'", *((char *)vector_get_at(ith_vec, 0))); break; case VECTOR: - _printVectorRecursive(ithVec->data, 0); + _vector_print_recursive(ith_vec->data, 0); break; case LIST: - _listPrintRecursive(ithVec->data, 0); + _list_print_recursive(ith_vec->data, 0); + break; + case BOOL: + printf("%s", (*((bool *)vector_get_at(ith_vec, 0)) == false) ? "false" : "true"); + break; + case STRING: + string_print((string_t *)vector_get_at(ith_vec, 0)); break; } - if (i < l->size - 1) { - fprintf(stdout, ", "); + if (i < this->size - 1) { + printf(", "); } } - fprintf(stdout, "]"); + + printf("]"); + if (depth != 0) { - fprintf(stdout, "\n"); + printf("\n"); } } -void -listPrint(list_t* l) { - fprintf(stdout, "["); - int i; - for (i = 0; i < l->size; i++) { - vector_t *ithVec = (vector_t *)vectorGetAt((vector_t *)l->data, i); +void list_show(list_t *this) { + printf("["); - switch (ithVec->type) { + int i; + for (i = 0; i < this->size; i++) { + vector_t *ith_vec = (vector_t *)vector_get_at((vector_t *)this->data, i); + + switch (ith_vec->type) { case INT: - printf("%d", *((int *)vectorGetAt(ithVec, 0))); + printf("%d", *((int *)vector_get_at(ith_vec, 0))); break; case FLOAT: - printf("%f", *((float *)vectorGetAt(ithVec, 0))); + printf("%f", *((float *)vector_get_at(ith_vec, 0))); break; case CHAR: - printf("'%c'", *((char *)vectorGetAt(ithVec, 0))); + printf("'%c'", *((char *)vector_get_at(ith_vec, 0))); break; case VECTOR: - _printVectorRecursive(ithVec->data, 0); + _vector_print_recursive(ith_vec->data, 0); break; case LIST: - _listPrintRecursive(ithVec->data, 0); + _list_print_recursive(ith_vec->data, 0); + break; + case BOOL: + printf("%s", (*((bool *)vector_get_at(ith_vec, 0)) == false) ? "false" : "true"); + break; + case STRING: + string_print((string_t *)vector_get_at(ith_vec, 0)); break; } - if (i < l->size - 1) { - fprintf(stdout, ", "); + if (i < this->size - 1) { + printf(", "); } } - fprintf(stdout, "]\n"); + + printf("]\n"); } -void -listCleanup(list_t* l) { - vectorCleanup((vector_t *)l->data); - free(l); +void list_cleanup(list_t *this) { + vector_cleanup((vector_t *)this->data); + free(this); } -void* -listPop(list_t* l) { - if (l->size != 0) { - vector_t *first_ptr = (vector_t *)vectorPop((vector_t *)l->data); - void *ptr = vectorPop(first_ptr); - l->size -= 1; +void *list_pop(list_t *this) { + if (this->size != 0) { + vector_t *first_ptr = (vector_t *)vector_pop((vector_t *)this->data); + void *ptr = vector_pop(first_ptr); + this->size -= 1; - if (l->size <= l->capacity / 2) l->capacity /= 2; - if (l->capacity == 0) l->capacity = 1; + if (this->size <= this->capacity / 2) + this->capacity /= 2; + + if (this->capacity == 0) + this->capacity = 1; return ptr; } else { @@ -155,150 +143,53 @@ listPop(list_t* l) { } } -void -listInsertAt(list_t* l, int index, dataType_e type, void* element) { - if (l->size == 0) { - switch (type) { - case INT: - listPush(l, INT, element); - break; - case FLOAT: - listPush(l, FLOAT, element); - break; - case CHAR: - listPush(l, CHAR, element); - break; - case VECTOR: - listPush(l, VECTOR, element); - break; - case LIST: - listPush(l, LIST, element); - break; - } +void list_insert_at(list_t *this, int index, type_e type, void *element) { + if (this->size == 0) { + list_push(this, type, element); } else { - vector_t* newVec; - switch (type) { - case INT: - newVec = vectorInit(INT); - vectorPush(newVec, element); - vectorInsertAt((vector_t *)l->data, index, newVec); - break; - case FLOAT: - newVec = vectorInit(FLOAT); - vectorPush(newVec, element); - vectorInsertAt((vector_t *)l->data, index, newVec); - break; - case CHAR: - newVec = vectorInit(CHAR); - vectorPush(newVec, element); - vectorInsertAt((vector_t *)l->data, index, newVec); - break; - case VECTOR: - newVec = vectorInit(VECTOR); - vectorPush(newVec, element); - vectorInsertAt((vector_t *)l->data, index, newVec); - break; - case LIST: - newVec = vectorInit(LIST); - vectorPush(newVec, element); - vectorInsertAt((vector_t *)l->data, index, newVec); - break; - default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); - } + vector_t* new_vec = vector_new(type); + + vector_push(new_vec, element); + vector_insert_at((vector_t *)this->data, index, new_vec); - l->size += 1; - if (l->size == l->capacity) { - l->capacity *= 2; + this->size += 1; + if (this->size == this->capacity) { + this->capacity *= 2; } } } -void -listRemoveAt(list_t* l, int index) { - vectorRemoveAt(l->data, index); - l->size -= 1; - if (l->size == l->capacity) { - l->capacity /= 2; +void list_remove_at(list_t *this, int index) { + vector_remove_at(this->data, index); + this->size -= 1; + if (this->size == this->capacity) { + this->capacity /= 2; } } -void -listSetAt(list_t* l, int index, dataType_e type, void* element) { - if (l->size == 0) { - listPush(l, type, element); - } else if (index >= l->size || index < 0) { - fprintf(stderr, "index out of range\nmust be between 0 and %d, is %d\n", l->size-1, index); - exit(EXIT_FAILURE); - } - - switch (type) { - case INT: - listRemoveAt(l, index); - if (index == l->size) { - l->data->size += 1; - if (l->data->size == l->data->capacity) { - l->data->capacity *= 2; - } +void list_set_at(list_t *this, int index, type_e type, void *element) { + if (this->size == 0) { + list_push(this, type, element); + } else if (index < this->size && index >= 0) { + list_remove_at(this, index); + if (index == this->size) { + this->data->size += 1; + if (this->data->size == this->data->capacity) { + this->data->capacity *= 2; } - listInsertAt(l, index, INT, element); - break; - case FLOAT: - listRemoveAt(l, index); - if (index == l->size) { - l->data->size += 1; - if (l->data->size == l->data->capacity) { - l->data->capacity *= 2; - } - } - listInsertAt(l, index, FLOAT, element); - break; - case CHAR: - listRemoveAt(l, index); - if (index == l->size) { - l->data->size += 1; - if (l->data->size == l->data->capacity) { - l->data->capacity *= 2; - } - } - listInsertAt(l, index, CHAR, element); - break; - case VECTOR: - listRemoveAt(l, index); - if (index == l->size) { - l->data->size += 1; - if (l->data->size == l->data->capacity) { - l->data->capacity *= 2; - } - } - listInsertAt(l, index, VECTOR, element); - break; - case LIST: - listRemoveAt(l, index); - if (index == l->size) { - l->data->size += 1; - if (l->data->size == l->data->capacity) { - l->data->capacity *= 2; - } - } - listInsertAt(l, index, LIST, element); - break; - default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); + } + list_insert_at(this, index, type, element); } } -void* -listGetAt(list_t* l, int index) { - if (l->size == 0) { - fprintf(stderr, "list is empty\n"); - exit(EXIT_FAILURE); - } else if (index >= l->size || index < 0) { - fprintf(stderr, "index out of range\n"); - exit(EXIT_FAILURE); +void *list_get_at(list_t *this, int index) { + if (this->size == 0) { + //fprintf(stderr, "list is empty\n"); + return NULL; + } else if (index >= this->size || index < 0) { + //fprintf(stderr, "index out of range\n"); + return NULL; + } else { + return vector_get_at((vector_t *)vector_get_at(this->data, index), 0); } - - return vectorGetAt((vector_t*)vectorGetAt(l->data, index), 0); } diff --git a/src/util.c b/src/util.c index c3debdc..e8bc58c 100644 --- a/src/util.c +++ b/src/util.c @@ -1,30 +1,28 @@ #include #include -char* -intToString(int x) { - vector_t* string = vectorInit(CHAR); +char *int_to_string(int x) { + vector_t *string = vector_new(CHAR); if (x > 0 && x < 10) { - vectorPush(string, &(char){x+48}); - char* retval = (char*)vectorToString(string); - vectorCleanup(string); + vector_push(string, &(char){x+48}); + char *retval = vector_to_string(string); + vector_cleanup(string); return retval; } else { while (x > 0) { int lastDigit = x % 10; x /= 10; - vectorInsertAt(string, 0, &(char){lastDigit+48}); + vector_insert_at(string, 0, &(char){lastDigit+48}); } - vectorPop(string); - char* retval = (char*)vectorToString(string); - vectorCleanup(string); + vector_pop(string); + char* retval = vector_to_string(string); + vector_cleanup(string); return retval; } } -long -pow(int x, int n) { +long pow(int x, int n) { long retval = 1; for (int i = 0; i < n; i++) { @@ -34,8 +32,7 @@ pow(int x, int n) { return retval; } -int -maxLowerPowerOf10(int x) { +int max_lower_power_of_10(int x) { int i = 0; long prev = pow(10, i++); @@ -47,5 +44,4 @@ maxLowerPowerOf10(int x) { prev = now; i++; } - } diff --git a/src/vector.c b/src/vector.c index 9581507..7f7dc22 100644 --- a/src/vector.c +++ b/src/vector.c @@ -1,481 +1,468 @@ #include #include #include +#include #include #include #include -void -vectorCleanup(vector_t* v) { - free(v->data); - free(v); +void vector_cleanup(vector_t *this) { + free(this->data); + free(this); } -int printNewline = 0; +static int printNewline = 0; -void -vectorReset(vector_t* v) { - while (v->size > 0) { - vectorPop(v); +void vector_reset(vector_t *this) { + while (this->size > 0) { + vector_pop(this); } } -void -_printVectorRecursive(vector_t* v, int depth) { +void _vector_print_recursive(vector_t *this, int depth) { int i; - fprintf(stdout, "["); - for (i = 0; i < v->size; i++) { - switch (v->type) { + printf("["); + for (i = 0; i < this->size; i++) { + switch (this->type) { case INT: - fprintf(stdout, "%d", *((int *)(v->data) + i)); + printf("%d", *((int *)(this->data) + i)); break; case FLOAT: - fprintf(stdout, "%f", *((float *)(v->data) + i)); + printf("%f", *((float *)(this->data) + i)); break; case CHAR: - fprintf(stdout, "%c", *((char *)(v->data) + i)); + printf("%c", *((char *)(this->data) + i)); break; case VECTOR: // Recursively print each level of the vector - _printVectorRecursive((vector_t *)(v->data + i * v->elementSize), depth + 1); - break; - default: - fprintf(stderr, "tried to print unsupported data type\n"); - exit(EXIT_FAILURE); - } - - if (i < v->size - 1 && v->type != CHAR) { - fprintf(stdout, ", "); - } else if (v->type == CHAR && i < v->size - 2 && v->size != 1) { - fprintf(stdout, ", "); - } - } - fprintf(stdout, "]"); - if (depth != 0) { - fprintf(stdout, "\n"); - } -} - -void -vectorPrint(vector_t* v) { - fprintf(stdout, "["); - int i; - for (i = 0; i < v->size; i++) { - switch (v->type) { - case INT: - fprintf(stdout, "%d", *((int *)(v->data) + i)); - break; - case FLOAT: - fprintf(stdout, "%f", *((float *)(v->data) + i)); - break; - case CHAR: - fprintf(stdout, "%c", *((char *)(v->data) + i)); - break; - case VECTOR: - // Print an nD vector - _printVectorRecursive((vector_t *)(v->data + i * v->elementSize), 0); + _vector_print_recursive((vector_t *)(this->data + i * this->element_size), depth + 1); break; case LIST: - // Print an nD vector - _listPrintRecursive((list_t *)(v->data + i * v->elementSize), 0); + _list_print_recursive((list_t *)(this->data + i * this->element_size), depth + 1); + case BOOL: + printf("%s", (*((bool *)(this->data + i * this->element_size)) == false) ? "false" : "true"); + break; + case STRING: + string_print((string_t *)(this->data + i * this->element_size)); break; default: - fprintf(stderr, "tried to print unsupported data type\n"); - exit(EXIT_FAILURE); + //fprintf(stderr, "tried to print unsupported data type\n"); + //exit(EXIT_FAILURE); + return; } - if (i < v->size - 1) { - fprintf(stdout, ", "); + if (i < this->size - 1 && this->type != CHAR) { + printf(", "); + } else if (this->type == CHAR && i < this->size - 2 && this->size != 1) { + printf(", "); } } - fprintf(stdout, "]"); - if (printNewline == 0) { - fprintf(stdout, "\n"); - } else { - fprintf(stdout, "]"); + printf("]"); + if (depth != 0) { + printf("\n"); } } -void -_printVectorAsStringRecursive(vector_t* v, int depth) { +void vector_print(vector_t *this) { + printf("["); int i; - for (i = 0; i < v->size; i++) { - switch (v->type) { + for (i = 0; i < this->size; i++) { + switch (this->type) { + case INT: + printf("%d", *((int *)(this->data) + i)); + break; + case FLOAT: + printf("%f", *((float *)(this->data) + i)); + break; case CHAR: - fprintf(stdout, "%c", *((char *)(v->data) + i)); + printf("%c", *((char *)(this->data) + i)); break; case VECTOR: // Recursively print each level of the vector - _printVectorAsStringRecursive((vector_t *)(v->data + i * v->elementSize), depth + 1); + _vector_print_recursive((vector_t *)(this->data + i * this->element_size), 0); + break; + case LIST: + _list_print_recursive((list_t *)(this->data + i * this->element_size), 0); + case BOOL: + printf("%s", (*((bool *)(this->data + i * this->element_size)) == false) ? "false" : "true"); + break; + case STRING: + string_print((string_t *)(this->data + i * this->element_size)); break; default: - fprintf(stderr, "tried to print a non-char type vector as string\n"); - exit(EXIT_FAILURE); + //fprintf(stderr, "tried to print unsupported data type\n"); + //exit(EXIT_FAILURE); + return; + } + + if (i < this->size - 1) { + printf(", "); } } - if (depth != 0) fprintf(stdout, "\n"); // do not print the last additional new line + printf("]"); + if (printNewline == 0) { + printf("\n"); + } else { + printf("]"); + } } -void -vectorPrintAsString(vector_t* v) { - switch (v->type) { +void _vector_print_as_string_recursive(vector_t *this, int depth) { + int i; + for (i = 0; i < this->size; i++) { + switch (this->type) { + case CHAR: + printf("%c", *((char *)(this->data) + i)); + break; + case VECTOR: + // Recursively print each level of the vector + _vector_print_as_string_recursive((vector_t *)(this->data + i * this->element_size), depth + 1); + break; + default: + //fprintf(stderr, "tried to print a non-char type vector as string\n"); + //exit(EXIT_FAILURE); + return; + } + } + + if (depth != 0) + printf("\n"); // do not print the last additional new line +} + +void vector_print_as_string(vector_t *this) { + switch (this->type) { case CHAR: - for (int i = 0; i < v->size; i++) { - fprintf(stdout, "%c", *((char *)(v->data) + i)); + for (int i = 0; i < this->size; i++) { + printf("%c", *((char *)(this->data) + i)); } - fprintf(stdout, "\n"); + printf("\n"); break; case VECTOR: - _printVectorAsStringRecursive(v, 0); + _vector_print_as_string_recursive(this, 0); break; default: - fprintf(stderr, "tried to print a non-char type vector as string | type: %d\n", v->type); - exit(EXIT_FAILURE); + //fprintf(stderr, "tried to print a non-char type vector as string | type: %d\n", this->type); + //exit(EXIT_FAILURE); + return; } } -vector_t* -vectorInit(dataType_e type) { - vector_t *v = malloc(sizeof(vector_t)); - if (!v) { - fprintf(stderr, "failed to allocate memory for the vector\n"); - exit(EXIT_FAILURE); +vector_t *vector_new(type_e type) { + vector_t *this = malloc(sizeof(vector_t)); + if (this == NULL) { + //fprintf(stderr, "failed to allocate memory for the vector\n"); + //exit(EXIT_FAILURE); + return NULL; } - v->type = type; - v->size = 0; - v->capacity = 1; - switch (v->type) { + this->type = type; + this->size = 0; + this->capacity = 1; + switch (this->type) { case INT: - v->elementSize = sizeof(int); + this->element_size = sizeof(int); break; case FLOAT: - v->elementSize = sizeof(float); + this->element_size = sizeof(float); break; case CHAR: - v->elementSize = sizeof(char); + this->element_size = sizeof(char); break; case VECTOR: - v->elementSize = sizeof(vector_t); + this->element_size = sizeof(vector_t); break; case LIST: - v->elementSize = sizeof(list_t); + this->element_size = sizeof(list_t); + break; + case BOOL: + this->element_size = sizeof(bool); + break; + case STRING: + this->element_size = sizeof(string_t); break; default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); + //fprintf(stderr, "specify a valid vector type\n"); + //exit(EXIT_FAILURE); + return NULL; } - v->data = malloc(v->elementSize * v->capacity); - if (!v->data) { - fprintf(stderr, "failed to allocate memory for vector data\n"); - exit(EXIT_FAILURE); + this->data = malloc(this->element_size * this->capacity); + if (this->data == NULL) { + //fprintf(stderr, "failed to allocate memory for vector data\n"); + //exit(EXIT_FAILURE); + return NULL; } - return v; + return this; } -void -vectorPush(vector_t* v, void* element) { - switch (v->type) { - case INT: - *((int *)(v->data) + v->size) = *((int *)element); - break; - case FLOAT: - *((float *)(v->data) + v->size) = *((float *)element); - break; - case CHAR: - // Allocate memory for the character - v->data = realloc(v->data, (v->size + 1) * v->elementSize); - if (!v->data) { - fprintf(stderr, "failed to allocate memory for vector data\n"); - exit(EXIT_FAILURE); - } - *((char *)(v->data) + v->size) = *((char *)element); - break; - case VECTOR: - // Instead of reallocating memory for vector_t pointers, allocate memory for the vector data - if (v->size == 0) { - // Allocate memory for the vector data for the first time - v->data = realloc(v->data, v->elementSize); - } else { - // Reallocate memory for the vector data - v->data = realloc(v->data, v->elementSize * (v->size + 1)); - } - if (!v->data) { - fprintf(stderr, "failed to allocate memory for vector data\n"); - exit(EXIT_FAILURE); - } - - // Copy the vector data from the element to the vector - memcpy((vector_t *)(v->data) + v->size, (vector_t *)element, sizeof(vector_t)); - break; - case LIST: - v->data = realloc(v->data, v->elementSize * (v->size + 1)); - if (!v->data) { - fprintf(stderr, "failed to allocate memory for vector data\n"); - exit(EXIT_FAILURE); - } - - memcpy((vector_t*)(v->data) + v->size, (list_t*)element, sizeof(list_t)); - break; - default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); +void vector_push(vector_t *this, void* element) { + void *tmp = realloc(this->data, (this->size + 1) * this->element_size); + this->data = tmp; + if (this->data == NULL) { + //fprintf(stderr, "failed to allocate memory for vector data\n"); + //exit(EXIT_FAILURE); + return; } - v->size += 1; - if (v->size == v->capacity) { - v->capacity *= 2; + switch (this->type) { + case INT: + *((int *)(this->data) + this->size) = *((int *)element); + break; + case FLOAT: + *((float *)(this->data) + this->size) = *((float *)element); + break; + case CHAR: + *((char *)(this->data) + this->size) = *((char *)element); + break; + case VECTOR: + // Copy the vector data from the element to the vector + memcpy((vector_t *)(this->data) + this->size, (vector_t *)element, sizeof(vector_t)); + break; + case LIST: + memcpy((vector_t*)(this->data) + this->size, (list_t*)element, sizeof(list_t)); + break; + case BOOL: + *((bool *)(this->data) + this->size) = *((bool *)element); + break; + case STRING: + memcpy((vector_t*)(this->data) + this->size, (string_t*)element, sizeof(string_t)); + break; + default: + return; + } + + this->size += 1; + if (this->size == this->capacity) { + this->capacity *= 2; } } -void* -vectorPop(vector_t* v) { +void *vector_pop(vector_t *this) { // capacity is always a power of 2, so a rounding error cannot happen i guess _/-(shi)-\_ - if (v->size != 0) { - switch (v->type) { - case INT: - int *iretval = (int *)(v->data) + v->size-1; - v->size -= 1; - if (v->size <= v->capacity / 2) v->capacity /= 2; - if (v->capacity == 0) v->capacity = 1; - return iretval; - case FLOAT: - float *fretval = (float *)(v->data) + v->size-1; - v->size -= 1; - if (v->size <= v->capacity / 2) v->capacity /= 2; - if (v->capacity == 0) v->capacity = 1; - return fretval; - case CHAR: - char *cretval = (char *)(v->data) + v->size-1; - v->size -= 1; - if (v->size <= v->capacity / 2) v->capacity /= 2; - if (v->capacity == 0) v->capacity = 1; - return cretval; - case VECTOR: - vector_t *vretval = (vector_t *)(v->data) + v->size-1; - v->size -= 1; - if (v->size <= v->capacity / 2) v->capacity /= 2; - if (v->capacity == 0) v->capacity = 1; - return vretval; - case LIST: - list_t* lretval = (list_t*)(v->data) + v->size-1; - v->size -= 1; - if (v->size <= v->capacity / 2) v->capacity /= 2; - if (v->capacity == 0) v->capacity = 1; - return lretval; - default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); - } + if (this->size != 0) { + this->size -= 1; + + if (this->size <= this->capacity / 2) + this->capacity /= 2; + + if (this->capacity == 0) + this->capacity = 1; + + return (this->data) + this->size-1; } else { // cannot pop when there is no value in the vector return NULL; } } -char* -vectorToString(vector_t* v) { - char* retString; - int totalSize = 0; +char *vector_to_string(vector_t *this) { + char* ret_string; + int total_size = 0; // Calculate the total size - for (int i = 0; i < v->size; i++) { - if (v->type == CHAR) { - totalSize += 1; // For a single character - } else if (v->type == VECTOR) { - vector_t* innerVector = (vector_t *)vectorGetAt(v, i); - char* innerString = vectorToString(innerVector); - totalSize += strlen(innerString); + for (int i = 0; i < this->size; i++) { + if (this->type == CHAR) { + total_size += 1; // For a single character + } else if (this->type == VECTOR) { + vector_t *inner_vector = (vector_t *)vector_get_at(this, i); + char *inner_string = vector_to_string(inner_vector); + total_size += strlen(inner_string); // Add newline between vectors (except the last one) - if (i < v->size - 1) { - totalSize += 1; + if (i < this->size - 1) { + total_size += 1; } - free(innerString); // Free the memory allocated for innerString + free(inner_string); // Free the memory allocated for innerString } } // Allocate memory for the string - retString = (char *)malloc((totalSize + 1 + 1) * sizeof(char)); // +1 for null terminator; +1 for ending '\n' + ret_string = (char *)malloc((total_size + 1 + 1) * sizeof(char)); // +1 for null terminator; +1 for ending '\n' // Copy the elements to the string int index = 0; - for (int i = 0; i < v->size; i++) { - if (v->type == CHAR) { - retString[index++] = *((char *)vectorGetAt(v, i)); - } else if (v->type == VECTOR) { - vector_t* innerVector = (vector_t *)vectorGetAt(v, i); - char* innerString = vectorToString(innerVector); - strcpy(retString + index, innerString); - index += strlen(innerString); + for (int i = 0; i < this->size; i++) { + if (this->type == CHAR) { + ret_string[index++] = *((char *)vector_get_at(this, i)); + } else if (this->type == VECTOR) { + vector_t *inner_vector = (vector_t *)vector_get_at(this, i); + char *inner_string = vector_to_string(inner_vector); + strcpy(ret_string + index, inner_string); + index += strlen(inner_string); // Add newline between vectors (including the last one) - if (i < v->size) { - retString[index++] = '\n'; + if (i < this->size) { + ret_string[index++] = '\n'; } - free(innerString); // Free the memory allocated for innerString + free(inner_string); // Free the memory allocated for innerString } } - retString[index] = '\0'; // Null-terminate the string + ret_string[index] = '\0'; // Null-terminate the string - return retString; + return ret_string; } -void* -vectorGetAt(vector_t* v, int index) { - switch (v->type) { - case INT: - return (int*)(v->data) + index; - case FLOAT: - return (float*)(v->data) + index; - case CHAR: - return (char*)(v->data) + index; - case VECTOR: - return (vector_t*)(v->data) + index; - case LIST: - return (list_t*)(v->data) + index; - default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); - } +void *vector_get_at(vector_t *this, int index) { + return (this->data) + index; } -void -vectorSetAt(vector_t* v, int index, void* element) { - if (v->size == 0) { - vectorPush(v, element); - } else if (index >= v->size) { - fprintf(stderr, "index out of range\n"); - exit(EXIT_FAILURE); +void vector_set_at(vector_t *this, int index, void *element) { + if (this->size == 0) { + vector_push(this, element); + } else if (index >= this->size) { + return; } - switch (v->type) { + switch (this->type) { case INT: - *((int *)(v->data) + index) = *((int *)element); + *((int *)(this->data) + index) = *((int *)element); break; case FLOAT: - *((float *)(v->data) + index) = *((float *)element); + *((float *)(this->data) + index) = *((float *)element); break; case CHAR: - *((char *)(v->data) + index) = *((char *)element); + *((char *)(this->data) + index) = *((char *)element); break; case VECTOR: - *((vector_t *)(v->data) + index) = *((vector_t *)element); + memcpy((vector_t*)(this->data) + index, (vector_t*)element, sizeof(vector_t)); break; case LIST: - *((list_t *)(v->data) + index) = *((list_t *)element); + memcpy((vector_t*)(this->data) + index, (list_t*)element, sizeof(list_t)); + break; + case BOOL: + *((bool *)(this->data) + index) = *((bool *)element); + break; + case STRING: + memcpy((vector_t*)(this->data) + index, (string_t*)element, sizeof(string_t)); break; default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); + return; } } -void -vectorInsertAt(vector_t* v, int index, void* element) { - if (v->size == 0) { - vectorPush(v, element); - } else if (index >= v->size || index < 0) { - fprintf(stderr, "index out of range\nmust be between 0 and %d, is %d\n", v->size-1, index); - exit(EXIT_FAILURE); - } +void vector_insert_at(vector_t *this, int index, void *element) { + if (this->size == 0) { + vector_push(this, element); + } else if (index < this->size && index >= 0) { + this->size += 1; + if (this->size >= this->capacity) { + this->capacity *= 2; + void *tmp = realloc(this->data, this->element_size * this->capacity); + this->data = tmp; + if (this->data == NULL) { + return; + } + } - v->size += 1; - if (v->size >= v->capacity) { - v->capacity *= 2; - v->data = realloc(v->data, v->elementSize * v->capacity); - } - - switch (v->type) { - case INT: - // move all elements to the right by one - for (int i = v->size-1; i > index; i--) { - *((int *)(v->data) + i) = *((int *)(v->data) + i-1); - } - // set the element at the given index - *((int *)(v->data) + index) = *((int *)element); - break; - case FLOAT: - for (int i = v->size-1; i > index; i--) { - *((float *)(v->data) + i) = *((float *)(v->data) + i-1); - } - *((float *)(v->data) + index) = *((float *)element); - break; - case CHAR: - for (int i = v->size-1; i > index; i--) { - *((char *)(v->data) + i) = *((char *)(v->data) + i-1); - } - *((char *)(v->data) + index) = *((char *)element); - break; - case VECTOR: - for (int i = v->size-1; i > index; i--) { - *((vector_t *)(v->data) + i) = *((vector_t *)(v->data) + i-1); - } - *((vector_t *)(v->data) + index) = *((vector_t *)element); - break; - case LIST: - for (int i = v->size-1; i > index; i--) { - *((list_t*)(v->data) + i) = *((list_t*)(v->data) + i-1); - } - *((list_t*)(v->data) + index) = *((list_t*)element); - break; - default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); + switch (this->type) { + case INT: + // move all elements to the right by one + for (int i = this->size-1; i > index; i--) { + *((int *)(this->data) + i) = *((int *)(this->data) + i-1); + } + // set the element at the given index + *((int *)(this->data) + index) = *((int *)element); + break; + case FLOAT: + for (int i = this->size-1; i > index; i--) { + *((float *)(this->data) + i) = *((float *)(this->data) + i-1); + } + *((float *)(this->data) + index) = *((float *)element); + break; + case CHAR: + for (int i = this->size-1; i > index; i--) { + *((char *)(this->data) + i) = *((char *)(this->data) + i-1); + } + *((char *)(this->data) + index) = *((char *)element); + break; + case VECTOR: + for (int i = this->size-1; i > index; i--) { + memcpy((vector_t *)(this->data) + i, (vector_t *)(this->data) + i-1, sizeof(vector_t)); + } + memcpy((vector_t*)(this->data) + index, (vector_t *)element, sizeof(vector_t)); + break; + case LIST: + for (int i = this->size-1; i > index; i--) { + memcpy((vector_t *)(this->data) + i, (list_t *)(this->data) + i-1, sizeof(list_t)); + } + memcpy((vector_t *)(this->data) + index, (list_t *)element, sizeof(list_t)); + break; + case BOOL: + for (int i = this->size-1; i > index; i--) { + *((bool *)(this->data) + i) = *((bool *)(this->data) + i-1); + } + *((bool *)(this->data) + index) = *((bool *)element); + break; + case STRING: + for (int i = this->size-1; i > index; i--) { + memcpy((vector_t *)(this->data) + i, (string_t *)(this->data) + i-1, sizeof(string_t)); + } + memcpy((vector_t *)(this->data) + index, (string_t *)element, sizeof(string_t)); + break; + default: + return; + } } } -void -vectorRemoveAt(vector_t* v, int index) { - if (v->size == 0) { - fprintf(stderr, "cannot remove from empty vector\n"); - exit(EXIT_FAILURE); - } else if (index >= v->size || index < 0) { - fprintf(stderr, "index out of range\n"); - exit(EXIT_FAILURE); - } +void vector_remove_at(vector_t *this, int index) { + if (index < this->size && index >= 0 && this->size != 0) { + switch (this->type) { + case INT: + // move all elements to the right by one + for (int i = index; i < this->size; i++) { + *((int *)(this->data) + i) = *((int *)(this->data) + i+1); + } + break; + case FLOAT: + for (int i = index; i < this->size; i++) { + *((float *)(this->data) + i) = *((float *)(this->data) + i+1); + } + break; + case CHAR: + for (int i = index; i < this->size; i++) { + *((char *)(this->data) + i) = *((char *)(this->data) + i+1); + } + break; + case VECTOR: + for (int i = index; i < this->size; i++) { + memcpy((vector_t *)(this->data) + i, (vector_t *)(this->data) + i+1, sizeof(vector_t)); + } + break; + case LIST: + for (int i = index; i < this->size; i++) { + memcpy((vector_t *)(this->data) + i, (list_t *)(this->data) + i+1, sizeof(list_t)); + } + break; + case BOOL: + for (int i = index; i < this->size; i++) { + *((bool *)(this->data) + i) = *((bool *)(this->data) + i+1); + } + break; + case STRING: + for (int i = index; i < this->size; i++) { + memcpy((vector_t *)(this->data) + i, (string_t *)(this->data) + i+1, sizeof(string_t)); + } + break; + default: + return; + } - switch (v->type) { - case INT: - // move all elements to the right by one - for (int i = index; i < v->size; i++) { - *((int *)(v->data) + i) = *((int *)(v->data) + i+1); + this->size -= 1; + if (this->size < this->capacity/2) { + this->capacity /= 2; + void *tmp = realloc(this->data, this->element_size * this->capacity); + this->data = tmp; + if (this->data == NULL) { + return; } - break; - case FLOAT: - for (int i = index; i < v->size; i++) { - *((float *)(v->data) + i) = *((float *)(v->data) + i+1); - } - break; - case CHAR: - for (int i = index; i < v->size; i++) { - *((char *)(v->data) + i) = *((char *)(v->data) + i+1); - } - break; - case VECTOR: - for (int i = index; i < v->size; i++) { - *((vector_t*)(v->data) + i) = *((vector_t*)(v->data) + i+1); - } - break; - case LIST: - for (int i = index; i < v->size; i++) { - *((list_t*)(v->data) + i) = *((list_t*)(v->data) + i+1); - } - break; - default: - fprintf(stderr, "specify a valid vector type\n"); - exit(EXIT_FAILURE); - } - - v->size -= 1; - if (v->size < v->capacity/2) { - v->capacity /= 2; - v->data = realloc(v->data, v->elementSize * v->capacity); + } + } else { + return; } }