From 741fbd9a4c109cb32cbfdbfe9d88933ecc444495 Mon Sep 17 00:00:00 2001
From: iliya <iliya.saroukha@hes-so.ch>
Date: Fri, 10 Nov 2023 10:58:51 +0100
Subject: [PATCH] feat: made implementation generic, goal finally achieved

---
 Makefile     | 13 ++++---
 struct/vec.c | 95 +++++++++++++++++++++++++++-------------------------
 struct/vec.h | 14 ++++----
 vec_test.c   | 16 +++++----
 4 files changed, 74 insertions(+), 64 deletions(-)

diff --git a/Makefile b/Makefile
index 780212b..4ef0dcd 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,11 @@
 CC := clang
-CFLAGS := -Wall -Wextra -g -pedantic -fPIC -fsanitize=address -fsanitize=leak -fsanitize=undefined
-VPATH := struct
-LDFLAGS := -L$(shell pwd)/ -lvector
+CFLAGS := -g -pedantic -Wall -Wextra -Werror -fPIC
+LDFLAGS := -fsanitize=address,leak,undefined -L$(shell pwd)/ -lvector
 SHELL := /bin/bash
+VPATH := struct
 TARGET := vec_test
 
+all: $(TARGET)
 
 $(TARGET): $(TARGET).o lib_dyn
 	$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
@@ -23,8 +24,7 @@ lib_dyn: vec.o
 		ln -s libvector.so.1.0.0 libvector.so; \
 	fi
 
-
-vec.o: vec.c vec.h
+%.o: %.c
 	$(CC) $(CFLAGS) -c $< 
 
 .PHONY: clean
@@ -32,3 +32,6 @@ vec.o: vec.c vec.h
 clean:
 	rm -f $(TARGET) *.o libvector.so libvector.so.1 libvector.so.1.0.0 
 
+.PHONY: rebuild
+
+rebuild: clean all
diff --git a/struct/vec.c b/struct/vec.c
index c791665..44ace6d 100644
--- a/struct/vec.c
+++ b/struct/vec.c
@@ -5,28 +5,28 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define err_init(x)                                                            \
+#define ERR_INIT(x)                                                            \
     if (x == NULL) {                                                           \
         fprintf(stderr, "Function: %s [%s:%d]: `Vector not initialised!`\n\n", \
                 __func__, __FILE__, __LINE__);                                 \
         return;                                                                \
     }
 
-#define err_len_zero(x)                                                        \
+#define ERR_LEN_ZERO(x)                                                        \
     if (x->len == 0) {                                                         \
         fprintf(stderr, "Function: %s [%s:%d]: `Vector length is zero!`\n\n",  \
                 __func__, __FILE__, __LINE__);                                 \
         return;                                                                \
     }
 
-#define print_arr(x, len)                                                      \
+#define PRINT_ARR(x, len)                                                      \
     for (size_t i = 0; i < len; i++) {                                         \
         fprintf(stderr, "LOG:\tarr[%ld] -> %ld\n", i, x[i]);                   \
     }                                                                          \
     fprintf(stderr, "\n");
 
 struct _vec_t {
-    int64_t *data;
+    void **data;
     size_t len;
     size_t capacity;
 };
