summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-06-27 10:33:14 +0200
committerThomas Haller <thaller@redhat.com>2019-06-28 16:48:17 +0200
commitb4fe51b5faa259f971a9e3d23cfba844526f6c13 (patch)
treea3f9585af32801ee92d41cf48b4dd3c57ae149ea
parent1d2df314cc9cbe242b3b1533777b834c6418408d (diff)
downloadNetworkManager-b4fe51b5faa259f971a9e3d23cfba844526f6c13.tar.gz
shared: add nm_utils_strv_dup() util
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.c56
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.h2
2 files changed, 58 insertions, 0 deletions
diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c
index 472a4c484f..7362dfc930 100644
--- a/shared/nm-glib-aux/nm-shared-utils.c
+++ b/shared/nm-glib-aux/nm-shared-utils.c
@@ -2345,6 +2345,62 @@ nm_utils_strv_make_deep_copied_n (const char **strv, gsize len)
return (char **) strv;
}
+/**
+ * @strv: the strv array to copy. It may be %NULL if @len
+ * is negative or zero (in which case %NULL will be returned).
+ * @len: the length of strings in @str. If negative, strv is assumed
+ * to be a NULL terminated array.
+ *
+ * Like g_strdupv(), with two differences:
+ *
+ * - accepts a @len parameter for non-null terminated strv array.
+ *
+ * - this never returns an empty strv array, but always %NULL if
+ * there are no strings.
+ *
+ * Note that if @len is non-negative, then it still must not
+ * contain any %NULL pointers within the first @len elements.
+ * Otherwise you would leak elements if you try to free the
+ * array with g_strfreev(). Allowing that would be error prone.
+ *
+ * Returns: (transfer full): a clone of the strv array. Always
+ * %NULL terminated.
+ */
+char **
+nm_utils_strv_dup (gpointer strv, gssize len)
+{
+ gsize i, l;
+ char **v;
+ const char *const *const src = strv;
+
+ if (len < 0)
+ l = NM_PTRARRAY_LEN (src);
+ else
+ l = len;
+ if (l == 0) {
+ /* this function never returns an empty strv array. If you
+ * need that, handle it yourself. */
+ return NULL;
+ }
+
+ v = g_new (char *, l + 1);
+ for (i = 0; i < l; i++) {
+
+ if (G_UNLIKELY (!src[i])) {
+ /* NULL strings are not allowed. Clear the remainder of the array
+ * and return it (with assertion failure). */
+ l++;
+ for (; i < l; i++)
+ v[i] = NULL;
+ g_return_val_if_reached (v);
+ }
+
+ v[i] = g_strdup (src[i]);
+ }
+ v[l] = NULL;
+ return v;
+}
+
/*****************************************************************************/
gssize
diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h
index e65d1be683..7de6c06208 100644
--- a/shared/nm-glib-aux/nm-shared-utils.h
+++ b/shared/nm-glib-aux/nm-shared-utils.h
@@ -979,6 +979,8 @@ nm_utils_strv_make_deep_copied_nonnull (const char **strv)
return nm_utils_strv_make_deep_copied (strv) ?: g_new0 (char *, 1);
}
+char **nm_utils_strv_dup (gpointer strv, gssize len);
+
/*****************************************************************************/
GSList *nm_utils_g_slist_find_str (const GSList *list,