summaryrefslogtreecommitdiffstats
path: root/hw4/l4basic/l4strv.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw4/l4basic/l4strv.c')
-rw-r--r--hw4/l4basic/l4strv.c297
1 files changed, 297 insertions, 0 deletions
diff --git a/hw4/l4basic/l4strv.c b/hw4/l4basic/l4strv.c
new file mode 100644
index 0000000..b05ad5b
--- /dev/null
+++ b/hw4/l4basic/l4strv.c
@@ -0,0 +1,297 @@
+/* vim: set sw=4 ts=4 sts=4 et: */
+
+#include "l4strv.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+LbsStrv* lbs_strv_new_with_max (size_t max) {
+ LbsStrv* strv = xmalloc (sizeof (LbsStrv));
+ if (strv == NULL) {
+ return NULL;
+ }
+
+ if (lbs_array_init_with_max (&strv->array, sizeof (LbsArray), max) < 0) {
+ free (strv);
+ return NULL;
+ }
+
+ strv->ref_count = 1;
+ strv->is_alloc = true;
+ return strv;
+}
+
+int lbs_strv_init_with_max (LbsStrv* strv, size_t max) {
+ if (lbs_array_init_with_max (&strv->array, sizeof (LbsArray), max) < 0) {
+ return -1;
+ }
+
+ strv->ref_count = 1;
+ strv->is_alloc = false;
+ return 0;
+}
+
+void* lbs_strv_ref_generic (void* strv_generic) {
+ LbsStrv* strv = LBS_STRV (strv_generic);
+ strv->ref_count++;
+ return strv;
+}
+
+void lbs_strv_unref_generic (void* strv_generic) {
+ if (strv_generic == NULL) {
+ return;
+ }
+ LbsStrv* strv = LBS_STRV (strv_generic);
+ strv->ref_count--;
+ if (strv->ref_count <= 0) {
+ lbs_strv_free (strv);
+ }
+}
+
+void lbs_strv_free_generic (void* strv_generic) {
+ if (strv_generic == NULL) {
+ return;
+ }
+ LbsStrv* strv = LBS_STRV (strv_generic);
+ size_t i = 0;
+ for (; i < lbs_strv_get_len (strv); i++) {
+ LbsArray* str_wrapper = lbs_strv_get_str_wrapper (strv, i);
+ lbs_array_unref (str_wrapper);
+ }
+ lbs_array_unref (&strv->array);
+ if (strv->is_alloc) {
+ free (strv);
+ }
+}
+
+char* lbs_strv_dup_str (LbsStrv* strv, size_t stri) {
+ LbsArray* str_wrapper = lbs_strv_get_str_wrapper (strv, stri);
+ size_t len = lbs_array_get_len (str_wrapper);
+ char* str = lbs_array_get_data (str_wrapper);
+
+ char* str_new = xmalloc (len + sizeof (char));
+ strncpy (str_new, str, len);
+ str_new[len] = '\0';
+
+ return str_new;
+}
+
+int lbs_strv_append_char (LbsStrv* strv, size_t stri, char chr) {
+ if (chr == '\0') {
+ return -1;
+ }
+
+ if (stri >= lbs_strv_get_len (strv)) {
+ stri = lbs_strv_get_len (strv);
+ LbsArray str_struct;
+ LbsArray* str = &str_struct;
+ if (lbs_array_init (str, sizeof (char)) < 0) {
+ return -1;
+ }
+ if (lbs_array_append_data (&strv->array, str) < 0) {
+ lbs_array_unref (str);
+ return -1;
+ }
+ }
+ LbsArray* str = lbs_strv_get_str_wrapper (strv, stri);
+ return lbs_array_append_data (str, &chr);
+}
+
+int lbs_strv_append_str_empty (LbsStrv* strv) {
+ LbsArray str_struct, *str = &str_struct;
+ if (lbs_array_init (str, sizeof (char)) < 0) {
+ return -1;
+ }
+ if (lbs_array_append_data (&strv->array, &str_struct) < 0) {
+ lbs_array_unref (str);
+ return -1;
+ }
+ return 0;
+}
+
+int lbs_strv_append_str (LbsStrv* strv, const char* bstr) {
+ if (bstr == NULL) {
+ return -1;
+ }
+
+ size_t len = strlen (bstr);
+ char* str_copy = xmalloc (sizeof (char) * len);
+ if (str_copy == NULL) {
+ return -1;
+ }
+ strncpy (str_copy, bstr, len);
+
+ LbsArray str_struct, *str = &str_struct;
+ if (lbs_array_make_struct (str, sizeof (char), len, len, str_copy) == NULL)
+ {
+ free (str_copy);
+ return -1;
+ }
+
+ if (lbs_array_append_data (&strv->array, &str_struct) < 0) {
+ lbs_array_unref (str);
+ free (str_copy);
+ return -1;
+ }
+
+ return 0;
+}
+
+int lbs_strv_append_strv (LbsStrv* strv, const char* const* bstrv) {
+ if (bstrv == NULL) {
+ return -1;
+ }
+
+ int i;
+ for (i = 0; bstrv[i] != NULL; i++) {
+ if (lbs_strv_append_str (strv, bstrv[i]) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int lbs_strv_remove_str (LbsStrv* strv) {
+ size_t len = lbs_strv_get_len (strv);
+ if (len <= 0) {
+ return -1;
+ }
+
+ lbs_array_unref (lbs_strv_get_str_wrapper (strv, len - 1));
+ return lbs_array_remove (&strv->array);
+}
+
+int lbs_strv_minimize (LbsStrv* strv) {
+ if (lbs_array_minimize (&strv->array) < 0) {
+ return -1;
+ }
+
+ size_t i;
+ size_t len = lbs_strv_get_len (strv);
+ for (i = 0; i < len; i++) {
+ LbsArray* str = lbs_strv_get_str_wrapper (strv, i);
+ if (lbs_array_minimize (str) < 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+char** lbs_strv_copy_strv (LbsStrv* strv) {
+ size_t len = lbs_strv_get_len (strv);
+ char** bstrv = xmalloc (sizeof (char*) * (len + 1));
+ if (bstrv == NULL) {
+ return NULL;
+ }
+
+ size_t i;
+ for (i = 0; i < len; i++) {
+ LbsArray* str = lbs_strv_get_str_wrapper (strv, i);
+ size_t str_len = lbs_array_get_len (str);
+ char* bstr = xmalloc (sizeof (char) * (str_len + 1));
+
+ strncpy (bstr, lbs_array_get_data (str), str_len);
+ bstr[str_len] = '\0';
+ bstrv[i] = bstr;
+ }
+ bstrv[len] = NULL;
+ return bstrv;
+}
+
+char** lbs_strv_drop_struct (LbsStrv* strv) {
+ char** bstrv = lbs_strv_copy_strv (strv);
+ if (bstrv == NULL) {
+ return NULL;
+ }
+
+ lbs_strv_free (strv);
+ return bstrv;
+}
+
+char** lbs_strv_generic_build (const char* str_first, ...) {
+ LbsArray bstrv_w_struct, *bstrv_w = &bstrv_w_struct;
+ va_list ap;
+ char* str;
+ char* str_copy;
+ size_t str_len;
+
+ if (lbs_array_init (bstrv_w, sizeof (void*)) < 0) {
+ return NULL;
+ }
+
+ va_start (ap, str_first);
+
+ str_len = strlen (str_first);
+ str_copy = xmalloc (sizeof (char) * (str_len + 1));
+ if (str_copy == NULL) {
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+ strcpy (str_copy, str_first);
+
+ if (lbs_array_append_ptr (bstrv_w, str_copy) < 0) {
+ free (str_copy);
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+
+
+ while ((str = va_arg (ap, char*)) != NULL) {
+ str_len = strlen (str);
+ str_copy = xmalloc (sizeof (char) * (str_len + 1));
+ if (str_copy == NULL) {
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+ strcpy (str_copy, str);
+
+ if (lbs_array_append_ptr (bstrv_w, str_copy) < 0) {
+ free (str_copy);
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+ }
+ if (lbs_array_append_ptr (bstrv_w, NULL) < 0) {
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+
+ va_end (ap);
+
+ return lbs_array_drop_struct (bstrv_w);
+}
+
+int lbs_strv_generic_cmp (
+ const char* const* bstrv1, const char* const* bstrv2) {
+ int i;
+ for (i = 0; bstrv1[i] != NULL && bstrv2[i] != NULL; i++) {
+ int r = strcmp (bstrv1[i], bstrv2[i]);
+ if (r != 0) {
+ return r;
+ }
+ }
+
+ if (bstrv1[i] != NULL) {
+ return 1;
+ }
+ if (bstrv2[i] != NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void lbs_strv_generic_free (char** bstrv) {
+ int i;
+ for (i = 0; bstrv[i] != NULL; i++) {
+ free (bstrv[i]);
+ }
+ free (bstrv);
+}