mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 08:56:15 +09:00
@@ -13,6 +13,7 @@
|
||||
#include "hashmap.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "path-util.h"
|
||||
#include "set.h"
|
||||
#include "sort-util.h"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "mkdir.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "socket-util.h"
|
||||
|
||||
@@ -2,6 +2,118 @@
|
||||
|
||||
#include "nulstr-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
char** strv_parse_nulstr(const char *s, size_t l) {
|
||||
/* l is the length of the input data, which will be split at NULs into elements of the resulting
|
||||
* strv. Hence, the number of items in the resulting strv will be equal to one plus the number of NUL
|
||||
* bytes in the l bytes starting at s, unless s[l-1] is NUL, in which case the final empty string is
|
||||
* not stored in the resulting strv, and length is equal to the number of NUL bytes.
|
||||
*
|
||||
* Note that contrary to a normal nulstr which cannot contain empty strings, because the input data
|
||||
* is terminated by any two consequent NUL bytes, this parser accepts empty strings in s. */
|
||||
|
||||
_cleanup_strv_free_ char **v = NULL;
|
||||
size_t c = 0, i = 0;
|
||||
|
||||
assert(s || l <= 0);
|
||||
|
||||
if (l <= 0)
|
||||
return new0(char*, 1);
|
||||
|
||||
for (const char *p = s; p < s + l; p++)
|
||||
if (*p == 0)
|
||||
c++;
|
||||
|
||||
if (s[l-1] != 0)
|
||||
c++;
|
||||
|
||||
v = new0(char*, c+1);
|
||||
if (!v)
|
||||
return NULL;
|
||||
|
||||
for (const char *p = s; p < s + l; ) {
|
||||
const char *e;
|
||||
|
||||
e = memchr(p, 0, s + l - p);
|
||||
|
||||
v[i] = memdup_suffix0(p, e ? e - p : s + l - p);
|
||||
if (!v[i])
|
||||
return NULL;
|
||||
|
||||
i++;
|
||||
|
||||
if (!e)
|
||||
break;
|
||||
|
||||
p = e + 1;
|
||||
}
|
||||
|
||||
assert(i == c);
|
||||
|
||||
return TAKE_PTR(v);
|
||||
}
|
||||
|
||||
char** strv_split_nulstr(const char *s) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
/* This parses a nulstr, without specification of size, and stops at an empty string. This cannot
|
||||
* parse nulstrs with embedded empty strings hence, as an empty string is an end marker. Use
|
||||
* strv_parse_nulstr() above to parse a nulstr with embedded empty strings (which however requires a
|
||||
* size to be specified) */
|
||||
|
||||
NULSTR_FOREACH(i, s)
|
||||
if (strv_extend(&l, i) < 0)
|
||||
return NULL;
|
||||
|
||||
return l ? TAKE_PTR(l) : strv_new(NULL);
|
||||
}
|
||||
|
||||
int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
|
||||
/* Builds a nulstr and returns it together with the size. An extra NUL byte will be appended (⚠️ but
|
||||
* not included in the size! ⚠️). This is done so that the nulstr can be used both in
|
||||
* strv_parse_nulstr() and in NULSTR_FOREACH()/strv_split_nulstr() contexts, i.e. with and without a
|
||||
* size parameter. In the former case we can include empty strings, in the latter case we cannot (as
|
||||
* that is the end marker).
|
||||
*
|
||||
* When NULSTR_FOREACH()/strv_split_nulstr() is used it is often assumed that the nulstr ends in two
|
||||
* NUL bytes (which it will, if not empty). To ensure that this assumption *always* holds, we'll
|
||||
* return a buffer with two NUL bytes in that case, but return a size of zero. */
|
||||
|
||||
_cleanup_free_ char *m = NULL;
|
||||
size_t n = 0;
|
||||
|
||||
assert(ret);
|
||||
assert(ret_size);
|
||||
|
||||
STRV_FOREACH(i, l) {
|
||||
size_t z;
|
||||
|
||||
z = strlen(*i);
|
||||
|
||||
if (!GREEDY_REALLOC(m, n + z + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(m + n, *i, z + 1);
|
||||
n += z + 1;
|
||||
}
|
||||
|
||||
if (!m) {
|
||||
/* return a buffer with an extra NUL, so that the assumption that we always have two trailing NULs holds */
|
||||
m = new0(char, 2);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
|
||||
n = 0;
|
||||
} else
|
||||
/* Make sure there is a second extra NUL at the end of resulting nulstr (not counted in return size) */
|
||||
m[n] = '\0';
|
||||
|
||||
*ret = TAKE_PTR(m);
|
||||
*ret_size = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* nulstr_get(const char *nulstr, const char *needle) {
|
||||
if (!nulstr)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <errno.h>
|
||||
#include <macro.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -15,3 +17,20 @@ const char* nulstr_get(const char *nulstr, const char *needle);
|
||||
static inline bool nulstr_contains(const char *nulstr, const char *needle) {
|
||||
return nulstr_get(nulstr, needle);
|
||||
}
|
||||
|
||||
char** strv_parse_nulstr(const char *s, size_t l);
|
||||
char** strv_split_nulstr(const char *s);
|
||||
int strv_make_nulstr(char * const *l, char **p, size_t *n);
|
||||
|
||||
static inline int strv_from_nulstr(char ***ret, const char *nulstr) {
|
||||
char **t;
|
||||
|
||||
assert(ret);
|
||||
|
||||
t = strv_split_nulstr(nulstr);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "missing_sched.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "namespace-util.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
|
||||
112
src/basic/strv.c
112
src/basic/strv.c
@@ -623,118 +623,6 @@ char** strv_remove(char **l, const char *s) {
|
||||
return l;
|
||||
}
|
||||
|
||||
char** strv_parse_nulstr(const char *s, size_t l) {
|
||||
/* l is the length of the input data, which will be split at NULs into
|
||||
* elements of the resulting strv. Hence, the number of items in the resulting strv
|
||||
* will be equal to one plus the number of NUL bytes in the l bytes starting at s,
|
||||
* unless s[l-1] is NUL, in which case the final empty string is not stored in
|
||||
* the resulting strv, and length is equal to the number of NUL bytes.
|
||||
*
|
||||
* Note that contrary to a normal nulstr which cannot contain empty strings, because
|
||||
* the input data is terminated by any two consequent NUL bytes, this parser accepts
|
||||
* empty strings in s.
|
||||
*/
|
||||
|
||||
size_t c = 0, i = 0;
|
||||
char **v;
|
||||
|
||||
assert(s || l <= 0);
|
||||
|
||||
if (l <= 0)
|
||||
return new0(char*, 1);
|
||||
|
||||
for (const char *p = s; p < s + l; p++)
|
||||
if (*p == 0)
|
||||
c++;
|
||||
|
||||
if (s[l-1] != 0)
|
||||
c++;
|
||||
|
||||
v = new0(char*, c+1);
|
||||
if (!v)
|
||||
return NULL;
|
||||
|
||||
for (const char *p = s; p < s + l; ) {
|
||||
const char *e;
|
||||
|
||||
e = memchr(p, 0, s + l - p);
|
||||
|
||||
v[i] = strndup(p, e ? e - p : s + l - p);
|
||||
if (!v[i]) {
|
||||
strv_free(v);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (!e)
|
||||
break;
|
||||
|
||||
p = e + 1;
|
||||
}
|
||||
|
||||
assert(i == c);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
char** strv_split_nulstr(const char *s) {
|
||||
char **r = NULL;
|
||||
|
||||
NULSTR_FOREACH(i, s)
|
||||
if (strv_extend(&r, i) < 0) {
|
||||
strv_free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!r)
|
||||
return strv_new(NULL);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
|
||||
/* A valid nulstr with two NULs at the end will be created, but
|
||||
* q will be the length without the two trailing NULs. Thus the output
|
||||
* string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
|
||||
* and can also be parsed by strv_parse_nulstr as long as the length
|
||||
* is provided separately.
|
||||
*/
|
||||
|
||||
_cleanup_free_ char *m = NULL;
|
||||
size_t n = 0;
|
||||
|
||||
assert(ret);
|
||||
assert(ret_size);
|
||||
|
||||
STRV_FOREACH(i, l) {
|
||||
size_t z;
|
||||
|
||||
z = strlen(*i);
|
||||
|
||||
if (!GREEDY_REALLOC(m, n + z + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(m + n, *i, z + 1);
|
||||
n += z + 1;
|
||||
}
|
||||
|
||||
if (!m) {
|
||||
m = new0(char, 2);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
n = 1;
|
||||
} else
|
||||
/* make sure there is a second extra NUL at the end of resulting nulstr */
|
||||
m[n] = '\0';
|
||||
|
||||
assert(n > 0);
|
||||
*ret = TAKE_PTR(m);
|
||||
*ret_size = n - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool strv_overlap(char * const *a, char * const *b) {
|
||||
STRV_FOREACH(i, a)
|
||||
if (strv_contains(b, *i))
|
||||
|
||||
@@ -124,20 +124,6 @@ static inline char *strv_join(char * const *l, const char *separator) {
|
||||
return strv_join_full(l, separator, NULL, false);
|
||||
}
|
||||
|
||||
char** strv_parse_nulstr(const char *s, size_t l);
|
||||
char** strv_split_nulstr(const char *s);
|
||||
int strv_make_nulstr(char * const *l, char **p, size_t *n);
|
||||
|
||||
static inline int strv_from_nulstr(char ***a, const char *nulstr) {
|
||||
char **t;
|
||||
|
||||
t = strv_split_nulstr(nulstr);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
*a = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool strv_overlap(char * const *a, char * const *b) _pure_;
|
||||
|
||||
#define _STRV_FOREACH_BACKWARDS(s, l, h, i) \
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "fileio.h"
|
||||
#include "format-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "process-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "path-lookup.h"
|
||||
#include "path-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "memory-util.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "mkdir-label.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "process-util.h"
|
||||
#include "random-util.h"
|
||||
#include "signal-util.h"
|
||||
@@ -112,6 +113,10 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* chop off the final NUL byte. We do this because we want to use the separator NUL bytes only if we
|
||||
* have multiple passwords. */
|
||||
n = LESS_BY(n, (size_t) 1);
|
||||
|
||||
serial = add_key("user", keyname, p, n, KEY_SPEC_USER_KEYRING);
|
||||
if (serial == -1)
|
||||
return -errno;
|
||||
|
||||
@@ -34,12 +34,13 @@
|
||||
#include "fs-util.h"
|
||||
#include "glob-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "ima-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "limits-util.h"
|
||||
#include "list.h"
|
||||
#include "macro.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "os-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fuzz.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "static-destruct.h"
|
||||
#include "stdio-util.h"
|
||||
|
||||
@@ -557,6 +557,8 @@ tests += [
|
||||
|
||||
[files('test-strv.c')],
|
||||
|
||||
[files('test-nulstr-util.c')],
|
||||
|
||||
[files('test-path-util.c')],
|
||||
|
||||
[files('test-rm-rf.c')],
|
||||
|
||||
160
src/test/test-nulstr-util.c
Normal file
160
src/test/test-nulstr-util.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "strv.h"
|
||||
#include "tests.h"
|
||||
|
||||
TEST(strv_split_nulstr) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
const char nulstr[] = "str0\0str1\0str2\0str3\0";
|
||||
|
||||
l = strv_split_nulstr(nulstr);
|
||||
assert_se(l);
|
||||
|
||||
assert_se(streq(l[0], "str0"));
|
||||
assert_se(streq(l[1], "str1"));
|
||||
assert_se(streq(l[2], "str2"));
|
||||
assert_se(streq(l[3], "str3"));
|
||||
}
|
||||
|
||||
TEST(strv_parse_nulstr) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx";
|
||||
|
||||
l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
|
||||
assert_se(l);
|
||||
puts("Parse nulstr:");
|
||||
strv_print(l);
|
||||
|
||||
assert_se(streq(l[0], "hoge"));
|
||||
assert_se(streq(l[1], "hoge2"));
|
||||
assert_se(streq(l[2], "hoge3"));
|
||||
assert_se(streq(l[3], ""));
|
||||
assert_se(streq(l[4], "hoge5"));
|
||||
assert_se(streq(l[5], ""));
|
||||
assert_se(streq(l[6], "xxx"));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[0]) {}, 0);
|
||||
assert_se(l);
|
||||
assert_se(strv_isempty(l));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[1]) { 0 }, 1);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[1]) { 'x' }, 1);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("x")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[2]) { 0, 0 }, 2);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("", "")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[2]) { 'x', 0 }, 2);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("x")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[3]) { 0, 0, 0 }, 3);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("", "", "")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[3]) { 'x', 0, 0 }, 3);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("x", "")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[3]) { 0, 'x', 0 }, 3);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("", "x")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[3]) { 0, 0, 'x' }, 3);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("", "", "x")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[3]) { 'x', 'x', 0 }, 3);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("xx")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[3]) { 0, 'x', 'x' }, 3);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("", "xx")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[3]) { 'x', 0, 'x' }, 3);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("x", "x")));
|
||||
strv_free(l);
|
||||
|
||||
l = strv_parse_nulstr((const char[3]) { 'x', 'x', 'x' }, 3);
|
||||
assert_se(l);
|
||||
assert_se(strv_equal(l, STRV_MAKE("xxx")));
|
||||
}
|
||||
|
||||
static void test_strv_make_nulstr_one(char **l) {
|
||||
_cleanup_free_ char *b = NULL, *c = NULL;
|
||||
_cleanup_strv_free_ char **q = NULL;
|
||||
size_t n, m;
|
||||
unsigned i = 0;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(strv_make_nulstr(l, &b, &n) >= 0);
|
||||
assert_se(q = strv_parse_nulstr(b, n));
|
||||
assert_se(strv_equal(l, q));
|
||||
|
||||
assert_se(strv_make_nulstr(q, &c, &m) >= 0);
|
||||
assert_se(memcmp_nn(b, n, c, m) == 0);
|
||||
|
||||
NULSTR_FOREACH(s, b)
|
||||
assert_se(streq(s, l[i++]));
|
||||
assert_se(i == strv_length(l));
|
||||
}
|
||||
|
||||
TEST(strv_make_nulstr) {
|
||||
test_strv_make_nulstr_one(NULL);
|
||||
test_strv_make_nulstr_one(STRV_MAKE(NULL));
|
||||
test_strv_make_nulstr_one(STRV_MAKE("foo"));
|
||||
test_strv_make_nulstr_one(STRV_MAKE("foo", "bar"));
|
||||
test_strv_make_nulstr_one(STRV_MAKE("foo", "bar", "quuux"));
|
||||
}
|
||||
|
||||
static void test_strv_make_nulstr_binary_one(char **l, const char *b, size_t n) {
|
||||
_cleanup_strv_free_ char **z = NULL;
|
||||
_cleanup_free_ char *a = NULL;
|
||||
size_t m;
|
||||
|
||||
assert_se(strv_make_nulstr(l, &a, &m) >= 0);
|
||||
assert_se(memcmp_nn(a, m, b, n) == 0);
|
||||
assert_se(z = strv_parse_nulstr(a, m));
|
||||
assert_se(strv_equal(l, z));
|
||||
}
|
||||
|
||||
TEST(strv_make_nulstr_binary) {
|
||||
test_strv_make_nulstr_binary_one(NULL, (const char[0]) {}, 0);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE(NULL), (const char[0]) {}, 0);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE(""), (const char[1]) { 0 }, 1);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("", ""), (const char[2]) { 0, 0 }, 2);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("x", ""), (const char[3]) { 'x', 0, 0 }, 3);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("", "x"), (const char[3]) { 0, 'x', 0 }, 3);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("", "", ""), (const char[3]) { 0, 0, 0 }, 3);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("x", "", ""), (const char[4]) { 'x', 0, 0, 0 }, 4);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("", "x", ""), (const char[4]) { 0, 'x', 0, 0 }, 4);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("", "", "x"), (const char[4]) { 0, 0, 'x', 0 }, 4);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("x", "x", ""), (const char[5]) { 'x', 0, 'x', 0, 0 }, 5);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("", "x", "x"), (const char[5]) { 0, 'x', 0, 'x', 0 }, 5);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("x", "", "x"), (const char[5]) { 'x', 0, 0, 'x', 0 }, 5);
|
||||
test_strv_make_nulstr_binary_one(STRV_MAKE("x", "x", "x"), (const char[6]) { 'x', 0, 'x', 0, 'x', 0 }, 6);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nulstr-util.h"
|
||||
#include "strbuf.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "escape.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "tests.h"
|
||||
@@ -487,37 +486,6 @@ TEST(strv_split_newlines_full) {
|
||||
assert_se(strv_equal(l, (char**) input_table_retain_escape));
|
||||
}
|
||||
|
||||
TEST(strv_split_nulstr) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
const char nulstr[] = "str0\0str1\0str2\0str3\0";
|
||||
|
||||
l = strv_split_nulstr (nulstr);
|
||||
assert_se(l);
|
||||
|
||||
assert_se(streq(l[0], "str0"));
|
||||
assert_se(streq(l[1], "str1"));
|
||||
assert_se(streq(l[2], "str2"));
|
||||
assert_se(streq(l[3], "str3"));
|
||||
}
|
||||
|
||||
TEST(strv_parse_nulstr) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx";
|
||||
|
||||
l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
|
||||
assert_se(l);
|
||||
puts("Parse nulstr:");
|
||||
strv_print(l);
|
||||
|
||||
assert_se(streq(l[0], "hoge"));
|
||||
assert_se(streq(l[1], "hoge2"));
|
||||
assert_se(streq(l[2], "hoge3"));
|
||||
assert_se(streq(l[3], ""));
|
||||
assert_se(streq(l[4], "hoge5"));
|
||||
assert_se(streq(l[5], ""));
|
||||
assert_se(streq(l[6], "xxx"));
|
||||
}
|
||||
|
||||
TEST(strv_overlap) {
|
||||
const char * const input_table[] = {
|
||||
"one",
|
||||
@@ -945,35 +913,6 @@ TEST(strv_extend_n) {
|
||||
assert_se(v[1] == NULL);
|
||||
}
|
||||
|
||||
static void test_strv_make_nulstr_one(char **l) {
|
||||
_cleanup_free_ char *b = NULL, *c = NULL;
|
||||
_cleanup_strv_free_ char **q = NULL;
|
||||
size_t n, m;
|
||||
unsigned i = 0;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(strv_make_nulstr(l, &b, &n) >= 0);
|
||||
assert_se(q = strv_parse_nulstr(b, n));
|
||||
assert_se(strv_equal(l, q));
|
||||
|
||||
assert_se(strv_make_nulstr(q, &c, &m) >= 0);
|
||||
assert_se(m == n);
|
||||
assert_se(memcmp(b, c, m) == 0);
|
||||
|
||||
NULSTR_FOREACH(s, b)
|
||||
assert_se(streq(s, l[i++]));
|
||||
assert_se(i == strv_length(l));
|
||||
}
|
||||
|
||||
TEST(strv_make_nulstr) {
|
||||
test_strv_make_nulstr_one(NULL);
|
||||
test_strv_make_nulstr_one(STRV_MAKE(NULL));
|
||||
test_strv_make_nulstr_one(STRV_MAKE("foo"));
|
||||
test_strv_make_nulstr_one(STRV_MAKE("foo", "bar"));
|
||||
test_strv_make_nulstr_one(STRV_MAKE("foo", "bar", "quuux"));
|
||||
}
|
||||
|
||||
TEST(foreach_string) {
|
||||
const char * const t[] = {
|
||||
"foo",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "mkdir-label.h"
|
||||
#include "mount-util.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "offline-passwd.h"
|
||||
#include "pager.h"
|
||||
#include "parse-argument.h"
|
||||
|
||||
Reference in New Issue
Block a user