/* 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); }