]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
string-util: add strextendn() helper
authorLennart Poettering <lennart@poettering.net>
Mon, 26 Jun 2023 15:15:28 +0000 (17:15 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 27 Jun 2023 11:49:46 +0000 (13:49 +0200)
src/basic/string-util.c
src/basic/string-util.h
src/test/test-string-util.c

index 1eedcb66f7cf3e2c562d1f789aa4822462d99469..d5e1d4e92dd5f11097ade8b897c0f3ad8384e957 100644 (file)
@@ -891,6 +891,33 @@ oom:
         return -ENOMEM;
 }
 
+char *strextendn(char **x, const char *s, size_t l) {
+        assert(x);
+        assert(s || l == 0);
+
+        if (l == SIZE_MAX)
+                l = strlen_ptr(s);
+        else if (l > 0)
+                l = strnlen(s, l); /* ignore trailing noise */
+
+        if (l > 0 || !*x) {
+                size_t q;
+                char *m;
+
+                q = strlen_ptr(*x);
+                m = realloc(*x, q + l + 1);
+                if (!m)
+                        return NULL;
+
+                memcpy_safe(m + q, s, l);
+                m[q + l] = 0;
+
+                *x = m;
+        }
+
+        return *x;
+}
+
 char *strrep(const char *s, unsigned n) {
         char *r, *p;
         size_t l;
index 0ff5b46bba93d74dee0cb132f1356f9f57049d2c..ce6ea64bb911637383bd55200b6cf39e92657c95 100644 (file)
@@ -186,6 +186,8 @@ char *strextend_with_separator_internal(char **x, const char *separator, ...) _s
 #define strextend_with_separator(x, separator, ...) strextend_with_separator_internal(x, separator, __VA_ARGS__, NULL)
 #define strextend(x, ...) strextend_with_separator_internal(x, NULL, __VA_ARGS__, NULL)
 
+char *strextendn(char **x, const char *s, size_t l);
+
 int strextendf_with_separator(char **x, const char *separator, const char *format, ...) _printf_(3,4);
 #define strextendf(x, ...) strextendf_with_separator(x, NULL, __VA_ARGS__)
 
index e8fcc5a13c98c1ebc24c3407255773b407847d73..6ec70054e785c2340a977e54cf7d4fc5373be427 100644 (file)
@@ -1274,4 +1274,22 @@ TEST(version_is_valid) {
         assert_se(version_is_valid("6.2.12-300.fc38.x86_64"));
 }
 
+TEST(strextendn) {
+        _cleanup_free_ char *x = NULL;
+
+        assert_se(streq_ptr(strextendn(&x, NULL, 0), ""));
+        x = mfree(x);
+
+        assert_se(streq_ptr(strextendn(&x, "", 0), ""));
+        x = mfree(x);
+
+        assert_se(streq_ptr(strextendn(&x, "xxx", 3), "xxx"));
+        assert_se(streq_ptr(strextendn(&x, "xxx", 3), "xxxxxx"));
+        assert_se(streq_ptr(strextendn(&x, "...", 1), "xxxxxx."));
+        assert_se(streq_ptr(strextendn(&x, "...", 2), "xxxxxx..."));
+        assert_se(streq_ptr(strextendn(&x, "...", 3), "xxxxxx......"));
+        assert_se(streq_ptr(strextendn(&x, "...", 4), "xxxxxx........."));
+        x = mfree(x);
+}
+
 DEFINE_TEST_MAIN(LOG_DEBUG);