Merge pull request #19672 from yuwata/strextend
tree-wide: introduce strextendf_with_separator() and use strextend() or freinds
This commit is contained in:
+3
-12
@@ -572,12 +572,9 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
|
||||
|
||||
t = strv_env_get_n(env, word+2, e-word-2, flags);
|
||||
|
||||
k = strjoin(r, t);
|
||||
if (!k)
|
||||
if (!strextend(&r, t))
|
||||
return NULL;
|
||||
|
||||
free_and_replace(r, k);
|
||||
|
||||
word = e+1;
|
||||
state = WORD;
|
||||
} else if (*e == ':') {
|
||||
@@ -627,12 +624,9 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
|
||||
else if (!t && state == DEFAULT_VALUE)
|
||||
t = v = replace_env_n(test_value, e-test_value, env, flags);
|
||||
|
||||
k = strjoin(r, t);
|
||||
if (!k)
|
||||
if (!strextend(&r, t))
|
||||
return NULL;
|
||||
|
||||
free_and_replace(r, k);
|
||||
|
||||
word = e+1;
|
||||
state = WORD;
|
||||
}
|
||||
@@ -646,12 +640,9 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
|
||||
|
||||
t = strv_env_get_n(env, word+1, e-word-1, flags);
|
||||
|
||||
k = strjoin(r, t);
|
||||
if (!k)
|
||||
if (!strextend(&r, t))
|
||||
return NULL;
|
||||
|
||||
free_and_replace(r, k);
|
||||
|
||||
word = e--;
|
||||
i--;
|
||||
state = WORD;
|
||||
|
||||
+18
-13
@@ -790,8 +790,8 @@ char *strextend_with_separator_internal(char **x, const char *separator, ...) {
|
||||
return p;
|
||||
}
|
||||
|
||||
int strextendf(char **x, const char *format, ...) {
|
||||
size_t m, a;
|
||||
int strextendf_with_separator(char **x, const char *separator, const char *format, ...) {
|
||||
size_t m, a, l_separator;
|
||||
va_list ap;
|
||||
int l;
|
||||
|
||||
@@ -802,6 +802,8 @@ int strextendf(char **x, const char *format, ...) {
|
||||
assert(x);
|
||||
assert(format);
|
||||
|
||||
l_separator = isempty(*x) ? 0 : strlen_ptr(separator);
|
||||
|
||||
/* Let's try to use the allocated buffer, if there's room at the end still. Otherwise let's extend by 64 chars. */
|
||||
if (*x) {
|
||||
m = strlen(*x);
|
||||
@@ -810,13 +812,15 @@ int strextendf(char **x, const char *format, ...) {
|
||||
} else
|
||||
m = a = 0;
|
||||
|
||||
if (a - m < 17) { /* if there's less than 16 chars space, then enlarge the buffer first */
|
||||
if (a - m < 17 + l_separator) { /* if there's less than 16 chars space, then enlarge the buffer first */
|
||||
char *n;
|
||||
|
||||
if (_unlikely_(m > SIZE_MAX - 64)) /* overflow check */
|
||||
if (_unlikely_(l_separator > SIZE_MAX - 64)) /* overflow check #1 */
|
||||
return -ENOMEM;
|
||||
if (_unlikely_(m > SIZE_MAX - 64 - l_separator)) /* overflow check #2 */
|
||||
return -ENOMEM;
|
||||
|
||||
n = realloc(*x, m + 64);
|
||||
n = realloc(*x, m + 64 + l_separator);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -825,19 +829,20 @@ int strextendf(char **x, const char *format, ...) {
|
||||
}
|
||||
|
||||
/* Now, let's try to format the string into it */
|
||||
memcpy_safe(*x + m, separator, l_separator);
|
||||
va_start(ap, format);
|
||||
l = vsnprintf(*x + m, a - m, format, ap);
|
||||
l = vsnprintf(*x + m + l_separator, a - m - l_separator, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
assert(l >= 0);
|
||||
|
||||
if ((size_t) l < a - m) {
|
||||
if ((size_t) l < a - m - l_separator) {
|
||||
char *n;
|
||||
|
||||
/* Nice! This worked. We are done. But first, let's return the extra space we don't
|
||||
* need. This should be a cheap operation, since we only lower the allocation size here,
|
||||
* never increase. */
|
||||
n = realloc(*x, m + (size_t) l + 1);
|
||||
n = realloc(*x, m + (size_t) l + l_separator + 1);
|
||||
if (n)
|
||||
*x = n;
|
||||
} else {
|
||||
@@ -845,22 +850,22 @@ int strextendf(char **x, const char *format, ...) {
|
||||
|
||||
/* Wasn't enough. Then let's allocate exactly what we need. */
|
||||
|
||||
if (_unlikely_((size_t) l > SIZE_MAX - 1)) /* overflow check #1 */
|
||||
if (_unlikely_((size_t) l > SIZE_MAX - (l_separator + 1))) /* overflow check #1 */
|
||||
goto oom;
|
||||
if (_unlikely_(m > SIZE_MAX - ((size_t) l + 1))) /* overflow check #2 */
|
||||
if (_unlikely_(m > SIZE_MAX - ((size_t) l + l_separator + 1))) /* overflow check #2 */
|
||||
goto oom;
|
||||
|
||||
a = m + (size_t) l + 1;
|
||||
a = m + (size_t) l + l_separator + 1;
|
||||
n = realloc(*x, a);
|
||||
if (!n)
|
||||
goto oom;
|
||||
*x = n;
|
||||
|
||||
va_start(ap, format);
|
||||
l = vsnprintf(*x + m, a - m, format, ap);
|
||||
l = vsnprintf(*x + m + l_separator, a - m - l_separator, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
assert((size_t) l < a - m);
|
||||
assert((size_t) l < a - m - l_separator);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -156,11 +156,11 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
|
||||
char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]);
|
||||
|
||||
char *strextend_with_separator_internal(char **x, const char *separator, ...) _sentinel_;
|
||||
|
||||
#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)
|
||||
|
||||
int strextendf(char **x, const char *format, ...) _printf_(2,3);
|
||||
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__)
|
||||
|
||||
char *strrep(const char *s, unsigned n);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user