refactoring done, small bugfixes included, vectors and lists of non-primitive types are not working though
This commit is contained in:
@@ -1,21 +1,15 @@
|
||||
#include <odweta/string.h>
|
||||
#include <odweta/vector.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
+15
-14
@@ -2,6 +2,7 @@
|
||||
#define FILE_H
|
||||
|
||||
#include <odweta/vector.h>
|
||||
#include <odweta/util.h>
|
||||
|
||||
typedef struct {
|
||||
char *path; // the file descriptor
|
||||
@@ -10,30 +11,30 @@ typedef struct {
|
||||
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
|
||||
|
||||
+11
-11
@@ -19,23 +19,23 @@ typedef struct {
|
||||
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
|
||||
#endif // LIST_H
|
||||
+14
-11
@@ -1,7 +1,9 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#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
|
||||
|
||||
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
|
||||
|
||||
+15
-27
@@ -4,51 +4,39 @@
|
||||
#include <odweta/util.h>
|
||||
|
||||
typedef struct {
|
||||
dataType_e type;
|
||||
type_e type;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
size_t elementSize;
|
||||
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
|
||||
|
||||
+107
-133
@@ -5,14 +5,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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);
|
||||
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
|
||||
}
|
||||
vectorCleanup(f->lines);
|
||||
free(f);
|
||||
this->not_newline_terminated = 0; // just for piece of mind
|
||||
}
|
||||
|
||||
void
|
||||
filePrint(file_t* f) {
|
||||
for (int i = 0; i < f->length; i++) {
|
||||
vectorPrintAsString((vector_t *)vectorGetAt(f->lines, i));
|
||||
vector_cleanup(this->lines);
|
||||
free(this);
|
||||
}
|
||||
|
||||
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) {
|
||||
void file_copy(file_t *src, char *dst) {
|
||||
FILE *fd = fopen(dst, "w");
|
||||
if (!fd) {
|
||||
fprintf(stderr, "could not open file for writing\n");
|
||||
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);
|
||||
void file_delete(file_t *this) {
|
||||
if (remove(this->path) == 0)
|
||||
file_cleanup(this);
|
||||
}
|
||||
|
||||
fileCleanup(f);
|
||||
void file_move(file_t *src, char *dst) {
|
||||
file_copy(src, dst);
|
||||
|
||||
file_delete(src);
|
||||
}
|
||||
|
||||
void
|
||||
fileMove(file_t* src, char* dst) {
|
||||
fileCopy(src, dst);
|
||||
|
||||
fileDelete(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++;
|
||||
}
|
||||
|
||||
+111
-220
@@ -1,152 +1,140 @@
|
||||
#include <odweta/list.h>
|
||||
#include <odweta/vector.h>
|
||||
#include <odweta/util.h>
|
||||
#include <odweta/string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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, "[");
|
||||
void list_show(list_t *this) {
|
||||
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, "]\n");
|
||||
}
|
||||
|
||||
void
|
||||
listCleanup(list_t* l) {
|
||||
vectorCleanup((vector_t *)l->data);
|
||||
free(l);
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
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_cleanup(list_t *this) {
|
||||
vector_cleanup((vector_t *)this->data);
|
||||
free(this);
|
||||
}
|
||||
|
||||
if (l->size <= l->capacity / 2) l->capacity /= 2;
|
||||
if (l->capacity == 0) l->capacity = 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 (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);
|
||||
|
||||
l->size += 1;
|
||||
if (l->size == l->capacity) {
|
||||
l->capacity *= 2;
|
||||
vector_push(new_vec, element);
|
||||
vector_insert_at((vector_t *)this->data, index, new_vec);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
+11
-15
@@ -1,30 +1,28 @@
|
||||
#include <odweta/util.h>
|
||||
#include <odweta/vector.h>
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+320
-333
@@ -1,481 +1,468 @@
|
||||
#include <odweta/vector.h>
|
||||
#include <odweta/util.h>
|
||||
#include <odweta/list.h>
|
||||
#include <odweta/string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
_vector_print_recursive((vector_t *)(this->data + i * this->element_size), depth + 1);
|
||||
break;
|
||||
case LIST:
|
||||
_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 && v->type != CHAR) {
|
||||
fprintf(stdout, ", ");
|
||||
} else if (v->type == CHAR && i < v->size - 2 && 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, "]");
|
||||
printf("]");
|
||||
if (depth != 0) {
|
||||
fprintf(stdout, "\n");
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vectorPrint(vector_t* v) {
|
||||
fprintf(stdout, "[");
|
||||
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:
|
||||
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));
|
||||
break;
|
||||
case VECTOR:
|
||||
// Print an nD vector
|
||||
_printVectorRecursive((vector_t *)(v->data + i * v->elementSize), 0);
|
||||
break;
|
||||
case LIST:
|
||||
// Print an nD vector
|
||||
_listPrintRecursive((list_t *)(v->data + i * v->elementSize), 0);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "tried to print unsupported data type\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (i < v->size - 1) {
|
||||
fprintf(stdout, ", ");
|
||||
}
|
||||
}
|
||||
fprintf(stdout, "]");
|
||||
if (printNewline == 0) {
|
||||
fprintf(stdout, "\n");
|
||||
} else {
|
||||
fprintf(stdout, "]");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_printVectorAsStringRecursive(vector_t* v, int depth) {
|
||||
int i;
|
||||
for (i = 0; i < v->size; i++) {
|
||||
switch (v->type) {
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "tried to print a non-char type vector as string\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (depth != 0) fprintf(stdout, "\n"); // do not print the last additional new line
|
||||
}
|
||||
|
||||
void
|
||||
vectorPrintAsString(vector_t* v) {
|
||||
switch (v->type) {
|
||||
case CHAR:
|
||||
for (int i = 0; i < v->size; i++) {
|
||||
fprintf(stdout, "%c", *((char *)(v->data) + i));
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
break;
|
||||
case VECTOR:
|
||||
_printVectorAsStringRecursive(v, 0);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "tried to print a non-char type vector as string | type: %d\n", v->type);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
v->type = type;
|
||||
v->size = 0;
|
||||
v->capacity = 1;
|
||||
switch (v->type) {
|
||||
case INT:
|
||||
v->elementSize = sizeof(int);
|
||||
break;
|
||||
case FLOAT:
|
||||
v->elementSize = sizeof(float);
|
||||
break;
|
||||
case CHAR:
|
||||
v->elementSize = sizeof(char);
|
||||
break;
|
||||
case VECTOR:
|
||||
v->elementSize = sizeof(vector_t);
|
||||
_vector_print_recursive((vector_t *)(this->data + i * this->element_size), 0);
|
||||
break;
|
||||
case LIST:
|
||||
v->elementSize = sizeof(list_t);
|
||||
_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, "specify a valid vector type\n");
|
||||
exit(EXIT_FAILURE);
|
||||
//fprintf(stderr, "tried to print unsupported data type\n");
|
||||
//exit(EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
v->data = malloc(v->elementSize * v->capacity);
|
||||
if (!v->data) {
|
||||
fprintf(stderr, "failed to allocate memory for vector data\n");
|
||||
exit(EXIT_FAILURE);
|
||||
if (i < this->size - 1) {
|
||||
printf(", ");
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
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);
|
||||
printf("]");
|
||||
if (printNewline == 0) {
|
||||
printf("\n");
|
||||
} else {
|
||||
// Reallocate memory for the vector data
|
||||
v->data = realloc(v->data, v->elementSize * (v->size + 1));
|
||||
printf("]");
|
||||
}
|
||||
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));
|
||||
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 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));
|
||||
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, "specify a valid vector type\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
v->size += 1;
|
||||
if (v->size == v->capacity) {
|
||||
v->capacity *= 2;
|
||||
//fprintf(stderr, "tried to print a non-char type vector as string\n");
|
||||
//exit(EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
vectorPop(vector_t* v) {
|
||||
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 < this->size; i++) {
|
||||
printf("%c", *((char *)(this->data) + i));
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
case VECTOR:
|
||||
_vector_print_as_string_recursive(this, 0);
|
||||
break;
|
||||
default:
|
||||
//fprintf(stderr, "tried to print a non-char type vector as string | type: %d\n", this->type);
|
||||
//exit(EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
this->type = type;
|
||||
this->size = 0;
|
||||
this->capacity = 1;
|
||||
switch (this->type) {
|
||||
case INT:
|
||||
this->element_size = sizeof(int);
|
||||
break;
|
||||
case FLOAT:
|
||||
this->element_size = sizeof(float);
|
||||
break;
|
||||
case CHAR:
|
||||
this->element_size = sizeof(char);
|
||||
break;
|
||||
case VECTOR:
|
||||
this->element_size = sizeof(vector_t);
|
||||
break;
|
||||
case LIST:
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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 this;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 *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) {
|
||||
void *vector_get_at(vector_t *this, int index) {
|
||||
return (this->data) + index;
|
||||
}
|
||||
|
||||
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 (this->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
|
||||
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);
|
||||
}
|
||||
|
||||
switch (v->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) {
|
||||
switch (this->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);
|
||||
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 *)(v->data) + index) = *((int *)element);
|
||||
*((int *)(this->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);
|
||||
for (int i = this->size-1; i > index; i--) {
|
||||
*((float *)(this->data) + i) = *((float *)(this->data) + i-1);
|
||||
}
|
||||
*((float *)(v->data) + index) = *((float *)element);
|
||||
*((float *)(this->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);
|
||||
for (int i = this->size-1; i > index; i--) {
|
||||
*((char *)(this->data) + i) = *((char *)(this->data) + i-1);
|
||||
}
|
||||
*((char *)(v->data) + index) = *((char *)element);
|
||||
*((char *)(this->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);
|
||||
for (int i = this->size-1; i > index; i--) {
|
||||
memcpy((vector_t *)(this->data) + i, (vector_t *)(this->data) + i-1, sizeof(vector_t));
|
||||
}
|
||||
*((vector_t *)(v->data) + index) = *((vector_t *)element);
|
||||
memcpy((vector_t*)(this->data) + index, (vector_t *)element, sizeof(vector_t));
|
||||
break;
|
||||
case LIST:
|
||||
for (int i = v->size-1; i > index; i--) {
|
||||
*((list_t*)(v->data) + i) = *((list_t*)(v->data) + i-1);
|
||||
for (int i = this->size-1; i > index; i--) {
|
||||
memcpy((vector_t *)(this->data) + i, (list_t *)(this->data) + i-1, sizeof(list_t));
|
||||
}
|
||||
*((list_t*)(v->data) + index) = *((list_t*)element);
|
||||
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:
|
||||
fprintf(stderr, "specify a valid vector type\n");
|
||||
exit(EXIT_FAILURE);
|
||||
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);
|
||||
}
|
||||
|
||||
switch (v->type) {
|
||||
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 < v->size; i++) {
|
||||
*((int *)(v->data) + i) = *((int *)(v->data) + i+1);
|
||||
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 < v->size; i++) {
|
||||
*((float *)(v->data) + i) = *((float *)(v->data) + i+1);
|
||||
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 < v->size; i++) {
|
||||
*((char *)(v->data) + i) = *((char *)(v->data) + i+1);
|
||||
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 < v->size; i++) {
|
||||
*((vector_t*)(v->data) + i) = *((vector_t*)(v->data) + i+1);
|
||||
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 < v->size; i++) {
|
||||
*((list_t*)(v->data) + i) = *((list_t*)(v->data) + i+1);
|
||||
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:
|
||||
fprintf(stderr, "specify a valid vector type\n");
|
||||
exit(EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
v->size -= 1;
|
||||
if (v->size < v->capacity/2) {
|
||||
v->capacity /= 2;
|
||||
v->data = realloc(v->data, v->elementSize * v->capacity);
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user