Code

Add more string utility functions and unit tests.
[sysdb.git] / src / utils / strings.c
index c07cfa1c2de1e0153f661c2a1553753d451788bb..b6a49e10ab36831d709f559cda7de4f5cfd8d79a 100644 (file)
 
 #include "utils/strings.h"
 
 
 #include "utils/strings.h"
 
+#include <assert.h>
+
 #include <stdlib.h>
 #include <string.h>
 
 /*
 #include <stdlib.h>
 #include <string.h>
 
 /*
- * public API
+ * private helper functions
  */
 
  */
 
-int
-stringv_copy(char ***dst, size_t *dst_len,
-               const char * const *src, size_t src_len)
+static int
+ensure_len(char ***s, size_t *s_len, size_t len)
 {
        char **tmp;
 {
        char **tmp;
-       size_t i;
 
 
-       if (*dst) {
-               tmp = realloc(*dst, src_len * sizeof(*tmp));
-               if (tmp)
-                       memset(tmp, 0, src_len * sizeof(*tmp));
+       if ((! s) || (! s_len))
+               return -1;
+
+       if (! len) {
+               if (*s)
+                       free(*s);
+               *s = NULL;
+               *s_len = 0;
+               return 0;
+       }
+
+       if (*s) {
+               tmp = realloc(*s, len * sizeof(*tmp));
+               if (tmp && (len > *s_len))
+                       memset(tmp + *s_len, 0, (len - *s_len) * sizeof(*tmp));
        }
        else
        }
        else
-               tmp = calloc(src_len, sizeof(*tmp));
+               tmp = calloc(len, sizeof(*tmp));
 
        if (! tmp)
                return -1;
 
 
        if (! tmp)
                return -1;
 
-       *dst = tmp;
-       *dst_len = src_len;
+       *s = tmp;
+       *s_len = len;
+       return 0;
+} /* ensure_len */
+
+/*
+ * public API
+ */
+
+int
+stringv_copy(char ***dst, size_t *dst_len,
+               const char * const *src, size_t src_len)
+{
+       size_t i;
+
+       if (src_len && (! src))
+               return -1;
+       if (ensure_len(dst, dst_len, src_len))
+               return -1;
+       assert(dst);
+
        for (i = 0; i < src_len; ++i) {
        for (i = 0; i < src_len; ++i) {
+               if ((*dst)[i])
+                       free((*dst)[i]);
                (*dst)[i] = strdup(src[i]);
                if (! (*dst)[i])
                        return -1;
                (*dst)[i] = strdup(src[i]);
                if (! (*dst)[i])
                        return -1;
@@ -66,6 +98,22 @@ stringv_copy(char ***dst, size_t *dst_len,
        return 0;
 } /* stringv_copy */
 
        return 0;
 } /* stringv_copy */
 
+int
+stringv_append(char ***s, size_t *s_len, const char *elem)
+{
+       size_t i;
+
+       if ((! s_len) || ensure_len(s, s_len, *s_len + 1))
+               return -1;
+       assert(s);
+
+       i = *s_len - 1;
+       (*s)[i] = strdup(elem);
+       if (! (*s)[i])
+               return -1;
+       return 0;
+} /* stringv_append */
+
 void
 stringv_free(char ***s, size_t *s_len)
 {
 void
 stringv_free(char ***s, size_t *s_len)
 {