summaryrefslogtreecommitdiffstats
path: root/gnulib-tests/unistr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 16:58:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 16:58:41 +0000
commite1908ae95dd4c9d19ee4dfabfc8bf8a7f85943fe (patch)
treef5cc731bedcac0fb7fe14d952e4581e749f8bb87 /gnulib-tests/unistr
parentInitial commit. (diff)
downloadcoreutils-e1908ae95dd4c9d19ee4dfabfc8bf8a7f85943fe.tar.xz
coreutils-e1908ae95dd4c9d19ee4dfabfc8bf8a7f85943fe.zip
Adding upstream version 9.4.upstream/9.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gnulib-tests/unistr')
-rw-r--r--gnulib-tests/unistr/test-chr.h141
-rw-r--r--gnulib-tests/unistr/test-cpy.h44
-rw-r--r--gnulib-tests/unistr/test-pcpy.h44
-rw-r--r--gnulib-tests/unistr/test-set.h44
-rw-r--r--gnulib-tests/unistr/test-strcat.h56
-rw-r--r--gnulib-tests/unistr/test-strncat.h90
-rw-r--r--gnulib-tests/unistr/test-u32-chr.c34
-rw-r--r--gnulib-tests/unistr/test-u32-cpy.c28
-rw-r--r--gnulib-tests/unistr/test-u32-pcpy.c28
-rw-r--r--gnulib-tests/unistr/test-u32-set.c29
-rw-r--r--gnulib-tests/unistr/test-u32-strcat.c28
-rw-r--r--gnulib-tests/unistr/test-u32-strlen.c57
-rw-r--r--gnulib-tests/unistr/test-u8-mbtoucr.c187
-rw-r--r--gnulib-tests/unistr/test-u8-uctomb.c157
-rw-r--r--gnulib-tests/unistr/u-set.h47
-rw-r--r--gnulib-tests/unistr/u32-set.c34
16 files changed, 1048 insertions, 0 deletions
diff --git a/gnulib-tests/unistr/test-chr.h b/gnulib-tests/unistr/test-chr.h
new file mode 100644
index 0000000..47d6612
--- /dev/null
+++ b/gnulib-tests/unistr/test-chr.h
@@ -0,0 +1,141 @@
+/* Test of uN_chr() functions.
+ Copyright (C) 2008-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake and Bruno Haible <bruno@clisp.org>, 2010. */
+
+int
+main (void)
+{
+ size_t size = 0x100000;
+ size_t i;
+ size_t length;
+ UNIT *input;
+ uint32_t *input32 = (uint32_t *) malloc (size * sizeof (uint32_t));
+ ASSERT (input32);
+
+ input32[0] = 'a';
+ input32[1] = 'b';
+ u32_set (input32 + 2, 'c', 1024);
+ for (i = 1026; i < size - 2; i += 63)
+ {
+ size_t last = i + 63 < size - 2 ? i + 63 : size - 2;
+ ucs4_t uc = 'd' | (i - 1026);
+ if (uc >= 0xd800 && uc <= 0xdfff)
+ uc |= 0x100000;
+ u32_set (input32 + i, uc, last - i);
+ }
+
+ input32[size - 2] = 'e';
+ input32[size - 1] = 'a';
+
+ input = U32_TO_U (input32, size, NULL, &length);
+ ASSERT (input);
+
+ /* Basic behavior tests. */
+ ASSERT (U_CHR (input, length, 'a') == input);
+
+ ASSERT (U_CHR (input, 0, 'a') == NULL);
+ void *page_boundary = zerosize_ptr ();
+ if (page_boundary)
+ ASSERT (U_CHR (page_boundary, 0, 'a') == NULL);
+
+ ASSERT (U_CHR (input, length, 'b') == input + 1);
+ ASSERT (U_CHR (input, length, 'c') == input + 2);
+ ASSERT (U_CHR (input, length, 'd') == input + 1026);
+
+ {
+ UNIT *exp = input + 1026;
+ UNIT *prev = input + 1;
+ for (i = 1026; i < size - 2; i += 63)
+ {
+ UNIT c[6];
+ size_t n;
+ ucs4_t uc = 'd' | (i - 1026);
+ if (uc >= 0xd800 && uc <= 0xdfff)
+ uc |= 0x100000;
+ n = U_UCTOMB (c, uc, 6);
+ ASSERT (exp < input + length - 1);
+ ASSERT (U_CHR (prev, (length - 1) - (prev - input), uc) == exp);
+ ASSERT (memcmp (exp, c, n * sizeof (UNIT)) == 0);
+ prev = exp;
+ exp += n * 63;
+ }
+ }
+
+ ASSERT (U_CHR (input + 1, length - 1, 'a') == input + length - 1);
+ ASSERT (U_CHR (input + 1, length - 1, 'e') == input + length - 2);
+
+ ASSERT (U_CHR (input, length, 'f') == NULL);
+ ASSERT (U_CHR (input, length, '\0') == NULL);
+
+ /* Check that a very long haystack is handled quickly if the byte is
+ found near the beginning. */
+ {
+ size_t repeat = 10000;
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (U_CHR (input, length, 'c') == input + 2);
+ }
+ }
+
+ /* Alignment tests. */
+ {
+ int i, j;
+ for (i = 0; i < 32; i++)
+ {
+ for (j = 0; j < 128; j++)
+ input[i + j] = j;
+ for (j = 0; j < 128; j++)
+ {
+ ASSERT (U_CHR (input + i, 128, j) == input + i + j);
+ }
+ }
+ }
+
+ /* Check that uN_chr() does not read past the first occurrence of the
+ byte being searched. */
+ {
+ char *page_boundary = (char *) zerosize_ptr ();
+ size_t n;
+
+ if (page_boundary != NULL)
+ {
+ for (n = 1; n <= 500 / sizeof (UNIT); n++)
+ {
+ UNIT *mem = (UNIT *) (page_boundary - n * sizeof (UNIT));
+ U_SET (mem, 'X', n);
+ ASSERT (U_CHR (mem, n, 'U') == NULL);
+
+ {
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ {
+ mem[i] = 'U';
+ ASSERT (U_CHR (mem, 4000, 'U') == mem + i);
+ mem[i] = 'X';
+ }
+ }
+ }
+ }
+ }
+
+ free (input);
+ if (sizeof (UNIT) != sizeof (uint32_t))
+ free (input32);
+
+ return 0;
+}
diff --git a/gnulib-tests/unistr/test-cpy.h b/gnulib-tests/unistr/test-cpy.h
new file mode 100644
index 0000000..5a81f9c
--- /dev/null
+++ b/gnulib-tests/unistr/test-cpy.h
@@ -0,0 +1,44 @@
+/* Test of uN_cpy() functions.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+int
+main ()
+{
+ /* Test small copying operations. */
+ {
+ static const UNIT src[] = { 'c', 'l', 'i', 'm', 'a', 't', 'e' };
+ size_t n;
+
+ for (n = 0; n <= SIZEOF (src); n++)
+ {
+ UNIT dest[1 + SIZEOF (src) + 1] =
+ { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC };
+ UNIT *ret;
+ size_t i;
+
+ ret = U_CPY (dest + 1, src, n);
+ ASSERT (ret == dest + 1);
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < n; i++)
+ ASSERT (dest[1 + i] == src[i]);
+ ASSERT (dest[1 + n] == MAGIC);
+ }
+ }
+
+ return 0;
+}
diff --git a/gnulib-tests/unistr/test-pcpy.h b/gnulib-tests/unistr/test-pcpy.h
new file mode 100644
index 0000000..b54e3a9
--- /dev/null
+++ b/gnulib-tests/unistr/test-pcpy.h
@@ -0,0 +1,44 @@
+/* Test of uN_pcpy() functions.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+int
+main ()
+{
+ /* Test small copying operations. */
+ {
+ static const UNIT src[] = { 'c', 'l', 'i', 'm', 'a', 't', 'e' };
+ size_t n;
+
+ for (n = 0; n <= SIZEOF (src); n++)
+ {
+ UNIT dest[1 + SIZEOF (src) + 1] =
+ { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC };
+ UNIT *ret;
+ size_t i;
+
+ ret = U_PCPY (dest + 1, src, n);
+ ASSERT (ret == dest + 1 + n);
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < n; i++)
+ ASSERT (dest[1 + i] == src[i]);
+ ASSERT (dest[1 + n] == MAGIC);
+ }
+ }
+
+ return 0;
+}
diff --git a/gnulib-tests/unistr/test-set.h b/gnulib-tests/unistr/test-set.h
new file mode 100644
index 0000000..2eb6c74
--- /dev/null
+++ b/gnulib-tests/unistr/test-set.h
@@ -0,0 +1,44 @@
+/* Test of uN_set() functions.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+int
+main ()
+{
+ {
+#define NMAX 7
+ size_t n;
+
+ for (n = 0; n <= NMAX; n++)
+ {
+ UNIT dest[1 + NMAX + 1] =
+ { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC };
+ UNIT *ret;
+ size_t i;
+
+ ret = U_SET (dest + 1, VALUE, n);
+ ASSERT (ret == dest + 1);
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < n; i++)
+ ASSERT (dest[1 + i] == VALUE);
+ ASSERT (dest[1 + n] == MAGIC);
+ }
+#undef NMAX
+ }
+
+ return 0;
+}
diff --git a/gnulib-tests/unistr/test-strcat.h b/gnulib-tests/unistr/test-strcat.h
new file mode 100644
index 0000000..f18702b
--- /dev/null
+++ b/gnulib-tests/unistr/test-strcat.h
@@ -0,0 +1,56 @@
+/* Test of uN_strcat() functions.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+int
+main ()
+{
+ /* Test small copying operations. */
+ {
+ static const UNIT base[] = { 'C', 'h', 'a', 'n', 'g', 'i', 'n', 'g', 0 };
+ static const UNIT src[] = { 'c', 'l', 'i', 'm', 'a', 't', 'e', 0 };
+ size_t m;
+ size_t n;
+
+ for (m = 0; m < SIZEOF (base); m++)
+ for (n = 1; n <= SIZEOF (src); n++)
+ {
+ UNIT dest[1 + (SIZEOF (base) - 1) + SIZEOF (src) + 1] =
+ { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC,
+ MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC
+ };
+ UNIT *result;
+ size_t i;
+
+ for (i = 0; i < m; i++)
+ dest[1 + i] = base[i];
+ dest[1 + m] = 0;
+
+ result = U_STRCAT (dest + 1, src + SIZEOF (src) - n);
+ ASSERT (result == dest + 1);
+
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < m; i++)
+ ASSERT (dest[1 + i] == base[i]);
+ for (i = 0; i < n; i++)
+ ASSERT (dest[1 + m + i] == src[SIZEOF (src) - n + i]);
+ ASSERT (dest[1 + m + n] == MAGIC);
+ }
+ }
+
+ return 0;
+}
diff --git a/gnulib-tests/unistr/test-strncat.h b/gnulib-tests/unistr/test-strncat.h
new file mode 100644
index 0000000..b6f2026
--- /dev/null
+++ b/gnulib-tests/unistr/test-strncat.h
@@ -0,0 +1,90 @@
+/* Test of uN_strncat() functions.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+static void
+check_single (const UNIT *input, size_t length, size_t n)
+{
+ static const UNIT base[] = { 'C', 'h', 'a', 'n', 'g', 'i', 'n', 'g', 0 };
+ size_t m;
+
+ for (m = 0; m < SIZEOF (base); m++)
+ {
+ UNIT *dest;
+ UNIT *result;
+ size_t i;
+
+ dest = (UNIT *) malloc ((1 + m + n + 2) * sizeof (UNIT));
+ ASSERT (dest != NULL);
+
+ dest[0] = MAGIC;
+ for (i = 0; i < m; i++)
+ dest[1 + i] = base[i];
+ dest[1 + m] = 0;
+ for (i = 1; i < n + 2; i++)
+ dest[1 + m + i] = MAGIC;
+
+ result = U_STRNCAT (dest + 1, input, n);
+ ASSERT (result == dest + 1);
+
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < m; i++)
+ ASSERT (dest[1 + i] == base[i]);
+ for (i = 0; i < (n <= length ? n : length); i++)
+ ASSERT (dest[1 + m + i] == input[i]);
+ ASSERT (dest[1 + m + i] == 0);
+ ASSERT (dest[1 + m + i + 1] == MAGIC);
+
+ free (dest);
+ }
+}
+
+static void
+check (const UNIT *input, size_t input_length)
+{
+ size_t length;
+ size_t n;
+
+ ASSERT (input_length > 0);
+ ASSERT (input[input_length - 1] == 0);
+ length = input_length - 1; /* = U_STRLEN (input) */
+
+ for (n = 0; n <= 2 * length + 2; n++)
+ check_single (input, length, n);
+
+ /* Check that U_STRNCAT (D, S, N) does not look at more than
+ MIN (U_STRLEN (S) + 1, N) units. */
+ {
+ char *page_boundary = (char *) zerosize_ptr ();
+
+ if (page_boundary != NULL)
+ {
+ for (n = 0; n <= 2 * length + 2; n++)
+ {
+ size_t n_to_copy = (n <= length ? n : length + 1);
+ UNIT *copy;
+ size_t i;
+
+ copy = (UNIT *) page_boundary - n_to_copy;
+ for (i = 0; i < n_to_copy; i++)
+ copy[i] = input[i];
+
+ check_single (copy, length, n);
+ }
+ }
+ }
+}
diff --git a/gnulib-tests/unistr/test-u32-chr.c b/gnulib-tests/unistr/test-u32-chr.c
new file mode 100644
index 0000000..d12aad3
--- /dev/null
+++ b/gnulib-tests/unistr/test-u32-chr.c
@@ -0,0 +1,34 @@
+/* Test of u32_chr() function.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_UCTOMB(s, uc, n) (*(s) = (uc), 1)
+#define U32_TO_U(s, n, result, length) (*(length) = (n), (s))
+#define U_CHR u32_chr
+#define U_SET u32_set
+#include "test-chr.h"
diff --git a/gnulib-tests/unistr/test-u32-cpy.c b/gnulib-tests/unistr/test-u32-cpy.c
new file mode 100644
index 0000000..ef6c882
--- /dev/null
+++ b/gnulib-tests/unistr/test-u32-cpy.c
@@ -0,0 +1,28 @@
+/* Test of u32_cpy() function.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_CPY u32_cpy
+#define MAGIC 0xBADFACE
+#include "test-cpy.h"
diff --git a/gnulib-tests/unistr/test-u32-pcpy.c b/gnulib-tests/unistr/test-u32-pcpy.c
new file mode 100644
index 0000000..276fad4
--- /dev/null
+++ b/gnulib-tests/unistr/test-u32-pcpy.c
@@ -0,0 +1,28 @@
+/* Test of u32_pcpy() function.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_PCPY u32_pcpy
+#define MAGIC 0xBADFACE
+#include "test-pcpy.h"
diff --git a/gnulib-tests/unistr/test-u32-set.c b/gnulib-tests/unistr/test-u32-set.c
new file mode 100644
index 0000000..3d8d1d6
--- /dev/null
+++ b/gnulib-tests/unistr/test-u32-set.c
@@ -0,0 +1,29 @@
+/* Test of u32_set() function.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_SET u32_set
+#define MAGIC 0xBADFACE
+#define VALUE 0x1D51E
+#include "test-set.h"
diff --git a/gnulib-tests/unistr/test-u32-strcat.c b/gnulib-tests/unistr/test-u32-strcat.c
new file mode 100644
index 0000000..3123124
--- /dev/null
+++ b/gnulib-tests/unistr/test-u32-strcat.c
@@ -0,0 +1,28 @@
+/* Test of u32_strcat() function.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_STRCAT u32_strcat
+#define MAGIC 0xBADFACE
+#include "test-strcat.h"
diff --git a/gnulib-tests/unistr/test-u32-strlen.c b/gnulib-tests/unistr/test-u32-strlen.c
new file mode 100644
index 0000000..a485527
--- /dev/null
+++ b/gnulib-tests/unistr/test-u32-strlen.c
@@ -0,0 +1,57 @@
+/* Test of u32_strlen() function.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* Empty string. */
+ {
+ static const uint32_t input[] = { 0 };
+ ASSERT (u32_strlen (input) == 0);
+ }
+
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint32_t input[] =
+ { 'G', 'r', 0x00FC, 0x00DF, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0x0417, 0x0434, 0x0440, 0x0430, 0x0432, 0x0441, 0x0442, 0x0432, 0x0443,
+ 0x0439, 0x0442, 0x0435, '!', ' ',
+ 'x', '=', '(', '-', 'b', 0x00B1, 's', 'q', 'r', 't', '(', 'b', 0x00B2,
+ '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')', ' ', ' ',
+ 0x65E5, 0x672C, 0x8A9E, ',', 0x4E2D, 0x6587, ',', 0xD55C, 0xAE00, 0
+ };
+ ASSERT (u32_strlen (input) == SIZEOF (input) - 1);
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint32_t input[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E, 0
+ };
+ ASSERT (u32_strlen (input) == SIZEOF (input) - 1);
+ }
+
+ return 0;
+}
diff --git a/gnulib-tests/unistr/test-u8-mbtoucr.c b/gnulib-tests/unistr/test-u8-mbtoucr.c
new file mode 100644
index 0000000..6628b70
--- /dev/null
+++ b/gnulib-tests/unistr/test-u8-mbtoucr.c
@@ -0,0 +1,187 @@
+/* Test of u8_mbtoucr() function.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ ucs4_t uc;
+ int ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint8_t input[] = "";
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint8_t buf[1];
+
+ for (c = 0; c < 0x80; c++)
+ {
+ buf[0] = c;
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, buf, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test 2-byte character input. */
+ {
+ static const uint8_t input[] = { 0xC3, 0x97 };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 2);
+ ASSERT (ret == 2);
+ ASSERT (uc == 0x00D7);
+ }
+
+ /* Test 3-byte character input. */
+ {
+ static const uint8_t input[] = { 0xE2, 0x82, 0xAC };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 3);
+ ASSERT (ret == 3);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test 4-byte character input. */
+ {
+ static const uint8_t input[] = { 0xF4, 0x8F, 0xBF, 0xBD };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 4);
+ ASSERT (ret == 4);
+ ASSERT (uc == 0x10FFFD);
+ }
+
+ /* Test incomplete/invalid 1-byte input. */
+ {
+ static const uint8_t input[] = { 0xC1 };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 1);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xC3 };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 1);
+ ASSERT (ret == -2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xE2 };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 1);
+ ASSERT (ret == -2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF4 };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 1);
+ ASSERT (ret == -2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xFE };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 1);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ /* Test incomplete/invalid 2-byte input. */
+ {
+ static const uint8_t input[] = { 0xE0, 0x9F };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 2);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0x82 };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 2);
+ ASSERT (ret == -2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0xD0 };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 2);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF0, 0x8F };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 2);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 2);
+ ASSERT (ret == -2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0 };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 2);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ /* Test incomplete/invalid 3-byte input. */
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xBF };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 3);
+ ASSERT (ret == -2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0, 0xBF };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 3);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xD0 };
+ uc = 0xBADFACE;
+ ret = u8_mbtoucr (&uc, input, 3);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ return 0;
+}
diff --git a/gnulib-tests/unistr/test-u8-uctomb.c b/gnulib-tests/unistr/test-u8-uctomb.c
new file mode 100644
index 0000000..7e8b518
--- /dev/null
+++ b/gnulib-tests/unistr/test-u8-uctomb.c
@@ -0,0 +1,157 @@
+/* Test of u8_uctomb() function.
+ Copyright (C) 2010-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define MAGIC 0xBA
+
+int
+main ()
+{
+ /* Test ISO 646 character, in particular the NUL character. */
+ {
+ ucs4_t uc;
+
+ for (uc = 0; uc < 0x80; uc++)
+ {
+ uint8_t buf[5] = { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC };
+ int ret;
+
+ ret = u8_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 1);
+ ASSERT (ret == 1);
+ ASSERT (buf[0] == uc);
+ ASSERT (buf[1] == MAGIC);
+ }
+ }
+
+ /* Test 2-byte character. */
+ {
+ ucs4_t uc = 0x00D7;
+ uint8_t buf[5] = { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC };
+ int ret;
+
+ ret = u8_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 1);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 2);
+ ASSERT (ret == 2);
+ ASSERT (buf[0] == 0xC3);
+ ASSERT (buf[1] == 0x97);
+ ASSERT (buf[2] == MAGIC);
+ }
+
+ /* Test 3-byte character. */
+ {
+ ucs4_t uc = 0x20AC;
+ uint8_t buf[5] = { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC };
+ int ret;
+
+ ret = u8_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 1);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 2);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+ ASSERT (buf[1] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 3);
+ ASSERT (ret == 3);
+ ASSERT (buf[0] == 0xE2);
+ ASSERT (buf[1] == 0x82);
+ ASSERT (buf[2] == 0xAC);
+ ASSERT (buf[3] == MAGIC);
+ }
+
+ /* Test 4-byte character. */
+ {
+ ucs4_t uc = 0x10FFFD;
+ uint8_t buf[5] = { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC };
+ int ret;
+
+ ret = u8_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 1);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 2);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+ ASSERT (buf[1] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 3);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+ ASSERT (buf[1] == MAGIC);
+ ASSERT (buf[2] == MAGIC);
+
+ ret = u8_uctomb (buf, uc, 4);
+ ASSERT (ret == 4);
+ ASSERT (buf[0] == 0xF4);
+ ASSERT (buf[1] == 0x8F);
+ ASSERT (buf[2] == 0xBF);
+ ASSERT (buf[3] == 0xBD);
+ ASSERT (buf[4] == MAGIC);
+ }
+
+ /* Test invalid characters. */
+ {
+ ucs4_t invalid[] = { 0x110000, 0xD800, 0xDBFF, 0xDC00, 0xDFFF };
+ uint8_t buf[5] = { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC };
+ size_t i;
+
+ for (i = 0; i < SIZEOF (invalid); i++)
+ {
+ ucs4_t uc = invalid[i];
+ int n;
+
+ for (n = 0; n <= 4; n++)
+ {
+ int ret = u8_uctomb (buf, uc, n);
+ ASSERT (ret == -1);
+ ASSERT (buf[0] == MAGIC);
+ ASSERT (buf[1] == MAGIC);
+ ASSERT (buf[2] == MAGIC);
+ ASSERT (buf[3] == MAGIC);
+ ASSERT (buf[4] == MAGIC);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/gnulib-tests/unistr/u-set.h b/gnulib-tests/unistr/u-set.h
new file mode 100644
index 0000000..7e1e6b5
--- /dev/null
+++ b/gnulib-tests/unistr/u-set.h
@@ -0,0 +1,47 @@
+/* Fill UTF-8/UTF-16/UTF-32 string.
+ Copyright (C) 1999, 2002, 2006, 2009-2023 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2002.
+
+ This file is free software.
+ It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+".
+ You can redistribute it and/or modify it under either
+ - the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 3, or (at your
+ option) any later version, or
+ - the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option)
+ any later version, or
+ - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+".
+
+ This file 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 and the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License and of the GNU General Public License along with this
+ program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+
+UNIT *
+FUNC (UNIT *s, ucs4_t uc, size_t n)
+{
+ if (n > 0)
+ {
+ if (IS_SINGLE_UNIT (uc))
+ {
+ UNIT *ptr = s;
+
+ for (; n > 0; n--)
+ *ptr++ = uc;
+ }
+ else
+ {
+ errno = EILSEQ;
+ return NULL;
+ }
+ }
+ return s;
+}
diff --git a/gnulib-tests/unistr/u32-set.c b/gnulib-tests/unistr/u32-set.c
new file mode 100644
index 0000000..5507efd
--- /dev/null
+++ b/gnulib-tests/unistr/u32-set.c
@@ -0,0 +1,34 @@
+/* Fill UTF-32 string.
+ Copyright (C) 1999, 2002, 2006, 2009-2023 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2002.
+
+ This file is free software.
+ It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+".
+ You can redistribute it and/or modify it under either
+ - the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 3, or (at your
+ option) any later version, or
+ - the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option)
+ any later version, or
+ - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+".
+
+ This file 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 and the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License and of the GNU General Public License along with this
+ program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include "unistr.h"
+
+#define FUNC u32_set
+#define UNIT uint32_t
+#define IS_SINGLE_UNIT(uc) (uc < 0xd800 || (uc >= 0xe000 && uc < 0x110000))
+#include "u-set.h"