summaryrefslogtreecommitdiff
path: root/tests/unistr
diff options
context:
space:
mode:
authorAndreas Rottmann <a.rottmann@gmx.at>2010-05-27 18:23:17 +0200
committerAndreas Rottmann <a.rottmann@gmx.at>2010-05-27 18:23:17 +0200
commitbd6adfa17d453e4c486e36fed4c5779db90a8a0e (patch)
tree9798677560d5f99061afe9f0db105a8c97f2438a /tests/unistr
parent79ca645d222db2e158784642c3b464a47bea26f3 (diff)
parent3e0814cd9862b89c7a39672672937477bd87ddfb (diff)
Merge commit 'upstream/0.9.3'
Diffstat (limited to 'tests/unistr')
-rw-r--r--tests/unistr/test-chr.h103
-rw-r--r--tests/unistr/test-cmp.h97
-rw-r--r--tests/unistr/test-cmp2.h56
-rw-r--r--tests/unistr/test-cpy-alloc.h41
-rw-r--r--tests/unistr/test-cpy.h44
-rw-r--r--tests/unistr/test-move.h152
-rw-r--r--tests/unistr/test-set.h44
-rw-r--r--tests/unistr/test-stpcpy.h47
-rw-r--r--tests/unistr/test-stpncpy.h79
-rw-r--r--tests/unistr/test-strcat.h56
-rw-r--r--tests/unistr/test-strcmp.h56
-rw-r--r--tests/unistr/test-strcpy.h47
-rw-r--r--tests/unistr/test-strdup.h41
-rw-r--r--tests/unistr/test-strncat.h90
-rw-r--r--tests/unistr/test-strncmp.h92
-rw-r--r--tests/unistr/test-strncpy.h79
-rw-r--r--tests/unistr/test-strnlen.h60
-rw-r--r--tests/unistr/test-u16-check.c66
-rw-r--r--tests/unistr/test-u16-chr.c31
-rw-r--r--tests/unistr/test-u16-cmp.c47
-rw-r--r--tests/unistr/test-u16-cmp2.c28
-rw-r--r--tests/unistr/test-u16-cpy-alloc.c29
-rw-r--r--tests/unistr/test-u16-cpy.c28
-rw-r--r--tests/unistr/test-u16-mblen.c84
-rw-r--r--tests/unistr/test-u16-mbsnlen.c68
-rw-r--r--tests/unistr/test-u16-mbtouc-unsafe.c33
-rw-r--r--tests/unistr/test-u16-mbtouc.c33
-rw-r--r--tests/unistr/test-u16-mbtouc.h82
-rw-r--r--tests/unistr/test-u16-mbtoucr.c90
-rw-r--r--tests/unistr/test-u16-move.c28
-rw-r--r--tests/unistr/test-u16-next.c91
-rw-r--r--tests/unistr/test-u16-prev.c175
-rw-r--r--tests/unistr/test-u16-set.c29
-rw-r--r--tests/unistr/test-u16-stpcpy.c28
-rw-r--r--tests/unistr/test-u16-stpncpy.c59
-rw-r--r--tests/unistr/test-u16-strcat.c28
-rw-r--r--tests/unistr/test-u16-strcmp.c34
-rw-r--r--tests/unistr/test-u16-strcmp.h42
-rw-r--r--tests/unistr/test-u16-strcoll.c41
-rw-r--r--tests/unistr/test-u16-strcpy.c28
-rw-r--r--tests/unistr/test-u16-strdup.c27
-rw-r--r--tests/unistr/test-u16-strlen.c57
-rw-r--r--tests/unistr/test-u16-strmblen.c78
-rw-r--r--tests/unistr/test-u16-strmbtouc.c91
-rw-r--r--tests/unistr/test-u16-strncat.c59
-rw-r--r--tests/unistr/test-u16-strncmp.c47
-rw-r--r--tests/unistr/test-u16-strncpy.c59
-rw-r--r--tests/unistr/test-u16-strnlen.c56
-rw-r--r--tests/unistr/test-u16-to-u32.c156
-rw-r--r--tests/unistr/test-u16-to-u8.c159
-rw-r--r--tests/unistr/test-u16-uctomb.c110
-rw-r--r--tests/unistr/test-u32-check.c66
-rw-r--r--tests/unistr/test-u32-chr.c31
-rw-r--r--tests/unistr/test-u32-cmp.c45
-rw-r--r--tests/unistr/test-u32-cmp2.c28
-rw-r--r--tests/unistr/test-u32-cpy-alloc.c29
-rw-r--r--tests/unistr/test-u32-cpy.c28
-rw-r--r--tests/unistr/test-u32-mblen.c81
-rw-r--r--tests/unistr/test-u32-mbsnlen.c63
-rw-r--r--tests/unistr/test-u32-mbtouc-unsafe.c33
-rw-r--r--tests/unistr/test-u32-mbtouc.c36
-rw-r--r--tests/unistr/test-u32-mbtouc.h77
-rw-r--r--tests/unistr/test-u32-mbtoucr.c83
-rw-r--r--tests/unistr/test-u32-move.c28
-rw-r--r--tests/unistr/test-u32-next.c86
-rw-r--r--tests/unistr/test-u32-prev.c133
-rw-r--r--tests/unistr/test-u32-set.c29
-rw-r--r--tests/unistr/test-u32-stpcpy.c28
-rw-r--r--tests/unistr/test-u32-stpncpy.c59
-rw-r--r--tests/unistr/test-u32-strcat.c28
-rw-r--r--tests/unistr/test-u32-strcmp.c34
-rw-r--r--tests/unistr/test-u32-strcmp.h42
-rw-r--r--tests/unistr/test-u32-strcoll.c41
-rw-r--r--tests/unistr/test-u32-strcpy.c28
-rw-r--r--tests/unistr/test-u32-strdup.c27
-rw-r--r--tests/unistr/test-u32-strlen.c57
-rw-r--r--tests/unistr/test-u32-strmblen.c75
-rw-r--r--tests/unistr/test-u32-strmbtouc.c86
-rw-r--r--tests/unistr/test-u32-strncat.c59
-rw-r--r--tests/unistr/test-u32-strncmp.c47
-rw-r--r--tests/unistr/test-u32-strncpy.c59
-rw-r--r--tests/unistr/test-u32-strnlen.c56
-rw-r--r--tests/unistr/test-u32-to-u16.c156
-rw-r--r--tests/unistr/test-u32-to-u8.c159
-rw-r--r--tests/unistr/test-u32-uctomb.c104
-rw-r--r--tests/unistr/test-u8-check.c188
-rw-r--r--tests/unistr/test-u8-chr.c31
-rw-r--r--tests/unistr/test-u8-cmp.c45
-rw-r--r--tests/unistr/test-u8-cmp2.c28
-rw-r--r--tests/unistr/test-u8-cpy-alloc.c29
-rw-r--r--tests/unistr/test-u8-cpy.c28
-rw-r--r--tests/unistr/test-u8-mblen.c155
-rw-r--r--tests/unistr/test-u8-mbsnlen.c61
-rw-r--r--tests/unistr/test-u8-mbtouc-unsafe.c33
-rw-r--r--tests/unistr/test-u8-mbtouc.c33
-rw-r--r--tests/unistr/test-u8-mbtouc.h179
-rw-r--r--tests/unistr/test-u8-mbtoucr.c187
-rw-r--r--tests/unistr/test-u8-move.c28
-rw-r--r--tests/unistr/test-u8-next.c188
-rw-r--r--tests/unistr/test-u8-prev.c315
-rw-r--r--tests/unistr/test-u8-set.c29
-rw-r--r--tests/unistr/test-u8-stpcpy.c28
-rw-r--r--tests/unistr/test-u8-stpncpy.c52
-rw-r--r--tests/unistr/test-u8-strcat.c28
-rw-r--r--tests/unistr/test-u8-strcmp.c34
-rw-r--r--tests/unistr/test-u8-strcmp.h42
-rw-r--r--tests/unistr/test-u8-strcoll.c41
-rw-r--r--tests/unistr/test-u8-strcpy.c28
-rw-r--r--tests/unistr/test-u8-strdup.c27
-rw-r--r--tests/unistr/test-u8-strlen.c50
-rw-r--r--tests/unistr/test-u8-strmblen.c149
-rw-r--r--tests/unistr/test-u8-strmbtouc.c188
-rw-r--r--tests/unistr/test-u8-strncat.c52
-rw-r--r--tests/unistr/test-u8-strncmp.c53
-rw-r--r--tests/unistr/test-u8-strncpy.c52
-rw-r--r--tests/unistr/test-u8-strnlen.c49
-rw-r--r--tests/unistr/test-u8-to-u16.c158
-rw-r--r--tests/unistr/test-u8-to-u32.c158
-rw-r--r--tests/unistr/test-u8-uctomb.c157
119 files changed, 8209 insertions, 0 deletions
diff --git a/tests/unistr/test-chr.h b/tests/unistr/test-chr.h
new file mode 100644
index 00000000..5a021c2d
--- /dev/null
+++ b/tests/unistr/test-chr.h
@@ -0,0 +1,103 @@
+/* Test of uN_chr() functions.
+ Copyright (C) 2008-2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake and Bruno Haible <bruno@clisp.org>, 2010. */
+
+int
+main (void)
+{
+ size_t n = 0x100000;
+ UNIT *input = (UNIT *) malloc (n * sizeof (UNIT));
+ ASSERT (input);
+
+ input[0] = 'a';
+ input[1] = 'b';
+ U_SET (input + 2, 'c', 1024);
+ U_SET (input + 1026, 'd', n - 1028);
+ input[n - 2] = 'e';
+ input[n - 1] = 'a';
+
+ /* Basic behavior tests. */
+ ASSERT (U_CHR (input, n, 'a') == input);
+
+ ASSERT (U_CHR (input, 0, 'a') == NULL);
+ ASSERT (U_CHR (zerosize_ptr (), 0, 'a') == NULL);
+
+ ASSERT (U_CHR (input, n, 'b') == input + 1);
+ ASSERT (U_CHR (input, n, 'c') == input + 2);
+ ASSERT (U_CHR (input, n, 'd') == input + 1026);
+
+ ASSERT (U_CHR (input + 1, n - 1, 'a') == input + n - 1);
+ ASSERT (U_CHR (input + 1, n - 1, 'e') == input + n - 2);
+
+ ASSERT (U_CHR (input, n, 'f') == NULL);
+ ASSERT (U_CHR (input, n, '\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, n, '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 ();
+
+ 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);
+
+ return 0;
+}
diff --git a/tests/unistr/test-cmp.h b/tests/unistr/test-cmp.h
new file mode 100644
index 00000000..e536f482
--- /dev/null
+++ b/tests/unistr/test-cmp.h
@@ -0,0 +1,97 @@
+/* Test of uN_cmp() functions.
+ Copyright (C) 2008-2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Simon Josefsson and Bruno Haible <bruno@clisp.org>, 2010. */
+
+static void
+test_cmp (void)
+{
+ /* Test equal / not equal distinction. */
+ ASSERT (U_CMP (zerosize_ptr (), zerosize_ptr (), 0) == 0);
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'f', 'o', 'o', 'b', 'a', 'r', 0 };
+ ASSERT (U_CMP (input1, input2, 2) == 0);
+ ASSERT (U_CMP (input1, input2, 3) == 0);
+ ASSERT (U_CMP (input1, input2, 4) != 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'b', 'a', 'r', 0 };
+ ASSERT (U_CMP (input1, input2, 1) != 0);
+ ASSERT (U_CMP (input1, input2, 3) != 0);
+ }
+
+ /* Test less / equal / greater distinction. */
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'm', 'o', 'o', 0 };
+ ASSERT (U_CMP (input1, input2, 4) < 0);
+ ASSERT (U_CMP (input2, input1, 4) > 0);
+ }
+ {
+ static const UNIT input1[] = { 'o', 'o', 'm', 'p', 'h', 0 };
+ static const UNIT input2[] = { 'o', 'o', 'p', 's', 0 };
+ ASSERT (U_CMP (input1, input2, 3) < 0);
+ ASSERT (U_CMP (input2, input1, 3) > 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'f', 'o', 'o', 'b', 'a', 'r', 0 };
+ ASSERT (U_CMP (input1, input2, 4) < 0);
+ ASSERT (U_CMP (input2, input1, 4) > 0);
+ }
+
+ /* Some old versions of memcmp were not 8-bit clean. */
+ {
+ static const UNIT input1[] = { 0x40 };
+ static const UNIT input2[] = { 0xC2 };
+ ASSERT (U_CMP (input1, input2, 1) < 0);
+ ASSERT (U_CMP (input2, input1, 1) > 0);
+ }
+ {
+ static const UNIT input1[] = { 0xC2 };
+ static const UNIT input2[] = { 0xC3 };
+ ASSERT (U_CMP (input1, input2, 1) < 0);
+ ASSERT (U_CMP (input2, input1, 1) > 0);
+ }
+
+ /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
+ or more and with at least one buffer not starting on a 4-byte boundary.
+ William Lewis provided this test program. */
+ {
+ UNIT foo[21];
+ UNIT bar[21];
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ UNIT *a = foo + i;
+ UNIT *b = bar + i;
+ int j;
+ for (j = 0; j < 8; j++)
+ a[j] = '-';
+ a[8] = '0';
+ for (j = 9; j < 16; j++)
+ a[j] = '1';
+ for (j = 0; j < 8; j++)
+ b[j] = '-';
+ b[8] = '1';
+ for (j = 9; j < 16; j++)
+ b[j] = '0';
+ ASSERT (U_CMP (a, b, 16) < 0);
+ }
+ }
+}
diff --git a/tests/unistr/test-cmp2.h b/tests/unistr/test-cmp2.h
new file mode 100644
index 00000000..261fe365
--- /dev/null
+++ b/tests/unistr/test-cmp2.h
@@ -0,0 +1,56 @@
+/* Test of uN_cmp2() functions.
+ Copyright (C) 2008-2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Simon Josefsson and Bruno Haible <bruno@clisp.org>, 2010. */
+
+int
+main ()
+{
+ {
+ static const UNIT input1[] = { 'a' };
+ static const UNIT input2[] = { 'b' };
+ ASSERT (U_CMP2 (input1, 0, input2, 0) == 0);
+ ASSERT (U_CMP2 (input1, 1, input2, 0) > 0);
+ ASSERT (U_CMP2 (input1, 0, input2, 1) < 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'f', 'o', 'o', 'b', 'a', 'r', 0 };
+ ASSERT (U_CMP2 (input1, 3, input2, 3) == 0);
+ ASSERT (U_CMP2 (input1, 4, input2, 3) > 0);
+ ASSERT (U_CMP2 (input2, 3, input1, 4) < 0);
+ ASSERT (U_CMP2 (input1, 3, input2, 4) < 0);
+ ASSERT (U_CMP2 (input2, 4, input1, 3) > 0);
+ ASSERT (U_CMP2 (input1, 4, input2, 4) < 0);
+ ASSERT (U_CMP2 (input2, 4, input1, 4) > 0);
+ ASSERT (U_CMP2 (input1, 3, input2, 7) < 0);
+ ASSERT (U_CMP2 (input2, 7, input1, 3) > 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o' };
+ static const UNIT input2[] = { 'm', 'o', 'o' };
+ ASSERT (U_CMP2 (input1, 3, input2, 3) < 0);
+ ASSERT (U_CMP2 (input2, 3, input1, 3) > 0);
+ }
+ {
+ static const UNIT input1[] = { 'o', 'o', 'm', 'p', 'h' };
+ static const UNIT input2[] = { 'o', 'o', 'p', 's' };
+ ASSERT (U_CMP2 (input1, 5, input2, 4) < 0);
+ ASSERT (U_CMP2 (input2, 4, input1, 5) > 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-cpy-alloc.h b/tests/unistr/test-cpy-alloc.h
new file mode 100644
index 00000000..795e0b77
--- /dev/null
+++ b/tests/unistr/test-cpy-alloc.h
@@ -0,0 +1,41 @@
+/* Test of uN_cpy_alloc() functions.
+ Copyright (C) 2010 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 <http://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 *result = U_CPY_ALLOC (src, n);
+ size_t i;
+
+ ASSERT (result != NULL);
+ for (i = 0; i < n; i++)
+ ASSERT (result[i] == src[i]);
+
+ free (result);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-cpy.h b/tests/unistr/test-cpy.h
new file mode 100644
index 00000000..b62fd14f
--- /dev/null
+++ b/tests/unistr/test-cpy.h
@@ -0,0 +1,44 @@
+/* Test of uN_cpy() functions.
+ Copyright (C) 2010 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 <http://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/tests/unistr/test-move.h b/tests/unistr/test-move.h
new file mode 100644
index 00000000..2462367d
--- /dev/null
+++ b/tests/unistr/test-move.h
@@ -0,0 +1,152 @@
+/* Test of uN_move() functions.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+int
+main ()
+{
+ /* Test copying operations with disjoint source and destination. */
+ {
+ 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_MOVE (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);
+ }
+ }
+
+ /* Test copying operations with overlap, in-place. */
+ {
+ 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];
+ UNIT *ret;
+ size_t i;
+
+ dest[0] = MAGIC;
+ for (i = 0; i < n; i++)
+ dest[1 + i] = src[i];
+ dest[1 + n] = MAGIC;
+
+ ret = U_MOVE (dest + 1, dest + 1, 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);
+ }
+ }
+
+ /* Test copying operations with overlap, moving downward. */
+ {
+ static const UNIT src[] = { 'c', 'l', 'i', 'm', 'a', 't', 'e' };
+ static const UNIT src2[] = { 'C', 'L', 'I', 'M', 'A', 'T', 'E' };
+ size_t d;
+
+ ASSERT (SIZEOF (src) == SIZEOF (src2));
+ for (d = 0; d <= SIZEOF (src); d++)
+ {
+ size_t n;
+
+ for (n = 0; n <= SIZEOF (src); n++)
+ {
+ UNIT dest[1 + 2 * SIZEOF (src) + 1];
+ UNIT *ret;
+ size_t i;
+
+ dest[0] = MAGIC;
+ for (i = 0; i < SIZEOF (src2); i++)
+ dest[1 + i] = src2[i];
+ for (i = 0; i < SIZEOF (src); i++)
+ dest[1 + SIZEOF (src) + i] = src[i];
+ dest[1 + 2 * SIZEOF (src)] = MAGIC;
+
+ ret =
+ U_MOVE (dest + 1 + SIZEOF (src) - d, dest + 1 + SIZEOF (src), n);
+ ASSERT (ret == dest + 1 + SIZEOF (src) - d);
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < SIZEOF (src) - d; i++)
+ ASSERT (dest[1 + i] == src2[i]);
+ for (i = 0; i < n; i++)
+ ASSERT (dest[1 + SIZEOF (src) - d + i] == src[i]);
+ for (i = SIZEOF (src) - d + n; i < SIZEOF (src2); i++)
+ ASSERT (dest[1 + i] == src2[i]);
+ for (i = (n >= d ? n - d : 0); i < SIZEOF (src); i++)
+ ASSERT (dest[1 + SIZEOF (src) + i] == src[i]);
+ ASSERT (dest[1 + 2 * SIZEOF (src)] == MAGIC);
+ }
+ }
+ }
+
+ /* Test copying operations with overlap, moving upward. */
+ {
+ static const UNIT src[] = { 'c', 'l', 'i', 'm', 'a', 't', 'e' };
+ static const UNIT src2[] = { 'C', 'L', 'I', 'M', 'A', 'T', 'E' };
+ size_t d;
+
+ ASSERT (SIZEOF (src) == SIZEOF (src2));
+ for (d = 0; d <= SIZEOF (src); d++)
+ {
+ size_t n;
+
+ for (n = 0; n <= SIZEOF (src); n++)
+ {
+ UNIT dest[1 + 2 * SIZEOF (src) + 1];
+ UNIT *ret;
+ size_t i;
+
+ dest[0] = MAGIC;
+ for (i = 0; i < SIZEOF (src); i++)
+ dest[1 + i] = src[i];
+ for (i = 0; i < SIZEOF (src2); i++)
+ dest[1 + SIZEOF (src) + i] = src2[i];
+ dest[1 + 2 * SIZEOF (src)] = MAGIC;
+
+ ret = U_MOVE (dest + 1 + d, dest + 1, n);
+ ASSERT (ret == dest + 1 + d);
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < d; i++)
+ ASSERT (dest[1 + i] == src[i]);
+ for (i = 0; i < n; i++)
+ ASSERT (dest[1 + d + i] == src[i]);
+ for (i = d + n; i < SIZEOF (src); i++)
+ ASSERT (dest[1 + i] == src[i]);
+ for (i = (d + n >= SIZEOF (src) ? d + n - SIZEOF (src) : 0);
+ i < SIZEOF (src2);
+ i++)
+ ASSERT (dest[1 + SIZEOF (src) + i] == src2[i]);
+ ASSERT (dest[1 + 2 * SIZEOF (src)] == MAGIC);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-set.h b/tests/unistr/test-set.h
new file mode 100644
index 00000000..56924dc3
--- /dev/null
+++ b/tests/unistr/test-set.h
@@ -0,0 +1,44 @@
+/* Test of uN_set() functions.
+ Copyright (C) 2010 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 <http://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/tests/unistr/test-stpcpy.h b/tests/unistr/test-stpcpy.h
new file mode 100644
index 00000000..76065dc4
--- /dev/null
+++ b/tests/unistr/test-stpcpy.h
@@ -0,0 +1,47 @@
+/* Test of uN_stpcpy() functions.
+ Copyright (C) 2010 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 <http://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', 0 };
+ size_t n;
+
+ for (n = 1; n <= SIZEOF (src); n++)
+ {
+ UNIT dest[1 + SIZEOF (src) + 1] =
+ { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC,
+ MAGIC
+ };
+ UNIT *result;
+ size_t i;
+
+ result = U_STPCPY (dest + 1, src + SIZEOF (src) - n);
+ ASSERT (result == dest + n);
+
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < n; i++)
+ ASSERT (dest[1 + i] == src[SIZEOF (src) - n + i]);
+ ASSERT (dest[1 + n] == MAGIC);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-stpncpy.h b/tests/unistr/test-stpncpy.h
new file mode 100644
index 00000000..bb81ff00
--- /dev/null
+++ b/tests/unistr/test-stpncpy.h
@@ -0,0 +1,79 @@
+/* Test of uN_stpncpy() functions.
+ Copyright (C) 2010 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 <http://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)
+{
+ UNIT *dest;
+ UNIT *result;
+ size_t i;
+
+ dest = (UNIT *) malloc ((1 + n + 1) * sizeof (UNIT));
+ ASSERT (dest != NULL);
+
+ for (i = 0; i < 1 + n + 1; i++)
+ dest[i] = MAGIC;
+
+ result = U_STPNCPY (dest + 1, input, n);
+ ASSERT (result == dest + 1 + (n <= length ? n : length));
+
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < (n <= length ? n : length + 1); i++)
+ ASSERT (dest[1 + i] == input[i]);
+ for (; i < n; i++)
+ ASSERT (dest[1 + i] == 0);
+ ASSERT (dest[1 + n] == 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_STPNCPY (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/tests/unistr/test-strcat.h b/tests/unistr/test-strcat.h
new file mode 100644
index 00000000..6c1f90dc
--- /dev/null
+++ b/tests/unistr/test-strcat.h
@@ -0,0 +1,56 @@
+/* Test of uN_strcat() functions.
+ Copyright (C) 2010 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 <http://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/tests/unistr/test-strcmp.h b/tests/unistr/test-strcmp.h
new file mode 100644
index 00000000..485b6f91
--- /dev/null
+++ b/tests/unistr/test-strcmp.h
@@ -0,0 +1,56 @@
+/* Test of uN_strcmp() and uN_strcoll() functions.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+static void
+test_strcmp (void)
+{
+ {
+ static const UNIT input1[] = { 0 };
+ static const UNIT input2[] = { 0 };
+ ASSERT (U_STRCMP (input1, input2) == 0);
+ }
+ {
+ static const UNIT input1[] = { 0 };
+ static const UNIT input2[] = { 'f', 'o', 'o', 0 };
+ ASSERT (U_STRCMP (input1, input2) < 0);
+ ASSERT (U_STRCMP (input2, input1) > 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'f', 'o', 'o', 0 };
+ ASSERT (U_STRCMP (input1, input2) == 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'b', 'a', 'r', 0 };
+ ASSERT (U_STRCMP (input1, input2) > 0);
+ ASSERT (U_STRCMP (input2, input1) < 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'f', 'o', 'o', 'b', 'a', 'r', 0 };
+ ASSERT (U_STRCMP (input1, input2) < 0);
+ ASSERT (U_STRCMP (input2, input1) > 0);
+ }
+ {
+ static const UNIT input1[] = { 'o', 'o', 'm', 'p', 'h', 0 };
+ static const UNIT input2[] = { 'o', 'o', 'p', 's', 0 };
+ ASSERT (U_STRCMP (input1, input2) < 0);
+ ASSERT (U_STRCMP (input2, input1) > 0);
+ }
+}
diff --git a/tests/unistr/test-strcpy.h b/tests/unistr/test-strcpy.h
new file mode 100644
index 00000000..f8fe5efd
--- /dev/null
+++ b/tests/unistr/test-strcpy.h
@@ -0,0 +1,47 @@
+/* Test of uN_strcpy() functions.
+ Copyright (C) 2010 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 <http://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', 0 };
+ size_t n;
+
+ for (n = 1; n <= SIZEOF (src); n++)
+ {
+ UNIT dest[1 + SIZEOF (src) + 1] =
+ { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC,
+ MAGIC
+ };
+ UNIT *result;
+ size_t i;
+
+ result = U_STRCPY (dest + 1, src + SIZEOF (src) - n);
+ ASSERT (result == dest + 1);
+
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < n; i++)
+ ASSERT (dest[1 + i] == src[SIZEOF (src) - n + i]);
+ ASSERT (dest[1 + n] == MAGIC);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-strdup.h b/tests/unistr/test-strdup.h
new file mode 100644
index 00000000..1684b39d
--- /dev/null
+++ b/tests/unistr/test-strdup.h
@@ -0,0 +1,41 @@
+/* Test of uN_strdup() functions.
+ Copyright (C) 2010 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 <http://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', 0 };
+ size_t n;
+
+ for (n = 1; n <= SIZEOF (src); n++)
+ {
+ UNIT *result = U_STRDUP (src + SIZEOF (src) - n);
+ size_t i;
+
+ ASSERT (result != NULL);
+ for (i = 0; i < n; i++)
+ ASSERT (result[i] == src[SIZEOF (src) - n + i]);
+
+ free (result);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-strncat.h b/tests/unistr/test-strncat.h
new file mode 100644
index 00000000..0445b6d9
--- /dev/null
+++ b/tests/unistr/test-strncat.h
@@ -0,0 +1,90 @@
+/* Test of uN_strncat() functions.
+ Copyright (C) 2010 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 <http://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/tests/unistr/test-strncmp.h b/tests/unistr/test-strncmp.h
new file mode 100644
index 00000000..628db94c
--- /dev/null
+++ b/tests/unistr/test-strncmp.h
@@ -0,0 +1,92 @@
+/* Test of uN_strncmp() functions.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+static void
+test_strncmp (void)
+{
+ {
+ static const UNIT input1[] = { 0 };
+ static const UNIT input2[] = { 0 };
+ ASSERT (U_STRNCMP (input1, input2, 0) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 1) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 1000000) == 0);
+ }
+ {
+ static const UNIT input1[] = { 0 };
+ static const UNIT input2[] = { 'f', 'o', 'o', 0 };
+ ASSERT (U_STRNCMP (input1, input2, 0) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 1) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 1) > 0);
+ ASSERT (U_STRNCMP (input1, input2, 3) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 3) > 0);
+ ASSERT (U_STRNCMP (input1, input2, 4) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 4) > 0);
+ ASSERT (U_STRNCMP (input1, input2, 1000000) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 1000000) > 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'f', 'o', 'o', 0 };
+ ASSERT (U_STRNCMP (input1, input2, 0) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 1) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 2) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 3) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 4) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 1000000) == 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'b', 'a', 'r', 0 };
+ ASSERT (U_STRNCMP (input1, input2, 0) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 1) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 1) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 2) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 2) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 1000000) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 1000000) < 0);
+ }
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 'f', 'o', 'o', 'b', 'a', 'r', 0 };
+ ASSERT (U_STRNCMP (input1, input2, 0) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 1) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 2) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 3) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 4) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 4) > 0);
+ ASSERT (U_STRNCMP (input1, input2, 1000000) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 1000000) > 0);
+ }
+ {
+ static const UNIT input1[] = { 'o', 'o', 'm', 'p', 'h', 0 };
+ static const UNIT input2[] = { 'o', 'o', 'p', 's', 0 };
+ ASSERT (U_STRNCMP (input1, input2, 0) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 1) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 2) == 0);
+ ASSERT (U_STRNCMP (input1, input2, 3) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 3) > 0);
+ ASSERT (U_STRNCMP (input1, input2, 4) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 4) > 0);
+ ASSERT (U_STRNCMP (input1, input2, 5) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 5) > 0);
+ ASSERT (U_STRNCMP (input1, input2, 6) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 6) > 0);
+ ASSERT (U_STRNCMP (input1, input2, 1000000) < 0);
+ ASSERT (U_STRNCMP (input2, input1, 1000000) > 0);
+ }
+}
diff --git a/tests/unistr/test-strncpy.h b/tests/unistr/test-strncpy.h
new file mode 100644
index 00000000..6fa0d12e
--- /dev/null
+++ b/tests/unistr/test-strncpy.h
@@ -0,0 +1,79 @@
+/* Test of uN_strncpy() functions.
+ Copyright (C) 2010 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 <http://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)
+{
+ UNIT *dest;
+ UNIT *result;
+ size_t i;
+
+ dest = (UNIT *) malloc ((1 + n + 1) * sizeof (UNIT));
+ ASSERT (dest != NULL);
+
+ for (i = 0; i < 1 + n + 1; i++)
+ dest[i] = MAGIC;
+
+ result = U_STRNCPY (dest + 1, input, n);
+ ASSERT (result == dest + 1);
+
+ ASSERT (dest[0] == MAGIC);
+ for (i = 0; i < (n <= length ? n : length + 1); i++)
+ ASSERT (dest[1 + i] == input[i]);
+ for (; i < n; i++)
+ ASSERT (dest[1 + i] == 0);
+ ASSERT (dest[1 + n] == 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_STRNCPY (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/tests/unistr/test-strnlen.h b/tests/unistr/test-strnlen.h
new file mode 100644
index 00000000..1199126c
--- /dev/null
+++ b/tests/unistr/test-strnlen.h
@@ -0,0 +1,60 @@
+/* Test of uN_strnlen() functions.
+ Copyright (C) 2010 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 <http://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)
+{
+ size_t result = U_STRNLEN (input, n);
+ ASSERT (result == (n <= length ? n : length));
+}
+
+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_STRNLEN (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/tests/unistr/test-u16-check.c b/tests/unistr/test-u16-check.c
new file mode 100644
index 00000000..b7a9c103
--- /dev/null
+++ b/tests/unistr/test-u16-check.c
@@ -0,0 +1,66 @@
+/* Test of u16_check() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* Test empty string. */
+ {
+ static const uint16_t input[] = { 0 };
+ ASSERT (u16_check (input, 0) == NULL);
+ }
+
+ /* Test valid non-empty string. */
+ {
+ static const uint16_t input[] = /* "Данило Шеган" */
+ { 0x0414, 0x0430, 0x043D, 0x0438, 0x043B, 0x043E, 0x0020, 0x0428, 0x0435, 0x0433, 0x0430, 0x043D };
+ ASSERT (u16_check (input, SIZEOF (input)) == NULL);
+ }
+
+ /* Test out-of-range character with 2 units: U+110000. */
+ {
+ static const uint16_t input[] = { 0x0414, 0x0430, 0xDBFF, 0xE000 };
+ ASSERT (u16_check (input, SIZEOF (input)) == input + 2);
+ }
+
+ /* Test surrogate codepoints. */
+ {
+ static const uint16_t input[] = { 0x0414, 0x0430, 0xDBFF, 0xDFFF };
+ ASSERT (u16_check (input, SIZEOF (input)) == NULL);
+ }
+ {
+ static const uint16_t input[] = { 0x0414, 0x0430, 0xDBFF };
+ ASSERT (u16_check (input, SIZEOF (input)) == input + 2);
+ }
+ {
+ static const uint16_t input[] = { 0x0414, 0x0430, 0xDFFF };
+ ASSERT (u16_check (input, SIZEOF (input)) == input + 2);
+ }
+ {
+ static const uint16_t input[] = { 0x0414, 0x0430, 0xDFFF, 0xDBFF };
+ ASSERT (u16_check (input, SIZEOF (input)) == input + 2);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-chr.c b/tests/unistr/test-u16-chr.c
new file mode 100644
index 00000000..d71755c1
--- /dev/null
+++ b/tests/unistr/test-u16-chr.c
@@ -0,0 +1,31 @@
+/* Test of u16_chr() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_CHR u16_chr
+#define U_SET u16_set
+#include "test-chr.h"
diff --git a/tests/unistr/test-u16-cmp.c b/tests/unistr/test-u16-cmp.c
new file mode 100644
index 00000000..1ab9019a
--- /dev/null
+++ b/tests/unistr/test-u16-cmp.c
@@ -0,0 +1,47 @@
+/* Test of u16_cmp() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_CMP u16_cmp
+#define MAGIC 0xBADE
+#include "test-cmp.h"
+
+int
+main ()
+{
+ test_cmp ();
+
+ /* Test comparison with non-BMP characters, split into surrogates. */
+ {
+ static const UNIT input1[] = { 0xD835, 0xDD1E };
+ static const UNIT input2[] = { 0xFEFF, 0xFFE5 };
+ ASSERT (U_CMP (input1, input2, 2) > 0);
+ ASSERT (U_CMP (input2, input1, 2) < 0);
+ ASSERT (U_CMP (input1, input2, 1) > 0);
+ ASSERT (U_CMP (input2, input1, 1) < 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-cmp2.c b/tests/unistr/test-u16-cmp2.c
new file mode 100644
index 00000000..3993dcdd
--- /dev/null
+++ b/tests/unistr/test-u16-cmp2.c
@@ -0,0 +1,28 @@
+/* Test of u16_cmp2() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_CMP2 u16_cmp2
+#define MAGIC 0xBADE
+#include "test-cmp2.h"
diff --git a/tests/unistr/test-u16-cpy-alloc.c b/tests/unistr/test-u16-cpy-alloc.c
new file mode 100644
index 00000000..d1aa2116
--- /dev/null
+++ b/tests/unistr/test-u16-cpy-alloc.c
@@ -0,0 +1,29 @@
+/* Test of u16_cpy_alloc() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_CPY_ALLOC u16_cpy_alloc
+#include "test-cpy-alloc.h"
diff --git a/tests/unistr/test-u16-cpy.c b/tests/unistr/test-u16-cpy.c
new file mode 100644
index 00000000..168a459a
--- /dev/null
+++ b/tests/unistr/test-u16-cpy.c
@@ -0,0 +1,28 @@
+/* Test of u16_cpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_CPY u16_cpy
+#define MAGIC 0xBADE
+#include "test-cpy.h"
diff --git a/tests/unistr/test-u16-mblen.c b/tests/unistr/test-u16-mblen.c
new file mode 100644
index 00000000..13186f3f
--- /dev/null
+++ b/tests/unistr/test-u16-mblen.c
@@ -0,0 +1,84 @@
+/* Test of u16_mblen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ int ret;
+
+ /* Test zero-length input. */
+ {
+ static const uint16_t input[] = { 0 };
+ ret = u16_mblen (input, 0);
+ ASSERT (ret == -1);
+ }
+
+ /* Test NUL unit input. */
+ {
+ static const uint16_t input[] = { 0 };
+ ret = u16_mblen (input, 1);
+ ASSERT (ret == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint16_t buf[1];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ ret = u16_mblen (buf, 1);
+ ASSERT (ret == 1);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint16_t input[] = { 0x20AC };
+ ret = u16_mblen (input, 1);
+ ASSERT (ret == 1);
+ }
+
+ /* Test 2-units character input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0xDD1F };
+ ret = u16_mblen (input, 2);
+ ASSERT (ret == 2);
+ }
+
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint16_t input[] = { 0xD835 };
+ ret = u16_mblen (input, 1);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint16_t input[] = { 0xDD1F };
+ ret = u16_mblen (input, 1);
+ ASSERT (ret == -1);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-mbsnlen.c b/tests/unistr/test-u16-mbsnlen.c
new file mode 100644
index 00000000..a2d8b10f
--- /dev/null
+++ b/tests/unistr/test-u16-mbsnlen.c
@@ -0,0 +1,68 @@
+/* Test of u16_mbsnlen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint16_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, '\n'
+ };
+ size_t n;
+
+ for (n = 0; n <= SIZEOF (input); n++)
+ {
+ size_t len = u16_mbsnlen (input, n);
+ ASSERT (len == n);
+ }
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint16_t input[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E
+ };
+ static const size_t expected[SIZEOF (input) + 1] =
+ { 0,
+ 1, 2, 3, 3, 4, 5, 5, 6, 7,
+ 8, 8, 9, 10, 10
+ };
+ size_t n;
+
+ for (n = 0; n <= SIZEOF (input); n++)
+ {
+ size_t len = u16_mbsnlen (input, n);
+ ASSERT (len == expected[n]);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-mbtouc-unsafe.c b/tests/unistr/test-u16-mbtouc-unsafe.c
new file mode 100644
index 00000000..a1d12149
--- /dev/null
+++ b/tests/unistr/test-u16-mbtouc-unsafe.c
@@ -0,0 +1,33 @@
+/* Test of u16_mbtouc_unsafe() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#include "test-u16-mbtouc.h"
+
+int
+main ()
+{
+ test_function (u16_mbtouc_unsafe);
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-mbtouc.c b/tests/unistr/test-u16-mbtouc.c
new file mode 100644
index 00000000..4545add7
--- /dev/null
+++ b/tests/unistr/test-u16-mbtouc.c
@@ -0,0 +1,33 @@
+/* Test of u16_mbtouc() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#include "test-u16-mbtouc.h"
+
+int
+main ()
+{
+ test_function (u16_mbtouc);
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-mbtouc.h b/tests/unistr/test-u16-mbtouc.h
new file mode 100644
index 00000000..ef0fb68a
--- /dev/null
+++ b/tests/unistr/test-u16-mbtouc.h
@@ -0,0 +1,82 @@
+/* Test of u16_mbtouc() and u16_mbtouc_unsafe() functions.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+static void
+test_function (int (*my_u16_mbtouc) (ucs4_t *, const uint16_t *, size_t))
+{
+ ucs4_t uc;
+ int ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint16_t input[] = { 0 };
+ uc = 0xBADFACE;
+ ret = my_u16_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint16_t buf[1];
+
+ for (c = 0; c < 0x80; c++)
+ {
+ buf[0] = c;
+ uc = 0xBADFACE;
+ ret = my_u16_mbtouc (&uc, buf, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint16_t input[] = { 0x20AC };
+ uc = 0xBADFACE;
+ ret = my_u16_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test 2-units character input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0xDD1F };
+ uc = 0xBADFACE;
+ ret = my_u16_mbtouc (&uc, input, 2);
+ ASSERT (ret == 2);
+ ASSERT (uc == 0x1D51F);
+ }
+
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint16_t input[] = { 0xD835 };
+ uc = 0xBADFACE;
+ ret = my_u16_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1 || ret == 2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint16_t input[] = { 0xDD1F };
+ uc = 0xBADFACE;
+ ret = my_u16_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0xFFFD);
+ }
+}
diff --git a/tests/unistr/test-u16-mbtoucr.c b/tests/unistr/test-u16-mbtoucr.c
new file mode 100644
index 00000000..fb1264d9
--- /dev/null
+++ b/tests/unistr/test-u16-mbtoucr.c
@@ -0,0 +1,90 @@
+/* Test of u16_mbtoucr() function.
+ Copyright (C) 2010 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 <http://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 uint16_t input[] = { 0 };
+ uc = 0xBADFACE;
+ ret = u16_mbtoucr (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint16_t buf[1];
+
+ for (c = 0; c < 0x80; c++)
+ {
+ buf[0] = c;
+ uc = 0xBADFACE;
+ ret = u16_mbtoucr (&uc, buf, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint16_t input[] = { 0x20AC };
+ uc = 0xBADFACE;
+ ret = u16_mbtoucr (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test 2-units character input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0xDD1F };
+ uc = 0xBADFACE;
+ ret = u16_mbtoucr (&uc, input, 2);
+ ASSERT (ret == 2);
+ ASSERT (uc == 0x1D51F);
+ }
+
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint16_t input[] = { 0xD835 };
+ uc = 0xBADFACE;
+ ret = u16_mbtoucr (&uc, input, 1);
+ ASSERT (ret == -2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint16_t input[] = { 0xDD1F };
+ uc = 0xBADFACE;
+ ret = u16_mbtoucr (&uc, input, 1);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-move.c b/tests/unistr/test-u16-move.c
new file mode 100644
index 00000000..ff1e6e35
--- /dev/null
+++ b/tests/unistr/test-u16-move.c
@@ -0,0 +1,28 @@
+/* Test of u16_move() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_MOVE u16_move
+#define MAGIC 0xBADE
+#include "test-move.h"
diff --git a/tests/unistr/test-u16-next.c b/tests/unistr/test-u16-next.c
new file mode 100644
index 00000000..d9ac6e93
--- /dev/null
+++ b/tests/unistr/test-u16-next.c
@@ -0,0 +1,91 @@
+/* Test of u16_next() function.
+ Copyright (C) 2010 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 <http://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;
+ const uint16_t *ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint16_t input[] = { 0 };
+ uc = 0xBADFACE;
+ ret = u16_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint16_t buf[2];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ buf[1] = 0;
+ uc = 0xBADFACE;
+ ret = u16_next (&uc, buf);
+ ASSERT (ret == buf + 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint16_t input[] = { 0x20AC, 0 };
+ uc = 0xBADFACE;
+ ret = u16_next (&uc, input);
+ ASSERT (ret == input + 1);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test 2-units character input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0xDD1F, 0 };
+ uc = 0xBADFACE;
+ ret = u16_next (&uc, input);
+ ASSERT (ret == input + 2);
+ ASSERT (uc == 0x1D51F);
+ }
+
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0 };
+ uc = 0xBADFACE;
+ ret = u16_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint16_t input[] = { 0xDD1F, 0 };
+ uc = 0xBADFACE;
+ ret = u16_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-prev.c b/tests/unistr/test-u16-prev.c
new file mode 100644
index 00000000..90e83418
--- /dev/null
+++ b/tests/unistr/test-u16-prev.c
@@ -0,0 +1,175 @@
+/* Test of u16_prev() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+static int
+check (const uint16_t *input, size_t input_length, ucs4_t *puc)
+{
+ ucs4_t uc;
+
+ /* Test recognition when at the beginning of the string. */
+ if (u16_prev (&uc, input + input_length, input) != input)
+ return 1;
+
+ /* Test recognition when preceded by a 1-unit character. */
+ {
+ uint16_t buf[100];
+ uint16_t *ptr;
+ size_t i;
+ ucs4_t uc1;
+
+ ptr = buf;
+ *ptr++ = 0x2102;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ if (u16_prev (&uc1, ptr + input_length, buf) != ptr)
+ return 2;
+ if (uc1 != uc)
+ return 3;
+ }
+
+ /* Test recognition when preceded by a 2-unit character. */
+ {
+ uint16_t buf[100];
+ uint16_t *ptr;
+ size_t i;
+ ucs4_t uc1;
+
+ ptr = buf;
+ *ptr++ = 0xD835;
+ *ptr++ = 0xDD1E;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ if (u16_prev (&uc1, ptr + input_length, buf) != ptr)
+ return 4;
+ if (uc1 != uc)
+ return 5;
+ }
+
+ *puc = uc;
+ return 0;
+}
+
+static int
+check_invalid (const uint16_t *input, size_t input_length)
+{
+ ucs4_t uc;
+
+ /* Test recognition when at the beginning of the string. */
+ uc = 0xBADFACE;
+ if (u16_prev (&uc, input + input_length, input) != NULL)
+ return 1;
+ if (uc != 0xBADFACE)
+ return 2;
+
+#if CONFIG_UNICODE_SAFETY
+ /* Test recognition when preceded by a 1-unit character. */
+ {
+ uint16_t buf[100];
+ uint16_t *ptr;
+ size_t i;
+
+ ptr = buf;
+ *ptr++ = 0x2102;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ uc = 0xBADFACE;
+ if (u16_prev (&uc, ptr + input_length, buf) != NULL)
+ return 3;
+ if (uc != 0xBADFACE)
+ return 4;
+ }
+
+ /* Test recognition when preceded by a 2-unit character. */
+ {
+ uint16_t buf[100];
+ uint16_t *ptr;
+ size_t i;
+
+ ptr = buf;
+ *ptr++ = 0xD835;
+ *ptr++ = 0xDD1E;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ uc = 0xBADFACE;
+ if (u16_prev (&uc, ptr + input_length, buf) != NULL)
+ return 5;
+ if (uc != 0xBADFACE)
+ return 6;
+ }
+#endif
+
+ return 0;
+}
+
+int
+main ()
+{
+ ucs4_t uc;
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint16_t buf[1];
+
+ for (c = 0; c < 0x80; c++)
+ {
+ buf[0] = c;
+ uc = 0xBADFACE;
+ ASSERT (check (buf, 1, &uc) == 0);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint16_t input[] = { 0x20AC };
+ uc = 0xBADFACE;
+ ASSERT (check (input, SIZEOF (input), &uc) == 0);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test 2-units character input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0xDD1F };
+ uc = 0xBADFACE;
+ ASSERT (check (input, SIZEOF (input), &uc) == 0);
+ ASSERT (uc == 0x1D51F);
+ }
+
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint16_t input[] = { 0xD835 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint16_t input[] = { 0xDD1F };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-set.c b/tests/unistr/test-u16-set.c
new file mode 100644
index 00000000..f3e63052
--- /dev/null
+++ b/tests/unistr/test-u16-set.c
@@ -0,0 +1,29 @@
+/* Test of u16_set() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_SET u16_set
+#define MAGIC 0xBADE
+#define VALUE 0x2102
+#include "test-set.h"
diff --git a/tests/unistr/test-u16-stpcpy.c b/tests/unistr/test-u16-stpcpy.c
new file mode 100644
index 00000000..6bf3ecb1
--- /dev/null
+++ b/tests/unistr/test-u16-stpcpy.c
@@ -0,0 +1,28 @@
+/* Test of u16_stpcpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_STPCPY u16_stpcpy
+#define MAGIC 0xBADE
+#include "test-stpcpy.h"
diff --git a/tests/unistr/test-u16-stpncpy.c b/tests/unistr/test-u16-stpncpy.c
new file mode 100644
index 00000000..e53ce6be
--- /dev/null
+++ b/tests/unistr/test-u16-stpncpy.c
@@ -0,0 +1,59 @@
+/* Test of u16_stpncpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_STPNCPY u16_stpncpy
+#define MAGIC 0xBADE
+#include "test-stpncpy.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint16_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
+ };
+ check (input, SIZEOF (input));
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint16_t input[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E, 0
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-strcat.c b/tests/unistr/test-u16-strcat.c
new file mode 100644
index 00000000..9d6032eb
--- /dev/null
+++ b/tests/unistr/test-u16-strcat.c
@@ -0,0 +1,28 @@
+/* Test of u16_strcat() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_STRCAT u16_strcat
+#define MAGIC 0xBADE
+#include "test-strcat.h"
diff --git a/tests/unistr/test-u16-strcmp.c b/tests/unistr/test-u16-strcmp.c
new file mode 100644
index 00000000..5fc47774
--- /dev/null
+++ b/tests/unistr/test-u16-strcmp.c
@@ -0,0 +1,34 @@
+/* Test of u16_strcmp() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define U_STRCMP u16_strcmp
+#include "test-u16-strcmp.h"
+
+int
+main ()
+{
+ test_u16_strcmp ();
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-strcmp.h b/tests/unistr/test-u16-strcmp.h
new file mode 100644
index 00000000..ad54a437
--- /dev/null
+++ b/tests/unistr/test-u16-strcmp.h
@@ -0,0 +1,42 @@
+/* Test of u16_strcmp() and u16_strcoll() functions.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#define UNIT uint16_t
+#include "test-strcmp.h"
+
+static void
+test_u16_strcmp (void)
+{
+ test_strcmp ();
+
+ /* Test comparison between ASCII and non-ASCII characters. */
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 0x2022, 0 };
+ ASSERT (U_STRCMP (input1, input2) < 0);
+ ASSERT (U_STRCMP (input2, input1) > 0);
+ }
+
+ /* Test comparison with non-BMP characters, split into surrogates. */
+ {
+ static const UNIT input1[] = { 0xD835, 0xDD1E, 0 };
+ static const UNIT input2[] = { 0xFEFF, 0 };
+ ASSERT (U_STRCMP (input1, input2) > 0);
+ ASSERT (U_STRCMP (input2, input1) < 0);
+ }
+}
diff --git a/tests/unistr/test-u16-strcoll.c b/tests/unistr/test-u16-strcoll.c
new file mode 100644
index 00000000..e24814a1
--- /dev/null
+++ b/tests/unistr/test-u16-strcoll.c
@@ -0,0 +1,41 @@
+/* Test of u16_strcoll() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define U_STRCMP u16_strcoll
+#include "test-u16-strcmp.h"
+
+int
+main ()
+{
+ /* This test relies on three facts:
+ - setlocale is not being called, therefore the locale is the "C" locale.
+ - In the "C" locale, strcoll is equivalent to strcmp.
+ - In the u16_strcoll implementation, Unicode strings that are not
+ convertible to the locale encoding are sorted higher than convertible
+ strings and compared according to u16_strcmp. */
+
+ test_u16_strcmp ();
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-strcpy.c b/tests/unistr/test-u16-strcpy.c
new file mode 100644
index 00000000..e017a112
--- /dev/null
+++ b/tests/unistr/test-u16-strcpy.c
@@ -0,0 +1,28 @@
+/* Test of u16_strcpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_STRCPY u16_strcpy
+#define MAGIC 0xBADE
+#include "test-strcpy.h"
diff --git a/tests/unistr/test-u16-strdup.c b/tests/unistr/test-u16-strdup.c
new file mode 100644
index 00000000..f0266d1b
--- /dev/null
+++ b/tests/unistr/test-u16-strdup.c
@@ -0,0 +1,27 @@
+/* Test of u16_strdup() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_STRDUP u16_strdup
+#include "test-strdup.h"
diff --git a/tests/unistr/test-u16-strlen.c b/tests/unistr/test-u16-strlen.c
new file mode 100644
index 00000000..7b8690be
--- /dev/null
+++ b/tests/unistr/test-u16-strlen.c
@@ -0,0 +1,57 @@
+/* Test of u16_strlen() function.
+ Copyright (C) 2010 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 <http://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 uint16_t input[] = { 0 };
+ ASSERT (u16_strlen (input) == 0);
+ }
+
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint16_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 (u16_strlen (input) == SIZEOF (input) - 1);
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint16_t input[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E, 0
+ };
+ ASSERT (u16_strlen (input) == SIZEOF (input) - 1);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-strmblen.c b/tests/unistr/test-u16-strmblen.c
new file mode 100644
index 00000000..80371b0a
--- /dev/null
+++ b/tests/unistr/test-u16-strmblen.c
@@ -0,0 +1,78 @@
+/* Test of u16_strmblen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ int ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint16_t input[] = { 0 };
+ ret = u16_strmblen (input);
+ ASSERT (ret == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint16_t buf[2];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ buf[1] = 0;
+ ret = u16_strmblen (buf);
+ ASSERT (ret == 1);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint16_t input[] = { 0x20AC, 0 };
+ ret = u16_strmblen (input);
+ ASSERT (ret == 1);
+ }
+
+ /* Test 2-units character input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0xDD1F, 0 };
+ ret = u16_strmblen (input);
+ ASSERT (ret == 2);
+ }
+
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0 };
+ ret = u16_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint16_t input[] = { 0xDD1F, 0 };
+ ret = u16_strmblen (input);
+ ASSERT (ret == -1);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-strmbtouc.c b/tests/unistr/test-u16-strmbtouc.c
new file mode 100644
index 00000000..ceeaf2cd
--- /dev/null
+++ b/tests/unistr/test-u16-strmbtouc.c
@@ -0,0 +1,91 @@
+/* Test of u16_strmbtouc() function.
+ Copyright (C) 2010 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 <http://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 uint16_t input[] = { 0 };
+ uc = 0xBADFACE;
+ ret = u16_strmbtouc (&uc, input);
+ ASSERT (ret == 0);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint16_t buf[2];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ buf[1] = 0;
+ uc = 0xBADFACE;
+ ret = u16_strmbtouc (&uc, buf);
+ ASSERT (ret == 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint16_t input[] = { 0x20AC, 0 };
+ uc = 0xBADFACE;
+ ret = u16_strmbtouc (&uc, input);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test 2-units character input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0xDD1F, 0 };
+ uc = 0xBADFACE;
+ ret = u16_strmbtouc (&uc, input);
+ ASSERT (ret == 2);
+ ASSERT (uc == 0x1D51F);
+ }
+
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint16_t input[] = { 0xD835, 0 };
+ uc = 0xBADFACE;
+ ret = u16_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint16_t input[] = { 0xDD1F, 0 };
+ uc = 0xBADFACE;
+ ret = u16_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-strncat.c b/tests/unistr/test-u16-strncat.c
new file mode 100644
index 00000000..c875cfc8
--- /dev/null
+++ b/tests/unistr/test-u16-strncat.c
@@ -0,0 +1,59 @@
+/* Test of u16_strncat() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_STRNCAT u16_strncat
+#define MAGIC 0xBADE
+#include "test-strncat.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint16_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
+ };
+ check (input, SIZEOF (input));
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint16_t input[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E, 0
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-strncmp.c b/tests/unistr/test-u16-strncmp.c
new file mode 100644
index 00000000..b04431bd
--- /dev/null
+++ b/tests/unistr/test-u16-strncmp.c
@@ -0,0 +1,47 @@
+/* Test of u16_strncmp() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_STRNCMP u16_strncmp
+#include "test-strncmp.h"
+
+int
+main ()
+{
+ test_strncmp ();
+
+ /* Test comparison with non-BMP characters, split into surrogates. */
+ {
+ static const UNIT input1[] = { 0xD835, 0xDD1E, 0 };
+ static const UNIT input2[] = { 0xFEFF, 0 };
+ ASSERT (U_STRNCMP (input1, input2, 1) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 1) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 2) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 2) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 1000000) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 1000000) < 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-strncpy.c b/tests/unistr/test-u16-strncpy.c
new file mode 100644
index 00000000..102f6534
--- /dev/null
+++ b/tests/unistr/test-u16-strncpy.c
@@ -0,0 +1,59 @@
+/* Test of u16_strncpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_STRNCPY u16_strncpy
+#define MAGIC 0xBADE
+#include "test-strncpy.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint16_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
+ };
+ check (input, SIZEOF (input));
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint16_t input[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E, 0
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-strnlen.c b/tests/unistr/test-u16-strnlen.c
new file mode 100644
index 00000000..beeba64b
--- /dev/null
+++ b/tests/unistr/test-u16-strnlen.c
@@ -0,0 +1,56 @@
+/* Test of u16_strnlen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint16_t
+#define U_STRNLEN u16_strnlen
+#include "test-strnlen.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint16_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
+ };
+ check (input, SIZEOF (input));
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint16_t input[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E, 0
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-to-u32.c b/tests/unistr/test-u16-to-u32.c
new file mode 100644
index 00000000..5b382b2f
--- /dev/null
+++ b/tests/unistr/test-u16-to-u32.c
@@ -0,0 +1,156 @@
+/* Test of u16_to_u32() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <errno.h>
+
+#include "macros.h"
+
+static int
+check (const uint16_t *input, size_t input_length,
+ const uint32_t *expected, size_t expected_length)
+{
+ size_t length;
+ uint32_t *result;
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u16_to_u32 (input, input_length, NULL, &length);
+ if (!(result != NULL))
+ return 1;
+ if (!(length == expected_length))
+ return 2;
+ if (!(u32_cmp (result, expected, expected_length) == 0))
+ return 3;
+ free (result);
+
+ /* Test return conventions with resultbuf too small. */
+ if (expected_length > 0)
+ {
+ uint32_t *preallocated;
+
+ length = expected_length - 1;
+ preallocated = (uint32_t *) malloc (length * sizeof (uint32_t));
+ result = u16_to_u32 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 4;
+ if (!(result != preallocated))
+ return 5;
+ if (!(length == expected_length))
+ return 6;
+ if (!(u32_cmp (result, expected, expected_length) == 0))
+ return 7;
+ free (result);
+ free (preallocated);
+ }
+
+ /* Test return conventions with resultbuf large enough. */
+ {
+ uint32_t *preallocated;
+
+ length = expected_length;
+ preallocated = (uint32_t *) malloc (length * sizeof (uint32_t));
+ result = u16_to_u32 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 8;
+ if (!(preallocated == NULL || result == preallocated))
+ return 9;
+ if (!(length == expected_length))
+ return 10;
+ if (!(u32_cmp (result, expected, expected_length) == 0))
+ return 11;
+ free (preallocated);
+ }
+
+ return 0;
+}
+
+int
+main ()
+{
+ /* Empty string. */
+ ASSERT (check (NULL, 0, NULL, 0) == 0);
+
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint16_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, '\n'
+ };
+ static const uint32_t expected[] =
+ { '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, '\n'
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint16_t input[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E
+ };
+ static const uint32_t expected[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* Invalid input. */
+ {
+ static const uint16_t input[] = { 'x', 0xDD1E, 0xD835, 'y' };
+#if 0 /* Currently invalid input is rejected, not accommodated. */
+ static const uint32_t expected[] = { 'x', 0xFFFD, 0xFFFD, 'y' };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+#else
+ size_t length;
+ uint32_t *result;
+ uint32_t preallocated[10];
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u16_to_u32 (input, SIZEOF (input), NULL, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf too small. */
+ length = 1;
+ result = u16_to_u32 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf large enough. */
+ length = SIZEOF (preallocated);
+ result = u16_to_u32 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+#endif
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-to-u8.c b/tests/unistr/test-u16-to-u8.c
new file mode 100644
index 00000000..4ef9b9b6
--- /dev/null
+++ b/tests/unistr/test-u16-to-u8.c
@@ -0,0 +1,159 @@
+/* Test of u16_to_u8() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <errno.h>
+
+#include "macros.h"
+
+static int
+check (const uint16_t *input, size_t input_length,
+ const uint8_t *expected, size_t expected_length)
+{
+ size_t length;
+ uint8_t *result;
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u16_to_u8 (input, input_length, NULL, &length);
+ if (!(result != NULL))
+ return 1;
+ if (!(length == expected_length))
+ return 2;
+ if (!(u8_cmp (result, expected, expected_length) == 0))
+ return 3;
+ free (result);
+
+ /* Test return conventions with resultbuf too small. */
+ if (expected_length > 0)
+ {
+ uint8_t *preallocated;
+
+ length = expected_length - 1;
+ preallocated = (uint8_t *) malloc (length * sizeof (uint8_t));
+ result = u16_to_u8 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 4;
+ if (!(result != preallocated))
+ return 5;
+ if (!(length == expected_length))
+ return 6;
+ if (!(u8_cmp (result, expected, expected_length) == 0))
+ return 7;
+ free (result);
+ free (preallocated);
+ }
+
+ /* Test return conventions with resultbuf large enough. */
+ {
+ uint8_t *preallocated;
+
+ length = expected_length;
+ preallocated = (uint8_t *) malloc (length * sizeof (uint8_t));
+ result = u16_to_u8 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 8;
+ if (!(preallocated == NULL || result == preallocated))
+ return 9;
+ if (!(length == expected_length))
+ return 10;
+ if (!(u8_cmp (result, expected, expected_length) == 0))
+ return 11;
+ free (preallocated);
+ }
+
+ return 0;
+}
+
+int
+main ()
+{
+ /* Empty string. */
+ ASSERT (check (NULL, 0, NULL, 0) == 0);
+
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint16_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, '\n'
+ };
+ static const uint8_t expected[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\n'
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint16_t input[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E
+ };
+ static const uint8_t expected[] =
+ { '-', '(', 0xF0, 0x9D, 0x94, 0x9E, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9F,
+ ')', '=', 0xF0, 0x9D, 0x94, 0x9F, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9E
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* Invalid input. */
+ {
+ static const uint16_t input[] = { 'x', 0xDD1E, 0xD835, 'y' };
+#if 0 /* Currently invalid input is rejected, not accommodated. */
+ static const uint8_t expected[] =
+ { 'x', 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 'y' };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+#else
+ size_t length;
+ uint8_t *result;
+ uint8_t preallocated[10];
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u16_to_u8 (input, SIZEOF (input), NULL, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf too small. */
+ length = 1;
+ result = u16_to_u8 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf large enough. */
+ length = SIZEOF (preallocated);
+ result = u16_to_u8 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+#endif
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u16-uctomb.c b/tests/unistr/test-u16-uctomb.c
new file mode 100644
index 00000000..ba502254
--- /dev/null
+++ b/tests/unistr/test-u16-uctomb.c
@@ -0,0 +1,110 @@
+/* Test of u16_uctomb() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define MAGIC 0xBADE
+
+int
+main ()
+{
+ /* Test ISO 646 character, in particular the NUL character. */
+ {
+ ucs4_t uc;
+
+ for (uc = 0; uc < 0x80; uc++)
+ {
+ uint16_t buf[3] = { MAGIC, MAGIC, MAGIC };
+ int ret;
+
+ ret = u16_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u16_uctomb (buf, uc, 1);
+ ASSERT (ret == 1);
+ ASSERT (buf[0] == uc);
+ ASSERT (buf[1] == MAGIC);
+ }
+ }
+
+ /* Test BMP character. */
+ {
+ ucs4_t uc = 0x20AC;
+ uint16_t buf[3] = { MAGIC, MAGIC, MAGIC };
+ int ret;
+
+ ret = u16_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u16_uctomb (buf, uc, 1);
+ ASSERT (ret == 1);
+ ASSERT (buf[0] == uc);
+ ASSERT (buf[1] == MAGIC);
+ }
+
+ /* Test non-BMP character. */
+ {
+ ucs4_t uc = 0x10FFFD;
+ uint16_t buf[3] = { MAGIC, MAGIC, MAGIC };
+ int ret;
+
+ ret = u16_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u16_uctomb (buf, uc, 1);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u16_uctomb (buf, uc, 2);
+ ASSERT (ret == 2);
+ ASSERT (buf[0] == 0xDBFF);
+ ASSERT (buf[1] == 0xDFFD);
+ ASSERT (buf[2] == MAGIC);
+ }
+
+ /* Test invalid characters. */
+ {
+ ucs4_t invalid[] = { 0x110000, 0xD800, 0xDBFF, 0xDC00, 0xDFFF };
+ uint16_t buf[3] = { MAGIC, MAGIC, MAGIC };
+ size_t i;
+
+ for (i = 0; i < SIZEOF (invalid); i++)
+ {
+ ucs4_t uc = invalid[i];
+ int n;
+
+ for (n = 0; n <= 2; n++)
+ {
+ int ret = u16_uctomb (buf, uc, n);
+ ASSERT (ret == -1);
+ ASSERT (buf[0] == MAGIC);
+ ASSERT (buf[1] == MAGIC);
+ ASSERT (buf[2] == MAGIC);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-check.c b/tests/unistr/test-u32-check.c
new file mode 100644
index 00000000..fdd64df6
--- /dev/null
+++ b/tests/unistr/test-u32-check.c
@@ -0,0 +1,66 @@
+/* Test of u32_check() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* Test empty string. */
+ {
+ static const uint32_t input[] = { 0 };
+ ASSERT (u32_check (input, 0) == NULL);
+ }
+
+ /* Test valid non-empty string. */
+ {
+ static const uint32_t input[] = /* "Данило Шеган" */
+ { 0x0414, 0x0430, 0x043D, 0x0438, 0x043B, 0x043E, 0x0020, 0x0428, 0x0435, 0x0433, 0x0430, 0x043D };
+ ASSERT (u32_check (input, SIZEOF (input)) == NULL);
+ }
+
+ /* Test out-of-range character with 1 unit: U+110000. */
+ {
+ static const uint32_t input[] = { 0x0414, 0x0430, 0x110000 };
+ ASSERT (u32_check (input, SIZEOF (input)) == input + 2);
+ }
+
+ /* Test surrogate codepoints. */
+ {
+ static const uint32_t input[] = { 0x0414, 0x0430, 0xDBFF, 0xDFFF };
+ ASSERT (u32_check (input, SIZEOF (input)) == input + 2);
+ }
+ {
+ static const uint32_t input[] = { 0x0414, 0x0430, 0xDBFF };
+ ASSERT (u32_check (input, SIZEOF (input)) == input + 2);
+ }
+ {
+ static const uint32_t input[] = { 0x0414, 0x0430, 0xDFFF };
+ ASSERT (u32_check (input, SIZEOF (input)) == input + 2);
+ }
+ {
+ static const uint32_t input[] = { 0x0414, 0x0430, 0xDFFF, 0xDBFF };
+ ASSERT (u32_check (input, SIZEOF (input)) == input + 2);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-chr.c b/tests/unistr/test-u32-chr.c
new file mode 100644
index 00000000..f23aa084
--- /dev/null
+++ b/tests/unistr/test-u32-chr.c
@@ -0,0 +1,31 @@
+/* Test of u32_chr() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_CHR u32_chr
+#define U_SET u32_set
+#include "test-chr.h"
diff --git a/tests/unistr/test-u32-cmp.c b/tests/unistr/test-u32-cmp.c
new file mode 100644
index 00000000..ab41b31f
--- /dev/null
+++ b/tests/unistr/test-u32-cmp.c
@@ -0,0 +1,45 @@
+/* Test of u32_cmp() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_CMP u32_cmp
+#define MAGIC 0xBADFACE
+#include "test-cmp.h"
+
+int
+main ()
+{
+ test_cmp ();
+
+ /* Test comparison with non-BMP characters. */
+ {
+ static const UNIT input1[] = { 0x1D51F };
+ static const UNIT input2[] = { 0xFEFF };
+ ASSERT (U_CMP (input1, input2, 1) > 0);
+ ASSERT (U_CMP (input2, input1, 1) < 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-cmp2.c b/tests/unistr/test-u32-cmp2.c
new file mode 100644
index 00000000..84450b56
--- /dev/null
+++ b/tests/unistr/test-u32-cmp2.c
@@ -0,0 +1,28 @@
+/* Test of u32_cmp2() function.
+ Copyright (C) 2010 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 <http://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_CMP2 u32_cmp2
+#define MAGIC 0xBADFACE
+#include "test-cmp2.h"
diff --git a/tests/unistr/test-u32-cpy-alloc.c b/tests/unistr/test-u32-cpy-alloc.c
new file mode 100644
index 00000000..d3675dd7
--- /dev/null
+++ b/tests/unistr/test-u32-cpy-alloc.c
@@ -0,0 +1,29 @@
+/* Test of u32_cpy_alloc() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_CPY_ALLOC u32_cpy_alloc
+#include "test-cpy-alloc.h"
diff --git a/tests/unistr/test-u32-cpy.c b/tests/unistr/test-u32-cpy.c
new file mode 100644
index 00000000..49fc9951
--- /dev/null
+++ b/tests/unistr/test-u32-cpy.c
@@ -0,0 +1,28 @@
+/* Test of u32_cpy() function.
+ Copyright (C) 2010 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 <http://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/tests/unistr/test-u32-mblen.c b/tests/unistr/test-u32-mblen.c
new file mode 100644
index 00000000..1ebd93eb
--- /dev/null
+++ b/tests/unistr/test-u32-mblen.c
@@ -0,0 +1,81 @@
+/* Test of u32_mblen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ int ret;
+
+ /* Test zero-length input. */
+ {
+ static const uint32_t input[] = { 0 };
+ ret = u32_mblen (input, 0);
+ ASSERT (ret == -1);
+ }
+
+ /* Test NUL unit input. */
+ {
+ static const uint32_t input[] = { 0 };
+ ret = u32_mblen (input, 1);
+ ASSERT (ret == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint32_t buf[1];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ ret = u32_mblen (buf, 1);
+ ASSERT (ret == 1);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x20AC };
+ ret = u32_mblen (input, 1);
+ ASSERT (ret == 1);
+ }
+
+ /* Test non-BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x1D51F };
+ ret = u32_mblen (input, 1);
+ ASSERT (ret == 1);
+ }
+
+#if CONFIG_UNICODE_SAFETY
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint32_t input[] = { 0x340000 };
+ ret = u32_mblen (input, 1);
+ ASSERT (ret == -1);
+ }
+#endif
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-mbsnlen.c b/tests/unistr/test-u32-mbsnlen.c
new file mode 100644
index 00000000..d9e066ba
--- /dev/null
+++ b/tests/unistr/test-u32-mbsnlen.c
@@ -0,0 +1,63 @@
+/* Test of u32_mbsnlen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+
+ /* 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, '\n'
+ };
+ size_t n;
+
+ for (n = 0; n <= SIZEOF (input); n++)
+ {
+ size_t len = u32_mbsnlen (input, n);
+ ASSERT (len == n);
+ }
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint32_t input[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E
+ };
+ size_t n;
+
+ for (n = 0; n <= SIZEOF (input); n++)
+ {
+ size_t len = u32_mbsnlen (input, n);
+ ASSERT (len == n);
+ }
+ }
+ return 0;
+}
diff --git a/tests/unistr/test-u32-mbtouc-unsafe.c b/tests/unistr/test-u32-mbtouc-unsafe.c
new file mode 100644
index 00000000..cb3052cb
--- /dev/null
+++ b/tests/unistr/test-u32-mbtouc-unsafe.c
@@ -0,0 +1,33 @@
+/* Test of u32_mbtouc_unsafe() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#include "test-u32-mbtouc.h"
+
+int
+main ()
+{
+ test_function (u32_mbtouc_unsafe);
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-mbtouc.c b/tests/unistr/test-u32-mbtouc.c
new file mode 100644
index 00000000..7c981b5c
--- /dev/null
+++ b/tests/unistr/test-u32-mbtouc.c
@@ -0,0 +1,36 @@
+/* Test of u32_mbtouc() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+/* Enable all tests that may be skipped when testing u32_mbtouc_unsafe. */
+#define FULL_SAFETY 1
+
+#include "test-u32-mbtouc.h"
+
+int
+main ()
+{
+ test_function (u32_mbtouc);
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-mbtouc.h b/tests/unistr/test-u32-mbtouc.h
new file mode 100644
index 00000000..7d701334
--- /dev/null
+++ b/tests/unistr/test-u32-mbtouc.h
@@ -0,0 +1,77 @@
+/* Test of u32_mbtouc() and u32_mbtouc_unsafe() functions.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+static void
+test_function (int (*my_u32_mbtouc) (ucs4_t *, const uint32_t *, size_t))
+{
+ ucs4_t uc;
+ int ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint32_t input[] = { 0 };
+ uc = 0xBADFACE;
+ ret = my_u32_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint32_t buf[1];
+
+ for (c = 0; c < 0x80; c++)
+ {
+ buf[0] = c;
+ uc = 0xBADFACE;
+ ret = my_u32_mbtouc (&uc, buf, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x20AC };
+ uc = 0xBADFACE;
+ ret = my_u32_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test non-BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x1D51F };
+ uc = 0xBADFACE;
+ ret = my_u32_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0x1D51F);
+ }
+
+#if FULL_SAFETY || CONFIG_UNICODE_SAFETY
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint32_t input[] = { 0x340000 };
+ uc = 0xBADFACE;
+ ret = my_u32_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0xFFFD);
+ }
+#endif
+}
diff --git a/tests/unistr/test-u32-mbtoucr.c b/tests/unistr/test-u32-mbtoucr.c
new file mode 100644
index 00000000..7b1034c5
--- /dev/null
+++ b/tests/unistr/test-u32-mbtoucr.c
@@ -0,0 +1,83 @@
+/* Test of u32_mbtoucr() function.
+ Copyright (C) 2010 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 <http://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 uint32_t input[] = { 0 };
+ uc = 0xBADFACE;
+ ret = u32_mbtoucr (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint32_t buf[1];
+
+ for (c = 0; c < 0x80; c++)
+ {
+ buf[0] = c;
+ uc = 0xBADFACE;
+ ret = u32_mbtoucr (&uc, buf, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x20AC };
+ uc = 0xBADFACE;
+ ret = u32_mbtoucr (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test non-BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x1D51F };
+ uc = 0xBADFACE;
+ ret = u32_mbtoucr (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0x1D51F);
+ }
+
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint32_t input[] = { 0x340000 };
+ uc = 0xBADFACE;
+ ret = u32_mbtoucr (&uc, input, 1);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-move.c b/tests/unistr/test-u32-move.c
new file mode 100644
index 00000000..44f95c00
--- /dev/null
+++ b/tests/unistr/test-u32-move.c
@@ -0,0 +1,28 @@
+/* Test of u32_move() function.
+ Copyright (C) 2010 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 <http://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_MOVE u32_move
+#define MAGIC 0xBADFACE
+#include "test-move.h"
diff --git a/tests/unistr/test-u32-next.c b/tests/unistr/test-u32-next.c
new file mode 100644
index 00000000..a5852e2c
--- /dev/null
+++ b/tests/unistr/test-u32-next.c
@@ -0,0 +1,86 @@
+/* Test of u32_next() function.
+ Copyright (C) 2010 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 <http://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;
+ const uint32_t *ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint32_t input[] = { 0 };
+ uc = 0xBADFACE;
+ ret = u32_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint32_t buf[2];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ buf[1] = 0;
+ uc = 0xBADFACE;
+ ret = u32_next (&uc, buf);
+ ASSERT (ret == buf + 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x20AC, 0 };
+ uc = 0xBADFACE;
+ ret = u32_next (&uc, input);
+ ASSERT (ret == input + 1);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test non-BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x1D51F, 0 };
+ uc = 0xBADFACE;
+ ret = u32_next (&uc, input);
+ ASSERT (ret == input + 1);
+ ASSERT (uc == 0x1D51F);
+ }
+
+#if CONFIG_UNICODE_SAFETY
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint32_t input[] = { 0x340000, 0 };
+ uc = 0xBADFACE;
+ ret = u32_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+#endif
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-prev.c b/tests/unistr/test-u32-prev.c
new file mode 100644
index 00000000..95187afa
--- /dev/null
+++ b/tests/unistr/test-u32-prev.c
@@ -0,0 +1,133 @@
+/* Test of u32_prev() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+static int
+check (const uint32_t *input, size_t input_length, ucs4_t *puc)
+{
+ ucs4_t uc;
+
+ /* Test recognition when at the beginning of the string. */
+ if (u32_prev (&uc, input + input_length, input) != input)
+ return 1;
+
+ /* Test recognition when preceded by a 1-unit character. */
+ {
+ uint32_t buf[100];
+ uint32_t *ptr;
+ size_t i;
+ ucs4_t uc1;
+
+ ptr = buf;
+ *ptr++ = 0x1D51E;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ if (u32_prev (&uc1, ptr + input_length, buf) != ptr)
+ return 2;
+ if (uc1 != uc)
+ return 3;
+ }
+
+ *puc = uc;
+ return 0;
+}
+
+static int
+check_invalid (const uint32_t *input, size_t input_length)
+{
+#if CONFIG_UNICODE_SAFETY
+ ucs4_t uc;
+
+ /* Test recognition when at the beginning of the string. */
+ uc = 0xBADFACE;
+ if (u32_prev (&uc, input + input_length, input) != NULL)
+ return 1;
+ if (uc != 0xBADFACE)
+ return 2;
+
+ /* Test recognition when preceded by a 1-unit character. */
+ {
+ uint32_t buf[100];
+ uint32_t *ptr;
+ size_t i;
+
+ ptr = buf;
+ *ptr++ = 0x1D51E;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ uc = 0xBADFACE;
+ if (u32_prev (&uc, ptr + input_length, buf) != NULL)
+ return 3;
+ if (uc != 0xBADFACE)
+ return 4;
+ }
+#endif
+
+ return 0;
+}
+
+int
+main ()
+{
+ ucs4_t uc;
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint32_t buf[1];
+
+ for (c = 0; c < 0x80; c++)
+ {
+ buf[0] = c;
+ uc = 0xBADFACE;
+ ASSERT (check (buf, 1, &uc) == 0);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x20AC };
+ uc = 0xBADFACE;
+ ASSERT (check (input, SIZEOF (input), &uc) == 0);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test non-BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x1D51F };
+ uc = 0xBADFACE;
+ ASSERT (check (input, SIZEOF (input), &uc) == 0);
+ ASSERT (uc == 0x1D51F);
+ }
+
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint32_t input[] = { 0x340000 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-set.c b/tests/unistr/test-u32-set.c
new file mode 100644
index 00000000..120804f1
--- /dev/null
+++ b/tests/unistr/test-u32-set.c
@@ -0,0 +1,29 @@
+/* Test of u32_set() function.
+ Copyright (C) 2010 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 <http://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/tests/unistr/test-u32-stpcpy.c b/tests/unistr/test-u32-stpcpy.c
new file mode 100644
index 00000000..9c99c52a
--- /dev/null
+++ b/tests/unistr/test-u32-stpcpy.c
@@ -0,0 +1,28 @@
+/* Test of u32_stpcpy() function.
+ Copyright (C) 2010 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 <http://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_STPCPY u32_stpcpy
+#define MAGIC 0xBADFACE
+#include "test-stpcpy.h"
diff --git a/tests/unistr/test-u32-stpncpy.c b/tests/unistr/test-u32-stpncpy.c
new file mode 100644
index 00000000..e29683bd
--- /dev/null
+++ b/tests/unistr/test-u32-stpncpy.c
@@ -0,0 +1,59 @@
+/* Test of u32_stpncpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_STPNCPY u32_stpncpy
+#define MAGIC 0xBADFACE
+#include "test-stpncpy.h"
+
+int
+main ()
+{
+ /* 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
+ };
+ check (input, SIZEOF (input));
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint32_t input[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E, 0
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-strcat.c b/tests/unistr/test-u32-strcat.c
new file mode 100644
index 00000000..66e7c853
--- /dev/null
+++ b/tests/unistr/test-u32-strcat.c
@@ -0,0 +1,28 @@
+/* Test of u32_strcat() function.
+ Copyright (C) 2010 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 <http://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/tests/unistr/test-u32-strcmp.c b/tests/unistr/test-u32-strcmp.c
new file mode 100644
index 00000000..8364a415
--- /dev/null
+++ b/tests/unistr/test-u32-strcmp.c
@@ -0,0 +1,34 @@
+/* Test of u32_strcmp() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define U_STRCMP u32_strcmp
+#include "test-u32-strcmp.h"
+
+int
+main ()
+{
+ test_u32_strcmp ();
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-strcmp.h b/tests/unistr/test-u32-strcmp.h
new file mode 100644
index 00000000..6d24132e
--- /dev/null
+++ b/tests/unistr/test-u32-strcmp.h
@@ -0,0 +1,42 @@
+/* Test of u32_strcmp() and u32_strcoll() functions.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#define UNIT uint32_t
+#include "test-strcmp.h"
+
+static void
+test_u32_strcmp (void)
+{
+ test_strcmp ();
+
+ /* Test comparison between ASCII and non-ASCII characters. */
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 0x2022, 0 };
+ ASSERT (U_STRCMP (input1, input2) < 0);
+ ASSERT (U_STRCMP (input2, input1) > 0);
+ }
+
+ /* Test comparison with non-BMP characters. */
+ {
+ static const UNIT input1[] = { 0x1D51F, 0 };
+ static const UNIT input2[] = { 0xFEFF, 0 };
+ ASSERT (U_STRCMP (input1, input2) > 0);
+ ASSERT (U_STRCMP (input2, input1) < 0);
+ }
+}
diff --git a/tests/unistr/test-u32-strcoll.c b/tests/unistr/test-u32-strcoll.c
new file mode 100644
index 00000000..36954e73
--- /dev/null
+++ b/tests/unistr/test-u32-strcoll.c
@@ -0,0 +1,41 @@
+/* Test of u32_strcoll() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define U_STRCMP u32_strcoll
+#include "test-u32-strcmp.h"
+
+int
+main ()
+{
+ /* This test relies on three facts:
+ - setlocale is not being called, therefore the locale is the "C" locale.
+ - In the "C" locale, strcoll is equivalent to strcmp.
+ - In the u32_strcoll implementation, Unicode strings that are not
+ convertible to the locale encoding are sorted higher than convertible
+ strings and compared according to u32_strcmp. */
+
+ test_u32_strcmp ();
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-strcpy.c b/tests/unistr/test-u32-strcpy.c
new file mode 100644
index 00000000..2e22aad4
--- /dev/null
+++ b/tests/unistr/test-u32-strcpy.c
@@ -0,0 +1,28 @@
+/* Test of u32_strcpy() function.
+ Copyright (C) 2010 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 <http://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_STRCPY u32_strcpy
+#define MAGIC 0xBADFACE
+#include "test-strcpy.h"
diff --git a/tests/unistr/test-u32-strdup.c b/tests/unistr/test-u32-strdup.c
new file mode 100644
index 00000000..ede8e544
--- /dev/null
+++ b/tests/unistr/test-u32-strdup.c
@@ -0,0 +1,27 @@
+/* Test of u32_strdup() function.
+ Copyright (C) 2010 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 <http://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_STRDUP u32_strdup
+#include "test-strdup.h"
diff --git a/tests/unistr/test-u32-strlen.c b/tests/unistr/test-u32-strlen.c
new file mode 100644
index 00000000..a349be75
--- /dev/null
+++ b/tests/unistr/test-u32-strlen.c
@@ -0,0 +1,57 @@
+/* Test of u32_strlen() function.
+ Copyright (C) 2010 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 <http://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/tests/unistr/test-u32-strmblen.c b/tests/unistr/test-u32-strmblen.c
new file mode 100644
index 00000000..733f8fc8
--- /dev/null
+++ b/tests/unistr/test-u32-strmblen.c
@@ -0,0 +1,75 @@
+/* Test of u32_strmblen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ int ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint32_t input[] = { 0 };
+ ret = u32_strmblen (input);
+ ASSERT (ret == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint32_t buf[2];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ buf[1] = 0;
+ ret = u32_strmblen (buf);
+ ASSERT (ret == 1);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x20AC, 0 };
+ ret = u32_strmblen (input);
+ ASSERT (ret == 1);
+ }
+
+ /* Test non-BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x1D51F, 0 };
+ ret = u32_strmblen (input);
+ ASSERT (ret == 1);
+ }
+
+#if CONFIG_UNICODE_SAFETY
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint32_t input[] = { 0x340000, 0 };
+ ret = u32_strmblen (input);
+ ASSERT (ret == -1);
+ }
+#endif
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-strmbtouc.c b/tests/unistr/test-u32-strmbtouc.c
new file mode 100644
index 00000000..79c222e0
--- /dev/null
+++ b/tests/unistr/test-u32-strmbtouc.c
@@ -0,0 +1,86 @@
+/* Test of u32_strmbtouc() function.
+ Copyright (C) 2010 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 <http://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 uint32_t input[] = { 0 };
+ uc = 0xBADFACE;
+ ret = u32_strmbtouc (&uc, input);
+ ASSERT (ret == 0);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint32_t buf[2];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ buf[1] = 0;
+ uc = 0xBADFACE;
+ ret = u32_strmbtouc (&uc, buf);
+ ASSERT (ret == 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x20AC, 0 };
+ uc = 0xBADFACE;
+ ret = u32_strmbtouc (&uc, input);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test non-BMP unit input. */
+ {
+ static const uint32_t input[] = { 0x1D51F, 0 };
+ uc = 0xBADFACE;
+ ret = u32_strmbtouc (&uc, input);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0x1D51F);
+ }
+
+#if CONFIG_UNICODE_SAFETY
+ /* Test incomplete/invalid 1-unit input. */
+ {
+ static const uint32_t input[] = { 0x340000, 0 };
+ uc = 0xBADFACE;
+ ret = u32_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+#endif
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-strncat.c b/tests/unistr/test-u32-strncat.c
new file mode 100644
index 00000000..346bafb7
--- /dev/null
+++ b/tests/unistr/test-u32-strncat.c
@@ -0,0 +1,59 @@
+/* Test of u32_strncat() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_STRNCAT u32_strncat
+#define MAGIC 0xBADFACE
+#include "test-strncat.h"
+
+int
+main ()
+{
+ /* 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
+ };
+ check (input, SIZEOF (input));
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint32_t input[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E, 0
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-strncmp.c b/tests/unistr/test-u32-strncmp.c
new file mode 100644
index 00000000..d69913da
--- /dev/null
+++ b/tests/unistr/test-u32-strncmp.c
@@ -0,0 +1,47 @@
+/* Test of u32_strncmp() function.
+ Copyright (C) 2010 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 <http://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_STRNCMP u32_strncmp
+#include "test-strncmp.h"
+
+int
+main ()
+{
+ test_strncmp ();
+
+ /* Test comparison with non-BMP characters. */
+ {
+ static const UNIT input1[] = { 0x1D51F, 0 };
+ static const UNIT input2[] = { 0xFEFF, 0 };
+ ASSERT (U_STRNCMP (input1, input2, 1) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 1) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 2) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 2) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 1000000) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 1000000) < 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-strncpy.c b/tests/unistr/test-u32-strncpy.c
new file mode 100644
index 00000000..9309c0ed
--- /dev/null
+++ b/tests/unistr/test-u32-strncpy.c
@@ -0,0 +1,59 @@
+/* Test of u32_strncpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_STRNCPY u32_strncpy
+#define MAGIC 0xBADFACE
+#include "test-strncpy.h"
+
+int
+main ()
+{
+ /* 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
+ };
+ check (input, SIZEOF (input));
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint32_t input[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E, 0
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-strnlen.c b/tests/unistr/test-u32-strnlen.c
new file mode 100644
index 00000000..69299148
--- /dev/null
+++ b/tests/unistr/test-u32-strnlen.c
@@ -0,0 +1,56 @@
+/* Test of u32_strnlen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint32_t
+#define U_STRNLEN u32_strnlen
+#include "test-strnlen.h"
+
+int
+main ()
+{
+ /* 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
+ };
+ check (input, SIZEOF (input));
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint32_t input[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E, 0
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-to-u16.c b/tests/unistr/test-u32-to-u16.c
new file mode 100644
index 00000000..6faf5379
--- /dev/null
+++ b/tests/unistr/test-u32-to-u16.c
@@ -0,0 +1,156 @@
+/* Test of u32_to_u16() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <errno.h>
+
+#include "macros.h"
+
+static int
+check (const uint32_t *input, size_t input_length,
+ const uint16_t *expected, size_t expected_length)
+{
+ size_t length;
+ uint16_t *result;
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u32_to_u16 (input, input_length, NULL, &length);
+ if (!(result != NULL))
+ return 1;
+ if (!(length == expected_length))
+ return 2;
+ if (!(u16_cmp (result, expected, expected_length) == 0))
+ return 3;
+ free (result);
+
+ /* Test return conventions with resultbuf too small. */
+ if (expected_length > 0)
+ {
+ uint16_t *preallocated;
+
+ length = expected_length - 1;
+ preallocated = (uint16_t *) malloc (length * sizeof (uint16_t));
+ result = u32_to_u16 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 4;
+ if (!(result != preallocated))
+ return 5;
+ if (!(length == expected_length))
+ return 6;
+ if (!(u16_cmp (result, expected, expected_length) == 0))
+ return 7;
+ free (result);
+ free (preallocated);
+ }
+
+ /* Test return conventions with resultbuf large enough. */
+ {
+ uint16_t *preallocated;
+
+ length = expected_length;
+ preallocated = (uint16_t *) malloc (length * sizeof (uint16_t));
+ result = u32_to_u16 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 8;
+ if (!(preallocated == NULL || result == preallocated))
+ return 9;
+ if (!(length == expected_length))
+ return 10;
+ if (!(u16_cmp (result, expected, expected_length) == 0))
+ return 11;
+ free (preallocated);
+ }
+
+ return 0;
+}
+
+int
+main ()
+{
+ /* Empty string. */
+ ASSERT (check (NULL, 0, NULL, 0) == 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, '\n'
+ };
+ static const uint16_t expected[] =
+ { '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, '\n'
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint32_t input[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E
+ };
+ static const uint16_t expected[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* Invalid input. */
+ {
+ static const uint32_t input[] = { 'x', 0x340000, 0x50000000, 'y' };
+#if 0 /* Currently invalid input is rejected, not accommodated. */
+ static const uint16_t expected[] = { 'x', 0xFFFD, 0xFFFD, 'y' };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+#else
+ size_t length;
+ uint16_t *result;
+ uint16_t preallocated[10];
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u32_to_u16 (input, SIZEOF (input), NULL, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf too small. */
+ length = 1;
+ result = u32_to_u16 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf large enough. */
+ length = SIZEOF (preallocated);
+ result = u32_to_u16 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+#endif
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-to-u8.c b/tests/unistr/test-u32-to-u8.c
new file mode 100644
index 00000000..933fba09
--- /dev/null
+++ b/tests/unistr/test-u32-to-u8.c
@@ -0,0 +1,159 @@
+/* Test of u32_to_u8() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <errno.h>
+
+#include "macros.h"
+
+static int
+check (const uint32_t *input, size_t input_length,
+ const uint8_t *expected, size_t expected_length)
+{
+ size_t length;
+ uint8_t *result;
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u32_to_u8 (input, input_length, NULL, &length);
+ if (!(result != NULL))
+ return 1;
+ if (!(length == expected_length))
+ return 2;
+ if (!(u8_cmp (result, expected, expected_length) == 0))
+ return 3;
+ free (result);
+
+ /* Test return conventions with resultbuf too small. */
+ if (expected_length > 0)
+ {
+ uint8_t *preallocated;
+
+ length = expected_length - 1;
+ preallocated = (uint8_t *) malloc (length * sizeof (uint8_t));
+ result = u32_to_u8 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 4;
+ if (!(result != preallocated))
+ return 5;
+ if (!(length == expected_length))
+ return 6;
+ if (!(u8_cmp (result, expected, expected_length) == 0))
+ return 7;
+ free (result);
+ free (preallocated);
+ }
+
+ /* Test return conventions with resultbuf large enough. */
+ {
+ uint8_t *preallocated;
+
+ length = expected_length;
+ preallocated = (uint8_t *) malloc (length * sizeof (uint8_t));
+ result = u32_to_u8 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 8;
+ if (!(preallocated == NULL || result == preallocated))
+ return 9;
+ if (!(length == expected_length))
+ return 10;
+ if (!(u8_cmp (result, expected, expected_length) == 0))
+ return 11;
+ free (preallocated);
+ }
+
+ return 0;
+}
+
+int
+main ()
+{
+ /* Empty string. */
+ ASSERT (check (NULL, 0, NULL, 0) == 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, '\n'
+ };
+ static const uint8_t expected[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\n'
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint32_t input[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E
+ };
+ static const uint8_t expected[] =
+ { '-', '(', 0xF0, 0x9D, 0x94, 0x9E, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9F,
+ ')', '=', 0xF0, 0x9D, 0x94, 0x9F, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9E
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* Invalid input. */
+ {
+ static const uint32_t input[] = { 'x', 0x340000, 0x50000000, 'y' };
+#if 0 /* Currently invalid input is rejected, not accommodated. */
+ static const uint8_t expected[] =
+ { 'x', 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 'y' };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+#else
+ size_t length;
+ uint8_t *result;
+ uint8_t preallocated[10];
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u32_to_u8 (input, SIZEOF (input), NULL, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf too small. */
+ length = 1;
+ result = u32_to_u8 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf large enough. */
+ length = SIZEOF (preallocated);
+ result = u32_to_u8 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+#endif
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u32-uctomb.c b/tests/unistr/test-u32-uctomb.c
new file mode 100644
index 00000000..0a25177b
--- /dev/null
+++ b/tests/unistr/test-u32-uctomb.c
@@ -0,0 +1,104 @@
+/* Test of u32_uctomb() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define MAGIC 0xBADFACE
+
+int
+main ()
+{
+ /* Test ISO 646 character, in particular the NUL character. */
+ {
+ ucs4_t uc;
+
+ for (uc = 0; uc < 0x80; uc++)
+ {
+ uint32_t buf[2] = { MAGIC, MAGIC };
+ int ret;
+
+ ret = u32_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u32_uctomb (buf, uc, 1);
+ ASSERT (ret == 1);
+ ASSERT (buf[0] == uc);
+ ASSERT (buf[1] == MAGIC);
+ }
+ }
+
+ /* Test BMP character. */
+ {
+ ucs4_t uc = 0x20AC;
+ uint32_t buf[2] = { MAGIC, MAGIC };
+ int ret;
+
+ ret = u32_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u32_uctomb (buf, uc, 1);
+ ASSERT (ret == 1);
+ ASSERT (buf[0] == uc);
+ ASSERT (buf[1] == MAGIC);
+ }
+
+ /* Test non-BMP character. */
+ {
+ ucs4_t uc = 0x10FFFD;
+ uint32_t buf[2] = { MAGIC, MAGIC };
+ int ret;
+
+ ret = u32_uctomb (buf, uc, 0);
+ ASSERT (ret == -2);
+ ASSERT (buf[0] == MAGIC);
+
+ ret = u32_uctomb (buf, uc, 1);
+ ASSERT (ret == 1);
+ ASSERT (buf[0] == uc);
+ ASSERT (buf[1] == MAGIC);
+ }
+
+ /* Test invalid characters. */
+ {
+ ucs4_t invalid[] = { 0x110000, 0xD800, 0xDBFF, 0xDC00, 0xDFFF };
+ uint32_t buf[2] = { MAGIC, MAGIC };
+ size_t i;
+
+ for (i = 0; i < SIZEOF (invalid); i++)
+ {
+ ucs4_t uc = invalid[i];
+ int n;
+
+ for (n = 0; n <= 2; n++)
+ {
+ int ret = u32_uctomb (buf, uc, n);
+ ASSERT (ret == -1);
+ ASSERT (buf[0] == MAGIC);
+ ASSERT (buf[1] == MAGIC);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-check.c b/tests/unistr/test-u8-check.c
new file mode 100644
index 00000000..a32d3850
--- /dev/null
+++ b/tests/unistr/test-u8-check.c
@@ -0,0 +1,188 @@
+/* Test of u8_check() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* Test empty string. */
+ {
+ static const uint8_t input[] = "";
+ ASSERT (u8_check (input, 0) == NULL);
+ }
+
+ /* Test valid non-empty string. */
+ {
+ static const uint8_t input[] = /* "Данило Шеган" */
+ "\320\224\320\260\320\275\320\270\320\273\320\276 \320\250\320\265\320\263\320\260\320\275";
+ ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
+ }
+
+ /* Test out-of-range character with 4 bytes: U+110000. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\364\220\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test out-of-range character with 5 bytes: U+200000. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\370\210\200\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test out-of-range character with 6 bytes: U+4000000. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\374\204\200\200\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test invalid lead byte. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\376\200\200\200\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\377\200\200\200\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test overlong 2-byte character. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\301\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test overlong 3-byte character. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\340\200\277";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test overlong 4-byte character. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\360\200\277\277";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test invalid bytes in 2-byte character. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\302\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\302\100";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\302\300";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test invalid bytes in 3-byte character. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\342\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\342\100\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\342\300\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\342\200\100";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\342\200\300";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test invalid bytes in 4-byte character. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\362\200\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\362\100\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\362\300\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\362\200\100\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\362\200\300\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\362\200\200\100";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\362\200\200\300";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test truncated/incomplete 2-byte character. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\302";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test truncated/incomplete 3-byte character. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\342\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test truncated/incomplete 4-byte character. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\362\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test missing lead byte. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\200\200\200\200\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ /* Test surrogate codepoints. */
+ {
+ static const uint8_t input[] = "\320\224\320\260\355\240\200\355\260\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+ {
+ static const uint8_t input[] = "\320\224\320\260\355\260\200";
+ ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-chr.c b/tests/unistr/test-u8-chr.c
new file mode 100644
index 00000000..7c4b9990
--- /dev/null
+++ b/tests/unistr/test-u8-chr.c
@@ -0,0 +1,31 @@
+/* Test of u8_chr() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_CHR u8_chr
+#define U_SET u8_set
+#include "test-chr.h"
diff --git a/tests/unistr/test-u8-cmp.c b/tests/unistr/test-u8-cmp.c
new file mode 100644
index 00000000..73778c71
--- /dev/null
+++ b/tests/unistr/test-u8-cmp.c
@@ -0,0 +1,45 @@
+/* Test of u8_cmp() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_CMP u8_cmp
+#define MAGIC 0xBA
+#include "test-cmp.h"
+
+int
+main ()
+{
+ test_cmp ();
+
+ /* Test comparison with non-BMP characters. */
+ {
+ static const UNIT input1[] = { 0xF0, 0x9D, 0x94, 0x9E };
+ static const UNIT input2[] = { 0xEF, 0xBB, 0xBF, 0x00 };
+ ASSERT (U_CMP (input1, input2, 4) > 0);
+ ASSERT (U_CMP (input2, input1, 4) < 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-cmp2.c b/tests/unistr/test-u8-cmp2.c
new file mode 100644
index 00000000..8a7848e8
--- /dev/null
+++ b/tests/unistr/test-u8-cmp2.c
@@ -0,0 +1,28 @@
+/* Test of u8_cmp2() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_CMP2 u8_cmp2
+#define MAGIC 0xBA
+#include "test-cmp2.h"
diff --git a/tests/unistr/test-u8-cpy-alloc.c b/tests/unistr/test-u8-cpy-alloc.c
new file mode 100644
index 00000000..2d35b8f4
--- /dev/null
+++ b/tests/unistr/test-u8-cpy-alloc.c
@@ -0,0 +1,29 @@
+/* Test of u8_cpy_alloc() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_CPY_ALLOC u8_cpy_alloc
+#include "test-cpy-alloc.h"
diff --git a/tests/unistr/test-u8-cpy.c b/tests/unistr/test-u8-cpy.c
new file mode 100644
index 00000000..8d1152dc
--- /dev/null
+++ b/tests/unistr/test-u8-cpy.c
@@ -0,0 +1,28 @@
+/* Test of u8_cpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_CPY u8_cpy
+#define MAGIC 0xBA
+#include "test-cpy.h"
diff --git a/tests/unistr/test-u8-mblen.c b/tests/unistr/test-u8-mblen.c
new file mode 100644
index 00000000..75e92d68
--- /dev/null
+++ b/tests/unistr/test-u8-mblen.c
@@ -0,0 +1,155 @@
+/* Test of u8_mblen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ int ret;
+
+ /* Test zero-length input. */
+ {
+ static const uint8_t input[] = "";
+ ret = u8_mblen (input, 0);
+ ASSERT (ret == -1);
+ }
+
+ /* Test NUL unit input. */
+ {
+ static const uint8_t input[] = "";
+ ret = u8_mblen (input, 1);
+ ASSERT (ret == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint8_t buf[1];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ ret = u8_mblen (buf, 1);
+ ASSERT (ret == 1);
+ }
+ }
+
+ /* Test 2-byte character input. */
+ {
+ static const uint8_t input[] = { 0xC3, 0x97 };
+ ret = u8_mblen (input, 2);
+ ASSERT (ret == 2);
+ }
+
+ /* Test 3-byte character input. */
+ {
+ static const uint8_t input[] = { 0xE2, 0x82, 0xAC };
+ ret = u8_mblen (input, 3);
+ ASSERT (ret == 3);
+ }
+
+ /* Test 4-byte character input. */
+ {
+ static const uint8_t input[] = { 0xF4, 0x8F, 0xBF, 0xBD };
+ ret = u8_mblen (input, 4);
+ ASSERT (ret == 4);
+ }
+
+ /* Test incomplete/invalid 1-byte input. */
+ {
+ static const uint8_t input[] = { 0xC1 };
+ ret = u8_mblen (input, 1);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xC3 };
+ ret = u8_mblen (input, 1);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xE2 };
+ ret = u8_mblen (input, 1);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF4 };
+ ret = u8_mblen (input, 1);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xFE };
+ ret = u8_mblen (input, 1);
+ ASSERT (ret == -1);
+ }
+
+ /* Test incomplete/invalid 2-byte input. */
+ {
+ static const uint8_t input[] = { 0xE0, 0x9F };
+ ret = u8_mblen (input, 2);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0x82 };
+ ret = u8_mblen (input, 2);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0xD0 };
+ ret = u8_mblen (input, 2);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF0, 0x8F };
+ ret = u8_mblen (input, 2);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F };
+ ret = u8_mblen (input, 2);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0 };
+ ret = u8_mblen (input, 2);
+ ASSERT (ret == -1);
+ }
+
+ /* Test incomplete/invalid 3-byte input. */
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xBF };
+ ret = u8_mblen (input, 3);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0, 0xBF };
+ ret = u8_mblen (input, 3);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xD0 };
+ ret = u8_mblen (input, 3);
+ ASSERT (ret == -1);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-mbsnlen.c b/tests/unistr/test-u8-mbsnlen.c
new file mode 100644
index 00000000..8e68550c
--- /dev/null
+++ b/tests/unistr/test-u8-mbsnlen.c
@@ -0,0 +1,61 @@
+/* Test of u8_mbsnlen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint8_t input[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\n'
+ };
+ static const size_t expected[SIZEOF (input) + 1] =
+ { 0,
+ 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
+ 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 31, 32, 33, 34, 35, 36,
+ 37, 38, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55,
+ 56, 56, 56, 57, 57, 57, 58,
+ 59, 59, 59, 60, 60, 60, 61
+ };
+ size_t n;
+
+ for (n = 0; n <= SIZEOF (input); n++)
+ {
+ size_t len = u8_mbsnlen (input, n);
+ ASSERT (len == expected[n]);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-mbtouc-unsafe.c b/tests/unistr/test-u8-mbtouc-unsafe.c
new file mode 100644
index 00000000..b093aa81
--- /dev/null
+++ b/tests/unistr/test-u8-mbtouc-unsafe.c
@@ -0,0 +1,33 @@
+/* Test of u8_mbtouc_unsafe() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#include "test-u8-mbtouc.h"
+
+int
+main ()
+{
+ test_function (u8_mbtouc_unsafe);
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-mbtouc.c b/tests/unistr/test-u8-mbtouc.c
new file mode 100644
index 00000000..f6960a68
--- /dev/null
+++ b/tests/unistr/test-u8-mbtouc.c
@@ -0,0 +1,33 @@
+/* Test of u8_mbtouc() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#include "test-u8-mbtouc.h"
+
+int
+main ()
+{
+ test_function (u8_mbtouc);
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-mbtouc.h b/tests/unistr/test-u8-mbtouc.h
new file mode 100644
index 00000000..bcafb052
--- /dev/null
+++ b/tests/unistr/test-u8-mbtouc.h
@@ -0,0 +1,179 @@
+/* Test of u8_mbtouc() and u8_mbtouc_unsafe() functions.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+static void
+test_function (int (*my_u8_mbtouc) (ucs4_t *, const uint8_t *, size_t))
+{
+ ucs4_t uc;
+ int ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint8_t input[] = "";
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&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 = my_u8_mbtouc (&uc, buf, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test 2-byte character input. */
+ {
+ static const uint8_t input[] = { 0xC3, 0x97 };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&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 = my_u8_mbtouc (&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 = my_u8_mbtouc (&uc, input, 4);
+ ASSERT (ret == 4);
+ ASSERT (uc == 0x10FFFD);
+ }
+
+ /* Test incomplete/invalid 1-byte input. */
+ {
+ static const uint8_t input[] = { 0xC1 };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xC3 };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xE2 };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF4 };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 1);
+ ASSERT (ret == 1);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xFE };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&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 = my_u8_mbtouc (&uc, input, 2);
+ ASSERT (ret == 1 || ret == 2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0x82 };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 2);
+ ASSERT (ret == 2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0xD0 };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 2);
+ ASSERT (ret == 1 || ret == 2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF0, 0x8F };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 2);
+ ASSERT (ret == 1 || ret == 2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 2);
+ ASSERT (ret == 2);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0 };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 2);
+ ASSERT (ret == 1 || ret == 2);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ /* Test incomplete/invalid 3-byte input. */
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xBF };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 3);
+ ASSERT (ret == 3);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0, 0xBF };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 3);
+ ASSERT (ret == 1 || ret == 3);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xD0 };
+ uc = 0xBADFACE;
+ ret = my_u8_mbtouc (&uc, input, 3);
+ ASSERT (ret == 1 || ret == 3);
+ ASSERT (uc == 0xFFFD);
+ }
+}
diff --git a/tests/unistr/test-u8-mbtoucr.c b/tests/unistr/test-u8-mbtoucr.c
new file mode 100644
index 00000000..88e08d39
--- /dev/null
+++ b/tests/unistr/test-u8-mbtoucr.c
@@ -0,0 +1,187 @@
+/* Test of u8_mbtoucr() function.
+ Copyright (C) 2010 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 <http://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/tests/unistr/test-u8-move.c b/tests/unistr/test-u8-move.c
new file mode 100644
index 00000000..d18d8dd2
--- /dev/null
+++ b/tests/unistr/test-u8-move.c
@@ -0,0 +1,28 @@
+/* Test of u8_move() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_MOVE u8_move
+#define MAGIC 0xBA
+#include "test-move.h"
diff --git a/tests/unistr/test-u8-next.c b/tests/unistr/test-u8-next.c
new file mode 100644
index 00000000..c4e06b59
--- /dev/null
+++ b/tests/unistr/test-u8-next.c
@@ -0,0 +1,188 @@
+/* Test of u8_next() function.
+ Copyright (C) 2010 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 <http://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;
+ const uint8_t *ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint8_t input[] = "";
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint8_t buf[2];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ buf[1] = 0;
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, buf);
+ ASSERT (ret == buf + 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test 2-byte character input. */
+ {
+ static const uint8_t input[] = { 0xC3, 0x97, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == input + 2);
+ ASSERT (uc == 0x00D7);
+ }
+
+ /* Test 3-byte character input. */
+ {
+ static const uint8_t input[] = { 0xE2, 0x82, 0xAC, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == input + 3);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test 4-byte character input. */
+ {
+ static const uint8_t input[] = { 0xF4, 0x8F, 0xBF, 0xBD, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == input + 4);
+ ASSERT (uc == 0x10FFFD);
+ }
+
+ /* Test incomplete/invalid 1-byte input. */
+ {
+ static const uint8_t input[] = { 0xC1, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xC3, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF4, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xFE, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ /* Test incomplete/invalid 2-byte input. */
+ {
+ static const uint8_t input[] = { 0xE0, 0x9F, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0x82, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0xD0, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF0, 0x8F, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ /* Test incomplete/invalid 3-byte input. */
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xBF, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0, 0xBF, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xD0, 0 };
+ uc = 0xBADFACE;
+ ret = u8_next (&uc, input);
+ ASSERT (ret == NULL);
+ ASSERT (uc == 0xFFFD);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-prev.c b/tests/unistr/test-u8-prev.c
new file mode 100644
index 00000000..61f47ef8
--- /dev/null
+++ b/tests/unistr/test-u8-prev.c
@@ -0,0 +1,315 @@
+/* Test of u8_prev() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+static int
+check (const uint8_t *input, size_t input_length, ucs4_t *puc)
+{
+ ucs4_t uc;
+
+ /* Test recognition when at the beginning of the string. */
+ if (u8_prev (&uc, input + input_length, input) != input)
+ return 1;
+
+ /* Test recognition when preceded by a 1-unit character. */
+ {
+ uint8_t buf[100];
+ uint8_t *ptr;
+ size_t i;
+ ucs4_t uc1;
+
+ ptr = buf;
+ *ptr++ = 'x';
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ if (u8_prev (&uc1, ptr + input_length, buf) != ptr)
+ return 2;
+ if (uc1 != uc)
+ return 3;
+ }
+
+ /* Test recognition when preceded by a 2-unit character. */
+ {
+ uint8_t buf[100];
+ uint8_t *ptr;
+ size_t i;
+ ucs4_t uc1;
+
+ ptr = buf;
+ *ptr++ = 0xC3;
+ *ptr++ = 0x97;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ if (u8_prev (&uc1, ptr + input_length, buf) != ptr)
+ return 4;
+ if (uc1 != uc)
+ return 5;
+ }
+
+ /* Test recognition when preceded by a 3-unit character. */
+ {
+ uint8_t buf[100];
+ uint8_t *ptr;
+ size_t i;
+ ucs4_t uc1;
+
+ ptr = buf;
+ *ptr++ = 0xE2;
+ *ptr++ = 0x84;
+ *ptr++ = 0x82;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ if (u8_prev (&uc1, ptr + input_length, buf) != ptr)
+ return 6;
+ if (uc1 != uc)
+ return 7;
+ }
+
+ /* Test recognition when preceded by a 4-unit character. */
+ {
+ uint8_t buf[100];
+ uint8_t *ptr;
+ size_t i;
+ ucs4_t uc1;
+
+ ptr = buf;
+ *ptr++ = 0xF0;
+ *ptr++ = 0x9D;
+ *ptr++ = 0x94;
+ *ptr++ = 0x9E;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ if (u8_prev (&uc1, ptr + input_length, buf) != ptr)
+ return 8;
+ if (uc1 != uc)
+ return 9;
+ }
+
+ *puc = uc;
+ return 0;
+}
+
+static int
+check_invalid (const uint8_t *input, size_t input_length)
+{
+ ucs4_t uc;
+
+ /* Test recognition when at the beginning of the string. */
+ uc = 0xBADFACE;
+ if (u8_prev (&uc, input + input_length, input) != NULL)
+ return 1;
+ if (uc != 0xBADFACE)
+ return 2;
+
+ /* Test recognition when preceded by a 1-unit character. */
+ {
+ uint8_t buf[100];
+ uint8_t *ptr;
+ size_t i;
+
+ ptr = buf;
+ *ptr++ = 'x';
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ uc = 0xBADFACE;
+ if (u8_prev (&uc, ptr + input_length, buf) != NULL)
+ return 3;
+ if (uc != 0xBADFACE)
+ return 4;
+ }
+
+ /* Test recognition when preceded by a 2-unit character. */
+ {
+ uint8_t buf[100];
+ uint8_t *ptr;
+ size_t i;
+
+ ptr = buf;
+ *ptr++ = 0xC3;
+ *ptr++ = 0x97;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ uc = 0xBADFACE;
+ if (u8_prev (&uc, ptr + input_length, buf) != NULL)
+ return 5;
+ if (uc != 0xBADFACE)
+ return 6;
+ }
+
+ /* Test recognition when preceded by a 3-unit character. */
+ {
+ uint8_t buf[100];
+ uint8_t *ptr;
+ size_t i;
+
+ ptr = buf;
+ *ptr++ = 0xE2;
+ *ptr++ = 0x84;
+ *ptr++ = 0x82;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ uc = 0xBADFACE;
+ if (u8_prev (&uc, ptr + input_length, buf) != NULL)
+ return 7;
+ if (uc != 0xBADFACE)
+ return 8;
+ }
+
+ /* Test recognition when preceded by a 4-unit character. */
+ {
+ uint8_t buf[100];
+ uint8_t *ptr;
+ size_t i;
+
+ ptr = buf;
+ *ptr++ = 0xF0;
+ *ptr++ = 0x9D;
+ *ptr++ = 0x94;
+ *ptr++ = 0x9E;
+ for (i = 0; i < input_length; i++)
+ ptr[i] = input[i];
+
+ uc = 0xBADFACE;
+ if (u8_prev (&uc, ptr + input_length, buf) != NULL)
+ return 9;
+ if (uc != 0xBADFACE)
+ return 10;
+ }
+
+ return 0;
+}
+
+int
+main ()
+{
+ ucs4_t uc;
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint8_t buf[1];
+
+ for (c = 0; c < 0x80; c++)
+ {
+ buf[0] = c;
+ uc = 0xBADFACE;
+ ASSERT (check (buf, 1, &uc) == 0);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test 2-byte character input. */
+ {
+ static const uint8_t input[] = { 0xC3, 0x97 };
+ uc = 0xBADFACE;
+ ASSERT (check (input, SIZEOF (input), &uc) == 0);
+ ASSERT (uc == 0x00D7);
+ }
+
+ /* Test 3-byte character input. */
+ {
+ static const uint8_t input[] = { 0xE2, 0x82, 0xAC };
+ uc = 0xBADFACE;
+ ASSERT (check (input, SIZEOF (input), &uc) == 0);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test 4-byte character input. */
+ {
+ static const uint8_t input[] = { 0xF4, 0x8F, 0xBF, 0xBD };
+ uc = 0xBADFACE;
+ ASSERT (check (input, SIZEOF (input), &uc) == 0);
+ ASSERT (uc == 0x10FFFD);
+ }
+
+ /* Test incomplete/invalid 1-byte input. */
+ {
+ static const uint8_t input[] = { 0xC1 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xC3 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xE2 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xF4 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xFE };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+
+ /* Test incomplete/invalid 2-byte input. */
+ {
+ static const uint8_t input[] = { 0xE0, 0x9F };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0x82 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0xD0 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xF0, 0x8F };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+
+ /* Test incomplete/invalid 3-byte input. */
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xBF };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xE4, 0xBF };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xD0 };
+ ASSERT (check_invalid (input, SIZEOF (input)) == 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-set.c b/tests/unistr/test-u8-set.c
new file mode 100644
index 00000000..e778fed9
--- /dev/null
+++ b/tests/unistr/test-u8-set.c
@@ -0,0 +1,29 @@
+/* Test of u8_set() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_SET u8_set
+#define MAGIC 0xBA
+#define VALUE 'x'
+#include "test-set.h"
diff --git a/tests/unistr/test-u8-stpcpy.c b/tests/unistr/test-u8-stpcpy.c
new file mode 100644
index 00000000..94c04715
--- /dev/null
+++ b/tests/unistr/test-u8-stpcpy.c
@@ -0,0 +1,28 @@
+/* Test of u8_stpcpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_STPCPY u8_stpcpy
+#define MAGIC 0xBA
+#include "test-stpcpy.h"
diff --git a/tests/unistr/test-u8-stpncpy.c b/tests/unistr/test-u8-stpncpy.c
new file mode 100644
index 00000000..4809626b
--- /dev/null
+++ b/tests/unistr/test-u8-stpncpy.c
@@ -0,0 +1,52 @@
+/* Test of u8_stpncpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_STPNCPY u8_stpncpy
+#define MAGIC 0xBA
+#include "test-stpncpy.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint8_t input[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\0'
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-strcat.c b/tests/unistr/test-u8-strcat.c
new file mode 100644
index 00000000..7fa9e84e
--- /dev/null
+++ b/tests/unistr/test-u8-strcat.c
@@ -0,0 +1,28 @@
+/* Test of u8_strcat() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_STRCAT u8_strcat
+#define MAGIC 0xBA
+#include "test-strcat.h"
diff --git a/tests/unistr/test-u8-strcmp.c b/tests/unistr/test-u8-strcmp.c
new file mode 100644
index 00000000..313cd110
--- /dev/null
+++ b/tests/unistr/test-u8-strcmp.c
@@ -0,0 +1,34 @@
+/* Test of u8_strcmp() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define U_STRCMP u8_strcmp
+#include "test-u8-strcmp.h"
+
+int
+main ()
+{
+ test_u8_strcmp ();
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-strcmp.h b/tests/unistr/test-u8-strcmp.h
new file mode 100644
index 00000000..9c25dac4
--- /dev/null
+++ b/tests/unistr/test-u8-strcmp.h
@@ -0,0 +1,42 @@
+/* Test of u8_strcmp() and u8_strcoll() functions.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#define UNIT uint8_t
+#include "test-strcmp.h"
+
+static void
+test_u8_strcmp (void)
+{
+ test_strcmp ();
+
+ /* Test comparison between ASCII and non-ASCII characters. */
+ {
+ static const UNIT input1[] = { 'f', 'o', 'o', 0 };
+ static const UNIT input2[] = { 0xE2, 0x80, 0xA2, 0 };
+ ASSERT (U_STRCMP (input1, input2) < 0);
+ ASSERT (U_STRCMP (input2, input1) > 0);
+ }
+
+ /* Test comparison with non-BMP characters. */
+ {
+ static const UNIT input1[] = { 0xF0, 0x9D, 0x94, 0x9E, 0 };
+ static const UNIT input2[] = { 0xEF, 0xBB, 0xBF, 0 };
+ ASSERT (U_STRCMP (input1, input2) > 0);
+ ASSERT (U_STRCMP (input2, input1) < 0);
+ }
+}
diff --git a/tests/unistr/test-u8-strcoll.c b/tests/unistr/test-u8-strcoll.c
new file mode 100644
index 00000000..ae5c9a4e
--- /dev/null
+++ b/tests/unistr/test-u8-strcoll.c
@@ -0,0 +1,41 @@
+/* Test of u8_strcoll() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define U_STRCMP u8_strcoll
+#include "test-u8-strcmp.h"
+
+int
+main ()
+{
+ /* This test relies on three facts:
+ - setlocale is not being called, therefore the locale is the "C" locale.
+ - In the "C" locale, strcoll is equivalent to strcmp.
+ - In the u8_strcoll implementation, Unicode strings that are not
+ convertible to the locale encoding are sorted higher than convertible
+ strings and compared according to u8_strcmp. */
+
+ test_u8_strcmp ();
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-strcpy.c b/tests/unistr/test-u8-strcpy.c
new file mode 100644
index 00000000..810f9750
--- /dev/null
+++ b/tests/unistr/test-u8-strcpy.c
@@ -0,0 +1,28 @@
+/* Test of u8_strcpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_STRCPY u8_strcpy
+#define MAGIC 0xBA
+#include "test-strcpy.h"
diff --git a/tests/unistr/test-u8-strdup.c b/tests/unistr/test-u8-strdup.c
new file mode 100644
index 00000000..6da21515
--- /dev/null
+++ b/tests/unistr/test-u8-strdup.c
@@ -0,0 +1,27 @@
+/* Test of u8_strdup() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_STRDUP u8_strdup
+#include "test-strdup.h"
diff --git a/tests/unistr/test-u8-strlen.c b/tests/unistr/test-u8-strlen.c
new file mode 100644
index 00000000..3dfa1b01
--- /dev/null
+++ b/tests/unistr/test-u8-strlen.c
@@ -0,0 +1,50 @@
+/* Test of u8_strlen() function.
+ Copyright (C) 2010 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 <http://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 uint8_t input[] = { 0 };
+ ASSERT (u8_strlen (input) == 0);
+ }
+
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint8_t input[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\0'
+ };
+ ASSERT (u8_strlen (input) == SIZEOF (input) - 1);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-strmblen.c b/tests/unistr/test-u8-strmblen.c
new file mode 100644
index 00000000..bde3000e
--- /dev/null
+++ b/tests/unistr/test-u8-strmblen.c
@@ -0,0 +1,149 @@
+/* Test of u8_strmblen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ int ret;
+
+ /* Test NUL unit input. */
+ {
+ static const uint8_t input[] = "";
+ ret = u8_strmblen (input);
+ ASSERT (ret == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint8_t buf[2];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ buf[1] = 0;
+ ret = u8_strmblen (buf);
+ ASSERT (ret == 1);
+ }
+ }
+
+ /* Test 2-byte character input. */
+ {
+ static const uint8_t input[] = { 0xC3, 0x97, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == 2);
+ }
+
+ /* Test 3-byte character input. */
+ {
+ static const uint8_t input[] = { 0xE2, 0x82, 0xAC, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == 3);
+ }
+
+ /* Test 4-byte character input. */
+ {
+ static const uint8_t input[] = { 0xF4, 0x8F, 0xBF, 0xBD, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == 4);
+ }
+
+ /* Test incomplete/invalid 1-byte input. */
+ {
+ static const uint8_t input[] = { 0xC1, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xC3, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF4, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xFE, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+
+ /* Test incomplete/invalid 2-byte input. */
+ {
+ static const uint8_t input[] = { 0xE0, 0x9F, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0x82, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0xD0, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF0, 0x8F, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+
+ /* Test incomplete/invalid 3-byte input. */
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xBF, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0, 0xBF, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xD0, 0 };
+ ret = u8_strmblen (input);
+ ASSERT (ret == -1);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-strmbtouc.c b/tests/unistr/test-u8-strmbtouc.c
new file mode 100644
index 00000000..55913575
--- /dev/null
+++ b/tests/unistr/test-u8-strmbtouc.c
@@ -0,0 +1,188 @@
+/* Test of u8_strmbtouc() function.
+ Copyright (C) 2010 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 <http://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_strmbtouc (&uc, input);
+ ASSERT (ret == 0);
+ ASSERT (uc == 0);
+ }
+
+ /* Test ISO 646 unit input. */
+ {
+ ucs4_t c;
+ uint8_t buf[2];
+
+ for (c = 1; c < 0x80; c++)
+ {
+ buf[0] = c;
+ buf[1] = 0;
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, buf);
+ ASSERT (ret == 1);
+ ASSERT (uc == c);
+ }
+ }
+
+ /* Test 2-byte character input. */
+ {
+ static const uint8_t input[] = { 0xC3, 0x97, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == 2);
+ ASSERT (uc == 0x00D7);
+ }
+
+ /* Test 3-byte character input. */
+ {
+ static const uint8_t input[] = { 0xE2, 0x82, 0xAC, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == 3);
+ ASSERT (uc == 0x20AC);
+ }
+
+ /* Test 4-byte character input. */
+ {
+ static const uint8_t input[] = { 0xF4, 0x8F, 0xBF, 0xBD, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == 4);
+ ASSERT (uc == 0x10FFFD);
+ }
+
+ /* Test incomplete/invalid 1-byte input. */
+ {
+ static const uint8_t input[] = { 0xC1, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xC3, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xF4, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xFE, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+
+ /* Test incomplete/invalid 2-byte input. */
+ {
+ static const uint8_t input[] = { 0xE0, 0x9F, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0x82, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xE2, 0xD0, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xF0, 0x8F, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+
+ /* Test incomplete/invalid 3-byte input. */
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xBF, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0xD0, 0xBF, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+ {
+ static const uint8_t input[] = { 0xF3, 0x8F, 0xD0, 0 };
+ uc = 0xBADFACE;
+ ret = u8_strmbtouc (&uc, input);
+ ASSERT (ret == -1);
+ ASSERT (uc == 0xBADFACE);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-strncat.c b/tests/unistr/test-u8-strncat.c
new file mode 100644
index 00000000..bb90041f
--- /dev/null
+++ b/tests/unistr/test-u8-strncat.c
@@ -0,0 +1,52 @@
+/* Test of u8_strncat() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_STRNCAT u8_strncat
+#define MAGIC 0xBA
+#include "test-strncat.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint8_t input[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\0'
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-strncmp.c b/tests/unistr/test-u8-strncmp.c
new file mode 100644
index 00000000..f63cdaa2
--- /dev/null
+++ b/tests/unistr/test-u8-strncmp.c
@@ -0,0 +1,53 @@
+/* Test of u8_strncmp() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_STRNCMP u8_strncmp
+#include "test-strncmp.h"
+
+int
+main ()
+{
+ test_strncmp ();
+
+ /* Test comparison with non-BMP characters. */
+ {
+ static const UNIT input1[] = { 0xF0, 0x9D, 0x94, 0x9E, 0 };
+ static const UNIT input2[] = { 0xEF, 0xBB, 0xBF, 0 };
+ ASSERT (U_STRNCMP (input1, input2, 1) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 1) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 2) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 2) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 3) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 3) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 4) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 4) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 5) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 5) < 0);
+ ASSERT (U_STRNCMP (input1, input2, 1000000) > 0);
+ ASSERT (U_STRNCMP (input2, input1, 1000000) < 0);
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-strncpy.c b/tests/unistr/test-u8-strncpy.c
new file mode 100644
index 00000000..64cabdc4
--- /dev/null
+++ b/tests/unistr/test-u8-strncpy.c
@@ -0,0 +1,52 @@
+/* Test of u8_strncpy() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_STRNCPY u8_strncpy
+#define MAGIC 0xBA
+#include "test-strncpy.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint8_t input[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\0'
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-strnlen.c b/tests/unistr/test-u8-strnlen.c
new file mode 100644
index 00000000..98de7977
--- /dev/null
+++ b/tests/unistr/test-u8-strnlen.c
@@ -0,0 +1,49 @@
+/* Test of u8_strnlen() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+#define UNIT uint8_t
+#define U_STRNLEN u8_strnlen
+#include "test-strnlen.h"
+
+int
+main ()
+{
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint8_t input[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\0'
+ };
+ check (input, SIZEOF (input));
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-to-u16.c b/tests/unistr/test-u8-to-u16.c
new file mode 100644
index 00000000..02ef44fe
--- /dev/null
+++ b/tests/unistr/test-u8-to-u16.c
@@ -0,0 +1,158 @@
+/* Test of u8_to_u16() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <errno.h>
+
+#include "macros.h"
+
+static int
+check (const uint8_t *input, size_t input_length,
+ const uint16_t *expected, size_t expected_length)
+{
+ size_t length;
+ uint16_t *result;
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u8_to_u16 (input, input_length, NULL, &length);
+ if (!(result != NULL))
+ return 1;
+ if (!(length == expected_length))
+ return 2;
+ if (!(u16_cmp (result, expected, expected_length) == 0))
+ return 3;
+ free (result);
+
+ /* Test return conventions with resultbuf too small. */
+ if (expected_length > 0)
+ {
+ uint16_t *preallocated;
+
+ length = expected_length - 1;
+ preallocated = (uint16_t *) malloc (length * sizeof (uint16_t));
+ result = u8_to_u16 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 4;
+ if (!(result != preallocated))
+ return 5;
+ if (!(length == expected_length))
+ return 6;
+ if (!(u16_cmp (result, expected, expected_length) == 0))
+ return 7;
+ free (result);
+ free (preallocated);
+ }
+
+ /* Test return conventions with resultbuf large enough. */
+ {
+ uint16_t *preallocated;
+
+ length = expected_length;
+ preallocated = (uint16_t *) malloc (length * sizeof (uint16_t));
+ result = u8_to_u16 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 8;
+ if (!(preallocated == NULL || result == preallocated))
+ return 9;
+ if (!(length == expected_length))
+ return 10;
+ if (!(u16_cmp (result, expected, expected_length) == 0))
+ return 11;
+ free (preallocated);
+ }
+
+ return 0;
+}
+
+int
+main ()
+{
+ /* Empty string. */
+ ASSERT (check (NULL, 0, NULL, 0) == 0);
+
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint8_t input[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\n'
+ };
+ static const uint16_t expected[] =
+ { '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, '\n'
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint8_t input[] =
+ { '-', '(', 0xF0, 0x9D, 0x94, 0x9E, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9F,
+ ')', '=', 0xF0, 0x9D, 0x94, 0x9F, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9E
+ };
+ static const uint16_t expected[] =
+ { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
+ 0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* Invalid input. */
+ {
+ static const uint8_t input[] = { 'x', 0xC2, 0xC3, 'y' };
+#if 0 /* Currently invalid input is rejected, not accommodated. */
+ static const uint16_t expected[] = { 'x', 0xFFFD, 0xFFFD, 'y' };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+#else
+ size_t length;
+ uint16_t *result;
+ uint16_t preallocated[10];
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u8_to_u16 (input, SIZEOF (input), NULL, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf too small. */
+ length = 1;
+ result = u8_to_u16 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf large enough. */
+ length = SIZEOF (preallocated);
+ result = u8_to_u16 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+#endif
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-to-u32.c b/tests/unistr/test-u8-to-u32.c
new file mode 100644
index 00000000..d148e62a
--- /dev/null
+++ b/tests/unistr/test-u8-to-u32.c
@@ -0,0 +1,158 @@
+/* Test of u8_to_u32() function.
+ Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
+
+#include <config.h>
+
+#include "unistr.h"
+
+#include <errno.h>
+
+#include "macros.h"
+
+static int
+check (const uint8_t *input, size_t input_length,
+ const uint32_t *expected, size_t expected_length)
+{
+ size_t length;
+ uint32_t *result;
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u8_to_u32 (input, input_length, NULL, &length);
+ if (!(result != NULL))
+ return 1;
+ if (!(length == expected_length))
+ return 2;
+ if (!(u32_cmp (result, expected, expected_length) == 0))
+ return 3;
+ free (result);
+
+ /* Test return conventions with resultbuf too small. */
+ if (expected_length > 0)
+ {
+ uint32_t *preallocated;
+
+ length = expected_length - 1;
+ preallocated = (uint32_t *) malloc (length * sizeof (uint32_t));
+ result = u8_to_u32 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 4;
+ if (!(result != preallocated))
+ return 5;
+ if (!(length == expected_length))
+ return 6;
+ if (!(u32_cmp (result, expected, expected_length) == 0))
+ return 7;
+ free (result);
+ free (preallocated);
+ }
+
+ /* Test return conventions with resultbuf large enough. */
+ {
+ uint32_t *preallocated;
+
+ length = expected_length;
+ preallocated = (uint32_t *) malloc (length * sizeof (uint32_t));
+ result = u8_to_u32 (input, input_length, preallocated, &length);
+ if (!(result != NULL))
+ return 8;
+ if (!(preallocated == NULL || result == preallocated))
+ return 9;
+ if (!(length == expected_length))
+ return 10;
+ if (!(u32_cmp (result, expected, expected_length) == 0))
+ return 11;
+ free (preallocated);
+ }
+
+ return 0;
+}
+
+int
+main ()
+{
+ /* Empty string. */
+ ASSERT (check (NULL, 0, NULL, 0) == 0);
+
+ /* Simple string. */
+ { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */
+ static const uint8_t input[] =
+ { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
+ 0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
+ 0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
+ '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
+ 'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
+ ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
+ 0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
+ 0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\n'
+ };
+ static const uint32_t expected[] =
+ { '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, '\n'
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* String with characters outside the BMP. */
+ {
+ static const uint8_t input[] =
+ { '-', '(', 0xF0, 0x9D, 0x94, 0x9E, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9F,
+ ')', '=', 0xF0, 0x9D, 0x94, 0x9F, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9E
+ };
+ static const uint32_t expected[] =
+ { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
+ 0x1D51F, 0x00D7, 0x1D51E
+ };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+ }
+
+ /* Invalid input. */
+ {
+ static const uint8_t input[] = { 'x', 0xC2, 0xC3, 'y' };
+#if 0 /* Currently invalid input is rejected, not accommodated. */
+ static const uint32_t expected[] = { 'x', 0xFFFD, 0xFFFD, 'y' };
+ ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
+#else
+ size_t length;
+ uint32_t *result;
+ uint32_t preallocated[10];
+
+ /* Test return conventions with resultbuf == NULL. */
+ result = u8_to_u32 (input, SIZEOF (input), NULL, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf too small. */
+ length = 1;
+ result = u8_to_u32 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+
+ /* Test return conventions with resultbuf large enough. */
+ length = SIZEOF (preallocated);
+ result = u8_to_u32 (input, SIZEOF (input), preallocated, &length);
+ ASSERT (result == NULL);
+ ASSERT (errno == EILSEQ);
+#endif
+ }
+
+ return 0;
+}
diff --git a/tests/unistr/test-u8-uctomb.c b/tests/unistr/test-u8-uctomb.c
new file mode 100644
index 00000000..8fbdc429
--- /dev/null
+++ b/tests/unistr/test-u8-uctomb.c
@@ -0,0 +1,157 @@
+/* Test of u8_uctomb() function.
+ Copyright (C) 2010 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 <http://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;
+}