string-util: introduce strprepend(), drop effectively unused strnappend() (#36343)

Split out from #36337
This commit is contained in:
Yu Watanabe
2025-02-11 18:09:03 +09:00
committed by GitHub
5 changed files with 55 additions and 71 deletions
+4 -13
View File
@@ -695,7 +695,7 @@ int replace_env_full(
_cleanup_strv_free_ char **unset_variables = NULL, **bad_variables = NULL;
const char *e, *word = format, *test_value = NULL; /* test_value is initialized to appease gcc */
_cleanup_free_ char *s = NULL;
char ***pu, ***pb, *k;
char ***pu, ***pb;
size_t i, len = 0; /* len is initialized to appease gcc */
int nest = 0, r;
@@ -717,33 +717,24 @@ int replace_env_full(
case CURLY:
if (*e == '{') {
k = strnappend(s, word, e-word-1);
if (!k)
if (!strextendn(&s, word, e-word-1))
return -ENOMEM;
free_and_replace(s, k);
word = e-1;
state = VARIABLE;
nest++;
} else if (*e == '$') {
k = strnappend(s, word, e-word);
if (!k)
if (!strextendn(&s, word, e-word))
return -ENOMEM;
free_and_replace(s, k);
word = e+1;
state = WORD;
} else if (FLAGS_SET(flags, REPLACE_ENV_ALLOW_BRACELESS) && strchr(VALID_BASH_ENV_NAME_CHARS, *e)) {
k = strnappend(s, word, e-word-1);
if (!k)
if (!strextendn(&s, word, e-word-1))
return -ENOMEM;
free_and_replace(s, k);
word = e-1;
state = VARIABLE_RAW;
+30 -50
View File
@@ -46,35 +46,42 @@ char* first_word(const char *s, const char *word) {
return (char*) nw;
}
char* strnappend(const char *s, const char *suffix, size_t b) {
size_t a;
char *r;
char* strprepend(char **x, const char *s) {
assert(x);
if (!s && !suffix)
return strdup("");
if (isempty(s) && *x)
return *x;
if (!s)
return strndup(suffix, b);
if (!suffix)
return strdup(s);
assert(s);
assert(suffix);
a = strlen(s);
if (b > SIZE_MAX - a)
char *p = strjoin(strempty(s), *x);
if (!p)
return NULL;
r = new(char, a+b+1);
if (!r)
return NULL;
free_and_replace(*x, p);
return *x;
}
memcpy(r, s, a);
memcpy(r+a, suffix, b);
r[a+b] = 0;
char* strextendn(char **x, const char *s, size_t l) {
assert(x);
assert(s || l == 0);
return r;
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;
*mempcpy_typesafe(m + q, s, l) = 0;
*x = m;
}
return *x;
}
char* strstrip(char *s) {
@@ -975,33 +982,6 @@ 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;
+2 -3
View File
@@ -106,7 +106,8 @@ static inline const char* empty_or_dash_to_null(const char *p) {
char* first_word(const char *s, const char *word) _pure_;
char* strnappend(const char *s, const char *suffix, size_t length);
char* strprepend(char **x, const char *s);
char* strextendn(char **x, const char *s, size_t l);
#define strjoin(a, ...) strextend_with_separator_internal(NULL, NULL, a, __VA_ARGS__, NULL)
@@ -193,8 +194,6 @@ 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__)
+6 -5
View File
@@ -600,14 +600,15 @@ static int parse_one_option(const char *option) {
* - text descriptions prefixed with "%:" or "%keyring:".
* - text description with no prefix.
* - numeric keyring id (ignored in current patch set). */
if (IN_SET(*val, '@', '%'))
keyring = strndup(val, sep - val);
else
/* add type prefix if missing (crypt_set_keyring_to_link() expects it) */
keyring = strnappend("%:", val, sep - val);
keyring = strndup(val, sep - val);
if (!keyring)
return log_oom();
/* add type prefix if missing (crypt_set_keyring_to_link() expects it) */
if (!IN_SET(*keyring, '@', '%'))
if (!strprepend(&keyring, "%:"))
return log_oom();
sep += 2;
/* %<key_type> is optional (and defaults to 'user') */
+13
View File
@@ -1348,6 +1348,19 @@ TEST(strextendn) {
x = mfree(x);
}
TEST(strprepend) {
_cleanup_free_ char *x = NULL;
ASSERT_STREQ(strprepend(&x, NULL), "");
x = mfree(x);
ASSERT_STREQ(strprepend(&x, ""), "");
ASSERT_STREQ(strprepend(&x, "xxx"), "xxx");
ASSERT_STREQ(strprepend(&x, "bar"), "barxxx");
ASSERT_STREQ(strprepend(&x, "foo"), "foobarxxx");
}
TEST(strlevenshtein) {
assert_se(strlevenshtein(NULL, NULL) == 0);
assert_se(strlevenshtein("", "") == 0);