diff --git a/src/utils/strings.c b/src/utils/strings.c
index c07cfa1c2de1e0153f661c2a1553753d451788bb..d7668f076a27fc087262420e0c84ac86a83308d3 100644 (file)
--- a/src/utils/strings.c
+++ b/src/utils/strings.c
#include "utils/strings.h"
+#include <assert.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;
- 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
- tmp = calloc(src_len, sizeof(*tmp));
+ tmp = calloc(len, sizeof(*tmp));
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) {
+ if ((*dst)[i])
+ free((*dst)[i]);
(*dst)[i] = strdup(src[i]);
if (! (*dst)[i])
return -1;
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 */
+
+int
+stringv_append_if_missing(char ***s, size_t *s_len, const char *elem)
+{
+ size_t i;
+
+ if ((! s) || (! s_len))
+ return -1;
+
+ for (i = 0; i < *s_len; i++)
+ if (! strcmp((*s)[i], elem))
+ return 0;
+
+ return stringv_append(s, s_len, elem);
+} /* stringv_append_if_missing */
+
void
stringv_free(char ***s, size_t *s_len)
{