From 892c5902ae11e5b0ca0494411067794d763baf45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 15 Mar 2024 13:16:51 +0100 Subject: [PATCH] src/basic: add yet another strdup helper It's a bit ugly to have both strdup_to() and strdup_to_full(). I initially started with one variant, but then in some functions we want the additional info, while in many other places, having 1 instead of 0 causes the return value of whole chains of functions to be changed. It *probably* wouldn't cause any difference, but there is at least of bunch of tests that would need to be updated, so in the end it seems to have the two variants. The output param is first to match free_and_strdup() and other similar functions. --- src/basic/string-util.c | 18 ++++++++++++++++++ src/basic/string-util.h | 6 ++++++ src/test/test-string-util.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/src/basic/string-util.c b/src/basic/string-util.c index c1e7e6e622..6e8d10747b 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -1126,6 +1126,24 @@ int free_and_strndup(char **p, const char *s, size_t l) { return 1; } +int strdup_to_full(char **ret, const char *src) { + if (!src) { + if (ret) + *ret = NULL; + + return 0; + } else { + if (ret) { + char *t = strdup(src); + if (!t) + return -ENOMEM; + *ret = t; + } + + return 1; + } +}; + bool string_is_safe(const char *p) { if (!p) return false; diff --git a/src/basic/string-util.h b/src/basic/string-util.h index e162765aa7..c402cd3af0 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -224,6 +224,12 @@ static inline int free_and_strdup_warn(char **p, const char *s) { } int free_and_strndup(char **p, const char *s, size_t l); +int strdup_to_full(char **ret, const char *src); +static inline int strdup_to(char **ret, const char *src) { + int r = strdup_to_full(ASSERT_PTR(ret), src); + return r < 0 ? r : 0; /* Suppress return value of 1. */ +} + bool string_is_safe(const char *p) _pure_; DISABLE_WARNING_STRINGOP_TRUNCATION; diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c index 92f1083a4c..3b003e885f 100644 --- a/src/test/test-string-util.c +++ b/src/test/test-string-util.c @@ -88,6 +88,35 @@ TEST(free_and_strndup) { } } +TEST(strdup_to_full) { + _cleanup_free_ char *dst; + + assert_se(strdup_to_full(NULL, NULL) == 0); + assert_se(strdup_to_full(&dst, NULL) == 0); + + assert_se(strdup_to_full(NULL, "") == 1); + assert_se(strdup_to_full(&dst, "") == 1); + assert_se(streq_ptr(dst, "")); + dst = mfree(dst); + + assert_se(strdup_to_full(NULL, "x") == 1); + assert_se(strdup_to_full(&dst, "x") == 1); + assert_se(streq_ptr(dst, "x")); +} + +TEST(strdup_to) { + _cleanup_free_ char *dst; + + assert_se(strdup_to(&dst, NULL) == 0); + + assert_se(strdup_to(&dst, "") == 0); + assert_se(streq_ptr(dst, "")); + dst = mfree(dst); + + assert_se(strdup_to(&dst, "x") == 0); + assert_se(streq_ptr(dst, "x")); +} + TEST(ascii_strcasecmp_n) { assert_se(ascii_strcasecmp_n("", "", 0) == 0); assert_se(ascii_strcasecmp_n("", "", 1) == 0);