blob: 70f1e8705d836c1d61a83c41dd90bdea57b3a156 [file] [log] [blame]
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "alloc-util.h"
#include "nulstr-util.h"
#include "set.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"));
}
TEST(set_make_nulstr) {
_cleanup_set_free_free_ Set *set = NULL;
size_t len = 0;
int r;
{
/* Unallocated and empty set. */
static const char expect[] = { 0x00, 0x00 };
_cleanup_free_ char *nulstr = NULL;
r = set_make_nulstr(set, &nulstr, &len);
assert_se(r == 0);
assert_se(len == 0);
assert_se(memcmp(expect, nulstr, len + 2) == 0);
}
{
/* Allocated by empty set. */
static const char expect[] = { 0x00, 0x00 };
_cleanup_free_ char *nulstr = NULL;
set = set_new(NULL);
assert_se(set);
r = set_make_nulstr(set, &nulstr, &len);
assert_se(r == 0);
assert_se(len == 0);
assert_se(memcmp(expect, nulstr, len + 2) == 0);
}
{
/* Non-empty set. */
static const char expect[] = { 'a', 'a', 'a', 0x00, 0x00 };
_cleanup_free_ char *nulstr = NULL;
assert_se(set_put_strdup(&set, "aaa") >= 0);
r = set_make_nulstr(set, &nulstr, &len);
assert_se(r == 0);
assert_se(len == 4);
assert_se(memcmp(expect, nulstr, len + 1) == 0);
}
}
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);