@@ -39,7 +39,6 @@ struct _vec_t {
  * @return Pointer to newly instantiated vector
  */
 vec_t *vec_create(size_t init_capacity) {
-
     if (init_capacity == 0) {
         fprintf(stderr, "Initial size of the vector has to be a non-zero\n");
         return NULL;
@@ -48,16 +47,16 @@ vec_t *vec_create(size_t init_capacity) {
     vec_t *vec = malloc(sizeof(vec_t));
 
     if (vec == NULL) {
-        fprintf(stderr, "Allocation for new vector failed!\n");
+        perror("malloc");
         return NULL;
     }
 
     vec->len = 0;
     vec->capacity = init_capacity;
-    vec->data = malloc(init_capacity * sizeof(int64_t));
+    vec->data = malloc(init_capacity * sizeof(void *));
 
     if (vec->data == NULL) {
-        fprintf(stderr, "Allocation for data member failed!\n");
+        perror("malloc");
         return NULL;
     }
 
@@ -92,16 +91,15 @@ ssize_t vec_length(vec_t *vec) {
  * @param idx Index in the vector
  * @return Value contained at the given index OR -1 in case of an error
  */
-int64_t vec_get(vec_t *vec, size_t idx) {
-
+void *vec_get(vec_t *vec, size_t idx) {
     if (vec == NULL) {
         fprintf(stderr, "Vector not initialised!\n");
-        return -1;
+        return NULL;
     }
 
     if (idx > vec->capacity - 1) {
         fprintf(stderr, "Index out of bounds\n");
-        return -1;
+        return NULL;
     }
 
     return vec->data[idx];
@@ -111,17 +109,15 @@ int64_t vec_get(vec_t *vec, size_t idx) {
  * @brief Function that inserts/pushes a value into an existing vector
  *
  * @param vec Vector in which we wish to insert a value
- * @param data Value that we wish to insert
  */
-void vec_push(vec_t *vec, int64_t data) {
-
-    err_init(vec);
+void vec_push(vec_t *vec, void *data) {
+    ERR_INIT(vec);
 
     if (vec->len >= (size_t)(vec->capacity * 0.75)) {
 
         size_t new_capacity = 2 * vec->capacity;
 
-        vec->data = realloc(vec->data, new_capacity * sizeof(int64_t));
+        vec->data = realloc(vec->data, new_capacity * sizeof(void *));
         vec->capacity = new_capacity;
     }
 
@@ -136,11 +132,9 @@ void vec_push(vec_t *vec, int64_t data) {
  * @param data Value that we wish to insert
  * @param idx Position in the vector
  */
-void vec_insert_at(vec_t *vec, int64_t data, size_t idx) {
-
-    err_init(vec);
-
-    err_len_zero(vec);
+void vec_insert_at(vec_t *vec, void *data, size_t idx) {
+    ERR_INIT(vec);
+    ERR_LEN_ZERO(vec);
 
     if (idx > vec->capacity - 1) {
         fprintf(stderr, "Index out of bounds\n");
@@ -150,21 +144,22 @@ void vec_insert_at(vec_t *vec, int64_t data, size_t idx) {
     if (idx <= vec->len) {
 
         size_t size_to_copy = vec->len - idx;
-        int64_t incl_and_aftr_idx[size_to_copy];
+        void **incl_and_aftr_idx = malloc(size_to_copy * sizeof(void *));
 
         memcpy((void *)incl_and_aftr_idx, (void *)(vec->data + idx),
-               size_to_copy * sizeof(int64_t));
+               size_to_copy * sizeof(void *));
 
         for (size_t i = 0; i < size_to_copy; i++) {
             vec_pop(vec);
         }
 
         vec_push(vec, data);
-        // print_arr(aftr_idx, size_to_copy);
 
         for (size_t i = 0; i < size_to_copy; i++) {
             vec_push(vec, incl_and_aftr_idx[i]);
         }
+
+        free(incl_and_aftr_idx);
     }
 }
 
@@ -175,8 +170,7 @@ void vec_insert_at(vec_t *vec, int64_t data, size_t idx) {
  * @param data Value to check for
  * @return `true` if value was found otherwise, `false`
  */
-bool is_in_vec(vec_t *vec, int64_t data) {
-
+bool is_in_vec(vec_t *vec, void *data) {
     if (vec == NULL) {
         fprintf(stderr, "Vector not initialised\n");
         return false;
@@ -198,16 +192,15 @@ bool is_in_vec(vec_t *vec, int64_t data) {
  * @param vec Vector from which the value will be removed
  * @return Last element in the vector
  */
-int64_t vec_pop(vec_t *vec) {
-
+void *vec_pop(vec_t *vec) {
     if (vec == NULL) {
         fprintf(stderr, "Vector not initialised\n");
-        return -1;
+        return NULL;
     }
 
     if (vec->len == 0) {
         fprintf(stderr, "Length of the vector is 0!\n");
-        return -1;
+        return NULL;
     }
     // needs resizing
     // should be extracted into separate function
@@ -215,7 +208,7 @@ int64_t vec_pop(vec_t *vec) {
 
         size_t new_size = vec->capacity / 2;
 
-        vec->data = realloc(vec->data, new_size * sizeof(int64_t));
+        vec->data = realloc(vec->data, new_size * sizeof(void *));
         vec->capacity = new_size;
     }
 
@@ -231,10 +224,8 @@ int64_t vec_pop(vec_t *vec) {
  * @param idx Position in the vector
  */
 void vec_remove(vec_t *vec, size_t idx) {
-
-    err_init(vec);
-
-    err_len_zero(vec);
+    ERR_INIT(vec);
+    ERR_LEN_ZERO(vec);
 
     if (idx > vec->len) {
         fprintf(stderr, "Index out of bounds!\n");
@@ -247,10 +238,10 @@ void vec_remove(vec_t *vec, size_t idx) {
     }
 
     size_t size_to_copy = vec->len - (idx + 1);
-    int64_t aftr_idx[size_to_copy];
+    void **aftr_idx = malloc(size_to_copy * sizeof(void *));
 
     memcpy((void *)aftr_idx, (void *)(vec->data + idx + 1),
-           size_to_copy * sizeof(int64_t));
+           size_to_copy * sizeof(void *));
 
     size_t size_to_pop = size_to_copy + 1;
 
@@ -258,11 +249,24 @@ void vec_remove(vec_t *vec, size_t idx) {
         vec_pop(vec);
     }
 
-    // print_arr(aftr_idx, size_to_copy);
-
     for (size_t i = 0; i < size_to_copy; i++) {
         vec_push(vec, aftr_idx[i]);
     }
+
+    free(aftr_idx);
+}
+
+char *print_int(void *element) {
+    int64_t data = (int64_t)element;
+    char *s = calloc(30, sizeof(char));
+
+    if (s == NULL) {
+        perror("calloc");
+        return NULL;
+    }
+
+    sprintf(s, "Data: %ld |\n", data);
+    return s;
 }
 
 /**
@@ -271,23 +275,22 @@ void vec_remove(vec_t *vec, size_t idx) {
  *
  * @param vec
  */
-void vec_print(vec_t *vec) {
-
-    err_init(vec);
+void vec_print(vec_t *vec, char *(*print_entry)(void *data)) {
+    ERR_LEN_ZERO(vec);
 
     fprintf(stdout, " ========= Vector Data =========\n");
     fprintf(stdout, " Capacity: %zu\tCurrent Size: %zu\n", vec->capacity,
             vec->len);
     fprintf(stdout, " ===============================\n");
-
     fprintf(stdout, " -------------------------------\n");
     for (size_t i = 0; i < vec->len; i++) {
-        fprintf(stdout, "| Vector[%ld]\t->\tData: %ld |\n", i, vec->data[i]);
+        char *s = print_entry(vec->data[i]);
+        fprintf(stdout, "| Vector[%ld]\t->\t%s", i, s);
+        free(s);
     }
     fprintf(stdout, " -------------------------------\n");
     fprintf(stdout, "\n");
 }
-
 /**
  * @brief Function that deallocates memory used up by the vector that was passed
  * as an argument to the function. Subsequently the pointer will be set to NULL,
diff --git a/struct/vec.h b/struct/vec.h
index 856226f..7ca9003 100644
--- a/struct/vec.h
+++ b/struct/vec.h
@@ -10,19 +10,21 @@ extern vec_t *vec_create(size_t init_len);
 
 extern ssize_t vec_length(vec_t *vec);
 
-extern int64_t vec_get(vec_t *vec, size_t idx);
+extern void *vec_get(vec_t *vec, size_t idx);
 
-extern void vec_push(vec_t *vec, int64_t data);
+extern void vec_push(vec_t *vec, void *data);
 
-extern void vec_insert_at(vec_t *vec, int64_t data, size_t idx);
+extern void vec_insert_at(vec_t *vec, void *data, size_t idx);
 
-extern bool is_in_vec(vec_t *vec, int64_t data);
+extern bool is_in_vec(vec_t *vec, void *data);
 
 extern void vec_remove(vec_t *vec, size_t idx);
 
-extern int64_t vec_pop(vec_t *vec);
+extern void *vec_pop(vec_t *vec);
 
-extern void vec_print(vec_t *vec);
+extern char *print_int(void *element);
+
+extern void vec_print(vec_t *vec, char *(*print_entry)(void *data));
 
 extern void vec_destroy(vec_t **vec);
 
diff --git a/vec_test.c b/vec_test.c
index a785ff1..b497f98 100644
--- a/vec_test.c
+++ b/vec_test.c
@@ -1,9 +1,9 @@
+#include "struct/vec.h"
 #include <libgen.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <vec.h>
 #define NB_OPTIONS 6
 
 void print_menu(void) {
@@ -19,7 +19,6 @@ void print_menu(void) {
 }
 
 int main(int argc, char **argv) {
-
     if (argc < 2) {
         fprintf(stderr, "Usage:\n");
         fprintf(stderr, "\t./%s <initial length of vector>\n",
@@ -69,7 +68,7 @@ int main(int argc, char **argv) {
             scanf("%ld", &to_push);
             fprintf(stdout, "\n");
 
-            vec_push(new_vec, to_push);
+            vec_push(new_vec, (void *)to_push);
             break;
         case 2:
             fprintf(stdout,
@@ -80,12 +79,13 @@ int main(int argc, char **argv) {
             vec_remove(new_vec, idx_to_drop);
             break;
         case 3:
-            item_poped = vec_pop(new_vec);
+            item_poped = (int64_t)vec_pop(new_vec);
             fprintf(stdout, "Last value in the vector: %ld was removed\n",
                     item_poped);
             break;
         case 4:
-            vec_print(new_vec);
+            // vec_print(new_vec);
+            vec_print(new_vec, print_int);
             break;
         case 5:
             fprintf(stdout,
@@ -97,13 +97,15 @@ int main(int argc, char **argv) {
                 "Specify the index at which you wish to insert the number: ");
             scanf("%zu", &idx_to_insert);
 
-            vec_insert_at(new_vec, to_push, idx_to_insert);
+            vec_insert_at(new_vec, (void *)to_push, idx_to_insert);
             break;
         case 6:
             vec_destroy(&new_vec);
-            return EXIT_SUCCESS;
+            exit(EXIT_SUCCESS);
         default:
             break;
         }
     }
+
+    return EXIT_SUCCESS;
 }
-- 
GitLab