string-util: simplify logic in strjoin_real()

The loops over (x, then all varargs, until a NULL is found) can be written much
simpler with an ordinary for loop. Just initialize the loop variable to x, test
that, and in the increment part, fetch the next va_arg(). That removes a level
of indentation, and avoids doing a separate strlen()/stpcpy() call for x.

While touching this code anyway, change (size_t)-1 to the more readable
SIZE_MAX.
This commit is contained in:
Rasmus Villemoes 2020-10-30 10:13:27 +01:00
parent cd20659891
commit 020003f235
1 changed files with 15 additions and 40 deletions

View File

@ -145,57 +145,32 @@ char *strnappend(const char *s, const char *suffix, size_t b) {
char *strjoin_real(const char *x, ...) {
va_list ap;
size_t l;
size_t l = 0;
char *r, *p;
va_start(ap, x);
for (const char *t = x; t; t = va_arg(ap, const char *)) {
size_t n;
if (x) {
l = strlen(x);
for (;;) {
const char *t;
size_t n;
t = va_arg(ap, const char *);
if (!t)
break;
n = strlen(t);
if (n > ((size_t) -1) - l) {
va_end(ap);
return NULL;
}
l += n;
n = strlen(t);
if (n > SIZE_MAX - l) {
va_end(ap);
return NULL;
}
} else
l = 0;
l += n;
}
va_end(ap);
r = new(char, l+1);
p = r = new(char, l+1);
if (!r)
return NULL;
if (x) {
p = stpcpy(r, x);
va_start(ap, x);
for (const char *t = x; t; t = va_arg(ap, const char *))
p = stpcpy(p, t);
va_end(ap);
va_start(ap, x);
for (;;) {
const char *t;
t = va_arg(ap, const char *);
if (!t)
break;
p = stpcpy(p, t);
}
va_end(ap);
} else
r[0] = 0;
*p = 0;
return r;
}