string-util: add new strdupcspn()/strdupspn()

These combine strndup() + strspn()/strcspn() into one.

There are a bunch of strndupa() calls that could use similar treatment
(or should be converted to strdup[c]spn(), but this commit doesn't
bother with that.
This commit is contained in:
Lennart Poettering 2023-01-20 13:14:42 +01:00
parent 71c6f0ac52
commit e8bec6242b
8 changed files with 27 additions and 13 deletions

View file

@ -862,7 +862,6 @@ int executable_is_script(const char *path, char **interpreter) {
int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
_cleanup_free_ char *status = NULL;
char *t, *f;
size_t len;
int r;
assert(terminator);
@ -914,9 +913,7 @@ int get_proc_field(const char *filename, const char *pattern, const char *termin
t--;
}
len = strcspn(t, terminator);
f = strndup(t, len);
f = strdupcspn(t, terminator);
if (!f)
return -ENOMEM;

View file

@ -62,7 +62,7 @@ int gethostname_full(GetHostnameFlags flags, char **ret) {
}
if (FLAGS_SET(flags, GET_HOSTNAME_SHORT))
buf = strndup(s, strcspn(s, "."));
buf = strdupcspn(s, ".");
else
buf = strdup(s);
if (!buf)

View file

@ -1201,3 +1201,19 @@ size_t strspn_from_end(const char *str, const char *accept) {
return n;
}
char *strdupspn(const char *a, const char *accept) {
if (isempty(a) || isempty(accept))
return strdup("");
return strndup(a, strspn(a, accept));
}
char *strdupcspn(const char *a, const char *reject) {
if (isempty(a))
return strdup("");
if (isempty(reject))
return strdup(a);
return strndup(a, strcspn(a, reject));
}

View file

@ -240,3 +240,6 @@ bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok);
char *string_replace_char(char *str, char old_char, char new_char);
size_t strspn_from_end(const char *str, const char *accept);
char *strdupspn(const char *a, const char *accept);
char *strdupcspn(const char *a, const char *reject);

View file

@ -40,11 +40,9 @@ static int apply_rule(const char *filename, unsigned line, const char *rule) {
assert(rule[0]);
_cleanup_free_ char *rulename = NULL;
const char *e;
int r;
e = strchrnul(rule + 1, rule[0]);
rulename = strndup(rule + 1, e - rule - 1);
rulename = strdupcspn(rule + 1, CHAR_TO_STR(rule[0]));
if (!rulename)
return log_oom();

View file

@ -505,7 +505,9 @@ int find_legacy_keymap(Context *c, char **ret) {
/* If that didn't work, strip off the
* other layouts from the entry, too */
x = strndup(a[1], strcspn(a[1], ","));
x = strdupcspn(a[1], ",");
if (!x)
return -ENOMEM;
if (startswith_comma(c->x11_layout, x))
matching = 1;
}

View file

@ -175,15 +175,13 @@ static int image_new(
static int extract_pretty(const char *path, const char *suffix, char **ret) {
_cleanup_free_ char *name = NULL;
const char *p;
size_t n;
assert(path);
assert(ret);
p = last_path_component(path);
n = strcspn(p, "/");
name = strndup(p, n);
name = strdupcspn(p, "/");
if (!name)
return -ENOMEM;

View file

@ -108,7 +108,7 @@ static int url_from_catalog(sd_journal *j, char **ret) {
weblink += strspn(weblink, " \t");
/* Cut out till next whitespace/newline */
url = strndup(weblink, strcspn(weblink, WHITESPACE));
url = strdupcspn(weblink, WHITESPACE);
if (!url)
return log_oom();