summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-04-02 12:21:46 +0200
committerThomas Haller <thaller@redhat.com>2019-04-04 21:01:15 +0200
commit2861a7ae0a7ceaa8b0d6726f5ca88b7c2841a928 (patch)
tree16486e3a74206024b9ad5107e5066803c10444c7
parent26d144d5a030875c3eaf62eb437a270f64ff729a (diff)
downloadNetworkManager-2861a7ae0a7ceaa8b0d6726f5ca88b7c2841a928.tar.gz
shared: add nm_strstrip_avoid_copy_a() helper
-rw-r--r--shared/nm-utils/nm-macros-internal.h28
-rw-r--r--shared/nm-utils/tests/test-shared-general.c52
2 files changed, 80 insertions, 0 deletions
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index b2668f8e37..25e5559744 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -1386,6 +1386,34 @@ nm_strstrip_avoid_copy (const char *str, char **str_free)
return s;
}
+#define nm_strstrip_avoid_copy_a(alloca_maxlen, str, out_str_free) \
+ ({ \
+ const char *_str_ssac = (str); \
+ char **_out_str_free_ssac = (out_str_free); \
+ \
+ G_STATIC_ASSERT_EXPR ((alloca_maxlen) > 0); \
+ \
+ nm_assert ( _out_str_free_ssac || ((alloca_maxlen) > (str ? strlen (str) : 0u))); \
+ nm_assert (!_out_str_free_ssac || !*_out_str_free_ssac); \
+ \
+ if (_str_ssac) { \
+ _str_ssac = nm_str_skip_leading_spaces (_str_ssac); \
+ if (_str_ssac[0] != '\0') { \
+ gsize _l = strlen (_str_ssac); \
+ \
+ if (g_ascii_isspace (_str_ssac[--_l])) { \
+ while ( _l > 0 \
+ && g_ascii_isspace (_str_ssac[_l - 1])) { \
+ _l--; \
+ } \
+ _str_ssac = nm_strndup_a ((alloca_maxlen), _str_ssac, _l, _out_str_free_ssac); \
+ } \
+ } \
+ } \
+ \
+ _str_ssac; \
+ })
+
/* g_ptr_array_sort()'s compare function takes pointers to the
* value. Thus, you cannot use strcmp directly. You can use
* nm_strcmp_p().
diff --git a/shared/nm-utils/tests/test-shared-general.c b/shared/nm-utils/tests/test-shared-general.c
index 5b220c10e0..f56bd15e50 100644
--- a/shared/nm-utils/tests/test-shared-general.c
+++ b/shared/nm-utils/tests/test-shared-general.c
@@ -392,6 +392,57 @@ test_strv_cmp (void)
/*****************************************************************************/
+static void
+_do_strstrip_avoid_copy (const char *str)
+{
+ gs_free char *str1 = g_strdup (str);
+ gs_free char *str2 = g_strdup (str);
+ gs_free char *str3 = NULL;
+ gs_free char *str4 = NULL;
+ const char *s3;
+ const char *s4;
+
+ if (str1)
+ g_strstrip (str1);
+
+ nm_strstrip (str2);
+
+ g_assert_cmpstr (str1, ==, str2);
+
+ s3 = nm_strstrip_avoid_copy (str, &str3);
+ g_assert_cmpstr (str1, ==, s3);
+
+ s4 = nm_strstrip_avoid_copy_a (10, str, &str4);
+ g_assert_cmpstr (str1, ==, s4);
+ g_assert (!str == !s4);
+ g_assert (!s4 || strlen (s4) <= strlen (str));
+ if (s4 && s4 == &str[strlen (str) - strlen (s4)]) {
+ g_assert (!str4);
+ g_assert (s3 == s4);
+ } else if (s4 && strlen (s4) >= 10) {
+ g_assert (str4);
+ g_assert (s4 == str4);
+ } else
+ g_assert (!str4);
+
+ if (!nm_streq0 (str1, str))
+ _do_strstrip_avoid_copy (str1);
+}
+
+static void
+test_strstrip_avoid_copy (void)
+{
+ _do_strstrip_avoid_copy (NULL);
+ _do_strstrip_avoid_copy ("");
+ _do_strstrip_avoid_copy (" ");
+ _do_strstrip_avoid_copy (" a ");
+ _do_strstrip_avoid_copy (" 012345678 ");
+ _do_strstrip_avoid_copy (" 0123456789 ");
+ _do_strstrip_avoid_copy (" 01234567890 ");
+ _do_strstrip_avoid_copy (" 012345678901 ");
+}
+/*****************************************************************************/
+
NMTST_DEFINE ();
int main (int argc, char **argv)
@@ -406,6 +457,7 @@ int main (int argc, char **argv)
g_test_add_func ("/general/test_nm_ip4_addr_is_localhost", test_nm_ip4_addr_is_localhost);
g_test_add_func ("/general/test_unaligned", test_unaligned);
g_test_add_func ("/general/test_strv_cmp", test_strv_cmp);
+ g_test_add_func ("/general/test_strstrip_avoid_copy", test_strstrip_avoid_copy);
return g_test_run ();
}