aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2022-02-03 10:54:07 +0000
committerFuwn <[email protected]>2022-02-03 10:54:07 +0000
commit47b5504cfd0224bf82477549236a363b9e0dc8b5 (patch)
treefb962ac20d24bc822945bc4a02325b1ce079b46e
parentrevert(cmake): re-add `-Werror` (diff)
downloadviv-47b5504cfd0224bf82477549236a363b9e0dc8b5.tar.xz
viv-47b5504cfd0224bf82477549236a363b9e0dc8b5.zip
feat(dynamic_array): implement for future use
-rw-r--r--include/viv/dynamic_array.h34
-rw-r--r--viv/CMakeLists.txt1
-rw-r--r--viv/dynamic_array.c266
3 files changed, 301 insertions, 0 deletions
diff --git a/include/viv/dynamic_array.h b/include/viv/dynamic_array.h
new file mode 100644
index 0000000..40deac6
--- /dev/null
+++ b/include/viv/dynamic_array.h
@@ -0,0 +1,34 @@
+/* http://www.martinbroadhurst.com/dynamic-array-in-c.html */
+
+#ifndef VIV_DYNAMIC_ARRAY_H
+#define VIV_DYNAMIC_ARRAY_H
+
+#pragma once
+
+typedef struct {
+ void **buffer;
+ unsigned int size;
+ unsigned int count;
+} VIV_DYNAMIC_ARRAY_dynamic_array;
+
+typedef void (*VIV_DYNAMIC_ARRAY_for_function)(void *);
+
+VIV_DYNAMIC_ARRAY_dynamic_array *VIV_DYNAMIC_ARRAY_create(unsigned int);
+void VIV_DYNAMIC_ARRAY_empty(VIV_DYNAMIC_ARRAY_dynamic_array *);
+void VIV_DYNAMIC_ARRAY_delete(VIV_DYNAMIC_ARRAY_dynamic_array *);
+void VIV_DYNAMIC_ARRAY_add_tail(VIV_DYNAMIC_ARRAY_dynamic_array *, void *);
+void VIV_DYNAMIC_ARRAY_add_head(VIV_DYNAMIC_ARRAY_dynamic_array *, void *);
+void *VIV_DYNAMIC_ARRAY_remove_tail(VIV_DYNAMIC_ARRAY_dynamic_array *);
+void *VIV_DYNAMIC_ARRAY_remove_head(VIV_DYNAMIC_ARRAY_dynamic_array *);
+void VIV_DYNAMIC_ARRAY_insert(VIV_DYNAMIC_ARRAY_dynamic_array *, unsigned int, void *);
+void *VIV_DYNAMIC_ARRAY_remove(VIV_DYNAMIC_ARRAY_dynamic_array *, unsigned int);
+void *VIV_DYNAMIC_ARRAY_get(const VIV_DYNAMIC_ARRAY_dynamic_array *, unsigned int);
+void *VIV_DYNAMIC_ARRAY_set(VIV_DYNAMIC_ARRAY_dynamic_array *, unsigned int, void *);
+void VIV_DYNAMIC_ARRAY_for_each(
+ const VIV_DYNAMIC_ARRAY_dynamic_array *,
+ VIV_DYNAMIC_ARRAY_for_function
+);
+unsigned int VIV_DYNAMIC_ARRAY_get_count(const VIV_DYNAMIC_ARRAY_dynamic_array *);
+void VIV_DYNAMIC_ARRAY_set_size(VIV_DYNAMIC_ARRAY_dynamic_array *, unsigned int);
+
+#endif /* VIV_DYNAMIC_ARRAY_H */
diff --git a/viv/CMakeLists.txt b/viv/CMakeLists.txt
index 852995f..663ec56 100644
--- a/viv/CMakeLists.txt
+++ b/viv/CMakeLists.txt
@@ -1,5 +1,6 @@
add_executable(${PROJECT_NAME}
cli.c
+ dynamic_array.c
gemini.c
flag.c
log.c
diff --git a/viv/dynamic_array.c b/viv/dynamic_array.c
new file mode 100644
index 0000000..6df62de
--- /dev/null
+++ b/viv/dynamic_array.c
@@ -0,0 +1,266 @@
+/* http://www.martinbroadhurst.com/dynamic-array-in-c.html */
+
+#include "viv/dynamic_array.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define START_SIZE 4 /* Initial buffer size if not specified */
+
+VIV_DYNAMIC_ARRAY_dynamic_array *VIV_DYNAMIC_ARRAY_create(unsigned int size) {
+ VIV_DYNAMIC_ARRAY_dynamic_array *array = malloc(
+ sizeof(VIV_DYNAMIC_ARRAY_dynamic_array)
+ );
+
+ if (array != NULL) {
+ if (size) {
+ array->buffer = malloc(size * sizeof(void *));
+ if (array->buffer) {
+ array->size = size;
+ } else {
+ free(array);
+ array = NULL;
+ }
+ } else {
+ array->buffer = NULL;
+ array->size = 0;
+ }
+
+ array->count = 0;
+ }
+
+ return array;
+}
+
+void VIV_DYNAMIC_ARRAY_empty(VIV_DYNAMIC_ARRAY_dynamic_array *array) {
+ array->count = 0;
+}
+
+void VIV_DYNAMIC_ARRAY_delete(VIV_DYNAMIC_ARRAY_dynamic_array *array) {
+ if (array) {
+ free(array->buffer);
+ free(array);
+ }
+}
+
+void VIV_DYNAMIC_ARRAY_add_tail(
+ VIV_DYNAMIC_ARRAY_dynamic_array *array,
+ void *data
+) {
+ if (array->count == array->size) {
+ /* No more space */
+ if (array->buffer != NULL) {
+ void **buffer = realloc(
+ array->buffer,
+ array->size * 2 * sizeof(void *)
+ );
+ array->buffer = buffer;
+ array->size *= 2;
+ } else {
+ array->buffer = malloc(START_SIZE * sizeof(void *));
+ array->size = START_SIZE;
+ }
+ }
+ if (array->buffer != NULL) {
+ array->buffer[array->count] = data;
+ array->count++;
+ }
+}
+
+void VIV_DYNAMIC_ARRAY_add_head(
+ VIV_DYNAMIC_ARRAY_dynamic_array *array,
+ void *data
+) {
+ if (array->count == array->size) {
+ /* No more space */
+ if (array->buffer != NULL) {
+ void **temp = malloc(array->size * 2 * sizeof(void *));
+ if (temp) {
+ /* Copy the elements one space to the right */
+ memcpy(temp + 1, array->buffer, array->count * sizeof(void *));
+ free(array->buffer);
+ array->buffer = temp;
+ array->size *= 2;
+ }
+ } else {
+ array->buffer = malloc(START_SIZE * sizeof(void *));
+ if (array->buffer) {
+ array->size = START_SIZE;
+ }
+ }
+ } else {
+ /* Move the elements one space to the right */
+ memmove(
+ array->buffer + 1,
+ array->buffer,
+ array->count * sizeof(void *)
+ );
+ }
+ if (array->buffer != NULL) {
+ array->buffer[0] = data;
+ array->count++;
+ }
+}
+
+void *VIV_DYNAMIC_ARRAY_remove_tail(VIV_DYNAMIC_ARRAY_dynamic_array *array) {
+ void *data = NULL;
+
+ if (array->count > 0) {
+ data = array->buffer[array->count - 1];
+ array->count--;
+ }
+
+ return data;
+}
+
+void *VIV_DYNAMIC_ARRAY_remove_head(VIV_DYNAMIC_ARRAY_dynamic_array *array) {
+ void *data = NULL;
+
+ if (array->count > 0) {
+ data = array->buffer[0];
+
+ /* Move the elements one space to the left */
+ memmove(
+ array->buffer,
+ array->buffer + 1,
+ (array->count - 1) * sizeof(void *)
+ );
+
+ array->count--;
+ }
+
+ return data;
+}
+
+void VIV_DYNAMIC_ARRAY_insert(
+ VIV_DYNAMIC_ARRAY_dynamic_array *array,
+ unsigned int pos,
+ void *data
+) {
+ if (pos == 0) {
+ VIV_DYNAMIC_ARRAY_add_head(array, data);
+ } else if (pos == array->count) {
+ VIV_DYNAMIC_ARRAY_add_tail(array, data);
+ } else if (pos < array->count) {
+ /* unsigned int i; */
+
+ if (array->count == array->size) {
+ /* Reallocate the buffer and copy, leaving a space */
+ void **temp = malloc(array->size * 2 * sizeof(void *));
+ if (temp) {
+ memcpy(temp, array->buffer, pos * sizeof(void *));
+ memcpy(
+ temp + pos + 1,
+ array->buffer + pos,
+ (array->count - pos) * sizeof(void *)
+ );
+ free(array->buffer);
+ array->buffer = temp;
+ array->size *= 2;
+ }
+ } else {
+ /* Move the elements after to the right */
+ memmove(
+ array->buffer + pos + 1, array->buffer + pos,
+ (array->count - pos) *sizeof(void *)
+ );
+ }
+
+ array->buffer[pos] = data;
+ array->count++;
+ }
+}
+
+void *VIV_DYNAMIC_ARRAY_remove(
+ VIV_DYNAMIC_ARRAY_dynamic_array *array,
+ unsigned int pos
+) {
+ void *data;
+
+ if (array->count < pos + 1) {
+ data = NULL;
+ } else if (pos == 0) {
+ data = VIV_DYNAMIC_ARRAY_remove_head(array);
+ } else if (pos == array->count - 1) {
+ data = VIV_DYNAMIC_ARRAY_remove_tail(array);
+ } else {
+ /* unsigned int i; */
+
+ data = array->buffer[pos];
+
+ /* Move the following elements left */
+ memmove(
+ array->buffer + pos, array->buffer + pos + 1,
+ (array->count - pos - 1) * sizeof(void *)
+ );
+
+ array->count--;
+ }
+
+ return data;
+}
+
+void *VIV_DYNAMIC_ARRAY_get(
+ const VIV_DYNAMIC_ARRAY_dynamic_array *array,
+ unsigned int pos
+) {
+ void *data = NULL;
+
+ if (pos < array->count) {
+ data = array->buffer[pos];
+ }
+
+ return data;
+}
+
+void *VIV_DYNAMIC_ARRAY_set(
+ VIV_DYNAMIC_ARRAY_dynamic_array *array,
+ unsigned int pos,
+ void *data
+) {
+ void *temp = NULL;
+
+ if (pos == array->count) {
+ VIV_DYNAMIC_ARRAY_add_tail(array, data);
+ } else if (pos < array->count) {
+ temp = array->buffer[pos];
+ array->buffer[pos] = data;
+ }
+
+ return temp;
+}
+
+void VIV_DYNAMIC_ARRAY_set_size(
+ VIV_DYNAMIC_ARRAY_dynamic_array *array,
+ unsigned int size
+) {
+ array->buffer = realloc(array->buffer, size);
+
+ if (array->buffer) {
+ array->size = size;
+
+ if (array->size < array->count) {
+ array->count = array->size;
+ }
+ } else {
+ array->size = 0;
+ array->count = 0;
+ }
+}
+
+void VIV_DYNAMIC_ARRAY_for_each(
+ const VIV_DYNAMIC_ARRAY_dynamic_array *array,
+ VIV_DYNAMIC_ARRAY_for_function function
+) {
+ unsigned int i;
+
+ for (i = 0; i < array->count; ++i) {
+ function(array->buffer[i]);
+ }
+}
+
+unsigned int VIV_DYNAMIC_ARRAY_get_count(
+ const VIV_DYNAMIC_ARRAY_dynamic_array *array
+) {
+ return array->count;
+}