usleep tests: Avoid failure due to known Cygwin 3.5.3 bug.
[gnulib.git] / tests / test-mcel.c
blob8f2f00220b67ac64cafe57ec13add56038ac1ccc
1 /* Test <mcel.h>
2 Copyright 2023-2024 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 #include <config.h>
19 #include <mcel.h>
21 #include <locale.h>
23 #include "macros.h"
25 static wint_t
26 to_ascii (wint_t c)
28 return c & 0x7f;
31 static int
32 sgn (int i)
34 return (i > 0) - (i < 0);
37 static void
38 test_mcel_vs_mbrtoc32 (unsigned char uc, mcel_t c, size_t n, char32_t ch)
40 ASSERT (!c.err == (n <= MB_LEN_MAX));
41 ASSERT (c.err
42 ? c.err == uc && c.ch == 0 && c.len == 1
43 : c.ch == ch && c.len == (n ? n : 1));
46 int
47 main (int argc, char *argv[])
49 /* configure should already have checked that the locale is supported. */
50 if (setlocale (LC_ALL, "") == NULL)
51 return 1;
53 mcel_t prev;
54 for (int ch = 0; ch < 0x80; ch++)
56 mcel_t c = mcel_ch (ch, 1);
57 ASSERT (c.ch == ch);
58 ASSERT (c.len == 1);
59 ASSERT (!c.err);
60 ASSERT (mcel_cmp (c, c) == 0);
61 ASSERT (mcel_tocmp (to_ascii, c, c) == 0);
62 if (ch)
64 ASSERT (mcel_cmp (prev, c) < 0);
65 ASSERT (mcel_cmp (c, prev) > 0);
66 ASSERT (mcel_tocmp (to_ascii, prev, c) < 0);
67 ASSERT (mcel_tocmp (to_ascii, c, prev) > 0);
69 ASSERT (mcel_isbasic (ch));
70 prev = c;
72 for (char ch = CHAR_MIN; ; ch++)
74 ASSERT (mcel_isbasic (ch) == (0 <= ch && ch <= 0x7f));
75 if (ch == CHAR_MAX)
76 break;
79 if (argc > 1 && argv[1][0] == '5')
81 /* Locale encoding is GB18030. */
82 #if (defined __GLIBC__ && __GLIBC__ == 2 && __GLIBC_MINOR__ >= 13 && __GLIBC_MINOR__ <= 15) || (GL_CHAR32_T_IS_UNICODE && (defined __FreeBSD__ || defined __NetBSD__ || defined __sun))
83 if (test_exit_status != EXIT_SUCCESS)
84 return test_exit_status;
85 fputs ("Skipping test: The GB18030 converter in this system's iconv is broken.\n", stderr);
86 return 77;
87 #endif
90 for (int ch = 0x80; ch < 0x200; ch++)
92 mcel_t c = mcel_ch (ch, 2);
93 ASSERT (c.ch == ch);
94 ASSERT (c.len == 2);
95 ASSERT (!c.err);
96 ASSERT (mcel_cmp (c, c) == 0);
97 ASSERT (mcel_tocmp (to_ascii, c, c) == 0);
98 ASSERT (mcel_cmp (prev, c) < 0);
99 ASSERT (mcel_cmp (c, prev) > 0);
100 ASSERT (mcel_tocmp (to_ascii, c, c) == 0);
101 int cmp = to_ascii (c.ch) ? -1 : 1;
102 ASSERT (sgn (mcel_tocmp (to_ascii, prev, c)) == cmp);
103 ASSERT (sgn (mcel_tocmp (to_ascii, c, prev)) == -cmp);
104 prev = c;
106 for (unsigned char err = 0x80; ; err++)
108 mcel_t c = mcel_err (err);
109 ASSERT (!c.ch);
110 ASSERT (c.len == 1);
111 ASSERT (c.err == err);
112 ASSERT (mcel_cmp (c, c) == 0);
113 ASSERT (mcel_cmp (prev, c) < 0);
114 ASSERT (mcel_cmp (c, prev) > 0);
115 ASSERT (mcel_tocmp (to_ascii, c, c) == 0);
116 ASSERT (mcel_tocmp (to_ascii, prev, c) < 0);
117 ASSERT (mcel_tocmp (to_ascii, c, prev) > 0);
118 prev = c;
119 if (err == (unsigned char) -1)
120 break;
123 for (int i = CHAR_MIN; i <= CHAR_MAX; i++)
124 for (int j = CHAR_MIN; j <= CHAR_MAX; j++)
125 for (int k = CHAR_MIN; k <= CHAR_MAX; k++)
127 char const ijk[] = {i, j, k};
128 mbstate_t mbs = {0};
129 char32_t ch;
130 size_t n = mbrtoc32 (&ch, ijk, sizeof ijk, &mbs);
131 mcel_t c = mcel_scan (ijk, ijk + sizeof ijk);
132 test_mcel_vs_mbrtoc32 (i, c, n, ch);
134 static char const terminator[] = "\r\n./";
135 for (int ti = 0; ti < sizeof terminator; ti++)
137 char t = terminator[ti];
138 if (i == t || j == t || k == t)
139 continue;
140 char const ijkt[] = {i, j, k, t};
141 mcel_t d = mcel_scant (ijkt, t);
142 ASSERT (c.ch == d.ch && c.err == d.err && c.len == d.len);
143 if (!t)
145 mcel_t z = mcel_scanz (ijkt);
146 ASSERT (d.ch == z.ch && d.err == z.err && d.len == z.len);
151 return test_exit_status;