chiark / gitweb /
Prep v239: Unmask delete_chars()
[elogind.git] / src / test / test-string-util.c
index 54fe87d2de758e4baf18de929212d9da8d443b19..202af8bcc3356e327c5db1f01f8577b1b29824de 100644 (file)
@@ -1,26 +1,11 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2015 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "alloc-util.h"
+#include "locale-util.h"
 #include "macro.h"
 #include "string-util.h"
 #include "strv.h"
+#include "utf8.h"
 
 static void test_string_erase(void) {
         char *x;
@@ -91,6 +76,87 @@ static void test_ascii_strcasecmp_nn(void) {
 }
 #endif // 0
 
+static void test_cellescape(void) {
+        char buf[40];
+
+        assert_se(streq(cellescape(buf, 1, ""), ""));
+        assert_se(streq(cellescape(buf, 1, "1"), ""));
+        assert_se(streq(cellescape(buf, 1, "12"), ""));
+
+        assert_se(streq(cellescape(buf, 2, ""), ""));
+        assert_se(streq(cellescape(buf, 2, "1"), "1"));
+        assert_se(streq(cellescape(buf, 2, "12"), "."));
+        assert_se(streq(cellescape(buf, 2, "123"), "."));
+
+        assert_se(streq(cellescape(buf, 3, ""), ""));
+        assert_se(streq(cellescape(buf, 3, "1"), "1"));
+        assert_se(streq(cellescape(buf, 3, "12"), "12"));
+        assert_se(streq(cellescape(buf, 3, "123"), ".."));
+        assert_se(streq(cellescape(buf, 3, "1234"), ".."));
+
+        assert_se(streq(cellescape(buf, 4, ""), ""));
+        assert_se(streq(cellescape(buf, 4, "1"), "1"));
+        assert_se(streq(cellescape(buf, 4, "12"), "12"));
+        assert_se(streq(cellescape(buf, 4, "123"), "123"));
+        assert_se(streq(cellescape(buf, 4, "1234"), is_locale_utf8() ? "…" : "..."));
+        assert_se(streq(cellescape(buf, 4, "12345"), is_locale_utf8() ? "…" : "..."));
+
+        assert_se(streq(cellescape(buf, 5, ""), ""));
+        assert_se(streq(cellescape(buf, 5, "1"), "1"));
+        assert_se(streq(cellescape(buf, 5, "12"), "12"));
+        assert_se(streq(cellescape(buf, 5, "123"), "123"));
+        assert_se(streq(cellescape(buf, 5, "1234"), "1234"));
+        assert_se(streq(cellescape(buf, 5, "12345"), is_locale_utf8() ? "1…" : "1..."));
+        assert_se(streq(cellescape(buf, 5, "123456"), is_locale_utf8() ? "1…" : "1..."));
+
+        assert_se(streq(cellescape(buf, 1, "\020"), ""));
+        assert_se(streq(cellescape(buf, 2, "\020"), "."));
+        assert_se(streq(cellescape(buf, 3, "\020"), ".."));
+        assert_se(streq(cellescape(buf, 4, "\020"), "…"));
+        assert_se(streq(cellescape(buf, 5, "\020"), "\\020"));
+
+        assert_se(streq(cellescape(buf, 5, "1234\020"), "1…"));
+        assert_se(streq(cellescape(buf, 6, "1234\020"), "12…"));
+        assert_se(streq(cellescape(buf, 7, "1234\020"), "123…"));
+        assert_se(streq(cellescape(buf, 8, "1234\020"), "1234…"));
+        assert_se(streq(cellescape(buf, 9, "1234\020"), "1234\\020"));
+
+        assert_se(streq(cellescape(buf, 1, "\t\n"), ""));
+        assert_se(streq(cellescape(buf, 2, "\t\n"), "."));
+        assert_se(streq(cellescape(buf, 3, "\t\n"), ".."));
+        assert_se(streq(cellescape(buf, 4, "\t\n"), "…"));
+        assert_se(streq(cellescape(buf, 5, "\t\n"), "\\t\\n"));
+
+        assert_se(streq(cellescape(buf, 5, "1234\t\n"), "1…"));
+        assert_se(streq(cellescape(buf, 6, "1234\t\n"), "12…"));
+        assert_se(streq(cellescape(buf, 7, "1234\t\n"), "123…"));
+        assert_se(streq(cellescape(buf, 8, "1234\t\n"), "1234…"));
+        assert_se(streq(cellescape(buf, 9, "1234\t\n"), "1234\\t\\n"));
+
+        assert_se(streq(cellescape(buf, 4, "x\t\020\n"), "…"));
+        assert_se(streq(cellescape(buf, 5, "x\t\020\n"), "x…"));
+        assert_se(streq(cellescape(buf, 6, "x\t\020\n"), "x…"));
+        assert_se(streq(cellescape(buf, 7, "x\t\020\n"), "x\\t…"));
+        assert_se(streq(cellescape(buf, 8, "x\t\020\n"), "x\\t…"));
+        assert_se(streq(cellescape(buf, 9, "x\t\020\n"), "x\\t…"));
+        assert_se(streq(cellescape(buf, 10, "x\t\020\n"), "x\\t\\020\\n"));
+
+        assert_se(streq(cellescape(buf, 6, "1\011"), "1\\t"));
+        assert_se(streq(cellescape(buf, 6, "1\020"), "1\\020"));
+        assert_se(streq(cellescape(buf, 6, "1\020x"), is_locale_utf8() ? "1…" : "1..."));
+
+        assert_se(streq(cellescape(buf, 40, "1\020"), "1\\020"));
+        assert_se(streq(cellescape(buf, 40, "1\020x"), "1\\020x"));
+
+        assert_se(streq(cellescape(buf, 40, "\a\b\f\n\r\t\v\\\"'"), "\\a\\b\\f\\n\\r\\t\\v\\\\\\\"\\'"));
+        assert_se(streq(cellescape(buf, 6, "\a\b\f\n\r\t\v\\\"'"), is_locale_utf8() ? "\\a…" : "\\a..."));
+        assert_se(streq(cellescape(buf, 7, "\a\b\f\n\r\t\v\\\"'"), is_locale_utf8() ? "\\a…" : "\\a..."));
+        assert_se(streq(cellescape(buf, 8, "\a\b\f\n\r\t\v\\\"'"), is_locale_utf8() ? "\\a\\b…" : "\\a\\b..."));
+
+        assert_se(streq(cellescape(buf, sizeof buf, "1\020"), "1\\020"));
+        assert_se(streq(cellescape(buf, sizeof buf, "1\020x"), "1\\020x"));
+}
+
 static void test_streq_ptr(void) {
         assert_se(streq_ptr(NULL, NULL));
         assert_se(!streq_ptr("abc", "cdef"));
@@ -105,9 +171,37 @@ static void test_strstrip(void) {
 }
 
 static void test_strextend(void) {
-        _cleanup_free_ char *str = strdup("0123");
-        strextend(&str, "456", "78", "9", NULL);
-        assert_se(streq(str, "0123456789"));
+        _cleanup_free_ char *str = NULL;
+
+        assert_se(strextend(&str, NULL));
+        assert_se(streq_ptr(str, ""));
+        assert_se(strextend(&str, "", "0", "", "", "123", NULL));
+        assert_se(streq_ptr(str, "0123"));
+        assert_se(strextend(&str, "456", "78", "9", NULL));
+        assert_se(streq_ptr(str, "0123456789"));
+}
+
+static void test_strextend_with_separator(void) {
+        _cleanup_free_ char *str = NULL;
+
+        assert_se(strextend_with_separator(&str, NULL, NULL));
+        assert_se(streq_ptr(str, ""));
+        str = mfree(str);
+
+        assert_se(strextend_with_separator(&str, "...", NULL));
+        assert_se(streq_ptr(str, ""));
+        assert_se(strextend_with_separator(&str, "...", NULL));
+        assert_se(streq_ptr(str, ""));
+        str = mfree(str);
+
+        assert_se(strextend_with_separator(&str, "xyz", "a", "bb", "ccc", NULL));
+        assert_se(streq_ptr(str, "axyzbbxyzccc"));
+        str = mfree(str);
+
+        assert_se(strextend_with_separator(&str, ",", "start", "", "1", "234", NULL));
+        assert_se(streq_ptr(str, "start,,1,234"));
+        assert_se(strextend_with_separator(&str, ";", "more", "5", "678", NULL));
+        assert_se(streq_ptr(str, "start,,1,234;more;5;678"));
 }
 
 static void test_strrep(void) {
@@ -121,7 +215,6 @@ static void test_strrep(void) {
         assert_se(streq(zero, ""));
 }
 
-
 static void test_strappend(void) {
         _cleanup_free_ char *t1, *t2, *t3, *t4;
 
@@ -291,15 +384,62 @@ static void test_endswith_no_case(void) {
         assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
 }
 
-#if 0 /// UNNEEDED by elogind
 static void test_delete_chars(void) {
-        char *r;
-        char input[] = "   hello, waldo.   abc";
+        char *s, input[] = "   hello, waldo.   abc";
 
-        r = delete_chars(input, WHITESPACE);
-        assert_se(streq(r, "hello,waldo.abc"));
+        s = delete_chars(input, WHITESPACE);
+        assert_se(streq(s, "hello,waldo.abc"));
+        assert_se(s == input);
+}
+
+static void test_delete_trailing_chars(void) {
+
+        char *s,
+                input1[] = " \n \r k \n \r ",
+                input2[] = "kkkkthiskkkiskkkaktestkkk",
+                input3[] = "abcdef";
+
+        s = delete_trailing_chars(input1, WHITESPACE);
+        assert_se(streq(s, " \n \r k"));
+        assert_se(s == input1);
+
+        s = delete_trailing_chars(input2, "kt");
+        assert_se(streq(s, "kkkkthiskkkiskkkaktes"));
+        assert_se(s == input2);
+
+        s = delete_trailing_chars(input3, WHITESPACE);
+        assert_se(streq(s, "abcdef"));
+        assert_se(s == input3);
+
+        s = delete_trailing_chars(input3, "fe");
+        assert_se(streq(s, "abcd"));
+        assert_se(s == input3);
+}
+
+static void test_delete_trailing_slashes(void) {
+        char s1[] = "foobar//",
+             s2[] = "foobar/",
+             s3[] = "foobar",
+             s4[] = "";
+
+        assert_se(streq(delete_trailing_chars(s1, "_"), "foobar//"));
+        assert_se(streq(delete_trailing_chars(s1, "/"), "foobar"));
+        assert_se(streq(delete_trailing_chars(s2, "/"), "foobar"));
+        assert_se(streq(delete_trailing_chars(s3, "/"), "foobar"));
+        assert_se(streq(delete_trailing_chars(s4, "/"), ""));
+}
+
+static void test_skip_leading_chars(void) {
+        char input1[] = " \n \r k \n \r ",
+                input2[] = "kkkkthiskkkiskkkaktestkkk",
+                input3[] = "abcdef";
+
+        assert_se(streq(skip_leading_chars(input1, WHITESPACE), "k \n \r "));
+        assert_se(streq(skip_leading_chars(input2, "k"), "thiskkkiskkkaktestkkk"));
+        assert_se(streq(skip_leading_chars(input2, "tk"), "hiskkkiskkkaktestkkk"));
+        assert_se(streq(skip_leading_chars(input3, WHITESPACE), "abcdef"));
+        assert_se(streq(skip_leading_chars(input3, "bcaef"), "def"));
 }
-#endif // 0
 
 static void test_in_charset(void) {
         assert_se(in_charset("dddaaabbbcccc", "abcd"));
@@ -342,15 +482,35 @@ static void test_first_word(void) {
         assert_se(!first_word("Hellooo", "Hello"));
 }
 
+static void test_strlen_ptr(void) {
+        assert_se(strlen_ptr("foo") == 3);
+        assert_se(strlen_ptr("") == 0);
+        assert_se(strlen_ptr(NULL) == 0);
+}
+
+static void test_memory_startswith(void) {
+        assert_se(streq(memory_startswith("", 0, ""), ""));
+        assert_se(streq(memory_startswith("", 1, ""), ""));
+        assert_se(streq(memory_startswith("x", 2, ""), "x"));
+        assert_se(!memory_startswith("", 1, "x"));
+        assert_se(!memory_startswith("", 1, "xxxxxxxx"));
+        assert_se(streq(memory_startswith("xxx", 4, "x"), "xx"));
+        assert_se(streq(memory_startswith("xxx", 4, "xx"), "x"));
+        assert_se(streq(memory_startswith("xxx", 4, "xxx"), ""));
+        assert_se(!memory_startswith("xxx", 4, "xxxx"));
+}
+
 int main(int argc, char *argv[]) {
         test_string_erase();
 #if 0 /// UNNEEDED by elogind
         test_ascii_strcasecmp_n();
         test_ascii_strcasecmp_nn();
 #endif // 0
+        test_cellescape();
         test_streq_ptr();
         test_strstrip();
         test_strextend();
+        test_strextend_with_separator();
         test_strrep();
         test_strappend();
         test_string_has_cc();
@@ -364,12 +524,15 @@ int main(int argc, char *argv[]) {
         test_foreach_word_quoted();
         test_endswith();
         test_endswith_no_case();
-#if 0 /// UNNEEDED by elogind
         test_delete_chars();
-#endif // 0
+        test_delete_trailing_chars();
+        test_delete_trailing_slashes();
+        test_skip_leading_chars();
         test_in_charset();
         test_split_pair();
         test_first_word();
+        test_strlen_ptr();
+        test_memory_startswith();
 
         return 0;
 }