summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2017-11-28 16:37:53 +0100
committerSven Eden <yamakuzure@gmx.net>2017-11-28 16:37:53 +0100
commit14728b9406dccbf6a74f21aaa1cc524273edbb15 (patch)
tree4fc519fe247975bf439aa82531799b18eb6de4de /src/basic
parent8a5a474e846f8810cb3861ed869da35db74f9a97 (diff)
string-util: rework strextend() to optionally inset separators between each appended string
This adds a new flavour of strextend(), called strextend_with_separator(), which takes an optional separator string. If specified, the separator is inserted between each appended string, as well as before the first one, but only if the original string was non-empty. This new call is particularly useful when appending new options to mount option strings and suchlike, which need to be comma-separated, and initially start out from an empty string.
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/string-util.c28
-rw-r--r--src/basic/string-util.h4
2 files changed, 26 insertions, 6 deletions
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index 445766e4a..704d020b2 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -708,16 +708,20 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
return obuf;
}
-char *strextend(char **x, ...) {
- va_list ap;
- size_t f, l;
+char *strextend_with_separator(char **x, const char *separator, ...) {
+ bool need_separator;
+ size_t f, l, l_separator;
char *r, *p;
+ va_list ap;
assert(x);
l = f = strlen_ptr(*x);
- va_start(ap, x);
+ need_separator = !isempty(*x);
+ l_separator = strlen_ptr(separator);
+
+ va_start(ap, separator);
for (;;) {
const char *t;
size_t n;
@@ -727,22 +731,29 @@ char *strextend(char **x, ...) {
break;
n = strlen(t);
+
+ if (need_separator)
+ n += l_separator;
+
if (n > ((size_t) -1) - l) {
va_end(ap);
return NULL;
}
l += n;
+ need_separator = true;
}
va_end(ap);
+ need_separator = !isempty(*x);
+
r = realloc(*x, l+1);
if (!r)
return NULL;
p = r + f;
- va_start(ap, x);
+ va_start(ap, separator);
for (;;) {
const char *t;
@@ -750,10 +761,17 @@ char *strextend(char **x, ...) {
if (!t)
break;
+ if (need_separator && separator)
+ p = stpcpy(p, separator);
+
p = stpcpy(p, t);
+
+ need_separator = true;
}
va_end(ap);
+ assert(p == r + l);
+
*p = 0;
*x = r;
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index f68b5f2f3..7276cfd6f 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -174,7 +174,9 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
char *strip_tab_ansi(char **p, size_t *l);
-char *strextend(char **x, ...) _sentinel_;
+char *strextend_with_separator(char **x, const char *separator, ...) _sentinel_;
+
+#define strextend(x, ...) strextend_with_separator(x, NULL, __VA_ARGS__)
char *strrep(const char *s, unsigned n);