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;
#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__)
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);