summaryrefslogtreecommitdiff
path: root/src/string_vec.c
diff options
context:
space:
mode:
authorPhil Jones <philj56@gmail.com>2021-11-06 18:44:27 +0000
committerPhil Jones <philj56@gmail.com>2021-11-06 19:02:29 +0000
commitae23e86114f559ce6d01a3e2499fc5417dc90d37 (patch)
treec55d7f3c3b131efd50ec2a6f884b48f9ce250c63 /src/string_vec.c
parentc28c5249c4d3ba7076e2c6ea598e3ad93a168301 (diff)
Start conversion to tofi.
Diffstat (limited to 'src/string_vec.c')
-rw-r--r--src/string_vec.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/string_vec.c b/src/string_vec.c
new file mode 100644
index 0000000..94f41fa
--- /dev/null
+++ b/src/string_vec.c
@@ -0,0 +1,84 @@
+#include <stdlib.h>
+#include <string.h>
+#include "string_vec.h"
+
+static int cmpstringp(const void *a, const void *b)
+{
+ /*
+ * We receive pointers to the array elements (which are pointers to
+ * char), so convert and dereference them for comparison.
+ */
+ const char *str1 = *(const char **)a;
+ const char *str2 = *(const char **)b;
+
+ /*
+ * Ensure any NULL strings are shoved to the end.
+ */
+ if (str1 == NULL) {
+ return 1;
+ }
+ if (str2 == NULL) {
+ return -1;
+ }
+ return strcmp(str1, str2);
+}
+
+struct string_vec string_vec_create()
+{
+ struct string_vec vec = {
+ .count = 0,
+ .size = 128,
+ .buf = calloc(128, sizeof(char *))
+ };
+ return vec;
+}
+
+void string_vec_destroy(struct string_vec *restrict vec)
+{
+ for (size_t i = 0; i < vec->count; i++) {
+ free(vec->buf[i]);
+ }
+ free(vec->buf);
+}
+
+void string_vec_add(struct string_vec *restrict vec, const char *restrict str)
+{
+ if (vec->count == vec->size) {
+ vec->size *= 2;
+ vec->buf = realloc(vec->buf, vec->size * sizeof(vec->buf[0]));
+ }
+ vec->buf[vec->count] = strdup(str);
+ vec->count++;
+}
+
+void string_vec_sort(struct string_vec *restrict vec)
+{
+ qsort(vec->buf, vec->count, sizeof(vec->buf[0]), cmpstringp);
+}
+
+void string_vec_uniq(struct string_vec *restrict vec)
+{
+ size_t count = vec->count;
+ for (size_t i = 1; i < vec->count; i++) {
+ if (!strcmp(vec->buf[i], vec->buf[i-1])) {
+ free(vec->buf[i-1]);
+ vec->buf[i-1] = NULL;
+ count--;
+ }
+ }
+ string_vec_sort(vec);
+ vec->count = count;
+}
+
+struct string_vec string_vec_filter(
+ struct string_vec *restrict vec,
+ const char *restrict substr)
+{
+ struct string_vec filt = string_vec_create();
+ for (size_t i = 0; i < vec->count; i++) {
+ if (strstr(vec->buf[i], substr) != NULL) {
+ string_vec_add(&filt, vec->buf[i]);
+ }
+ }
+ return filt;
+}