1 /* Test of c32islower() function.
2    Copyright (C) 2020-2021 Free Software Foundation, Inc.
3 
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.
8 
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.
13 
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/>.  */
16 
17 #include <config.h>
18 
19 #include <uchar.h>
20 
21 #include "signature.h"
22 SIGNATURE_CHECK (c32islower, int, (wint_t));
23 
24 #include <locale.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <wchar.h>
28 
29 #include "macros.h"
30 
31 /* Returns the value of c32islower for the multibyte character s[0..n-1].  */
32 static int
for_character(const char * s,size_t n)33 for_character (const char *s, size_t n)
34 {
35   mbstate_t state;
36   char32_t wc;
37   size_t ret;
38 
39   memset (&state, '\0', sizeof (mbstate_t));
40   wc = (char32_t) 0xBADFACE;
41   ret = mbrtoc32 (&wc, s, n, &state);
42   ASSERT (ret == n);
43 
44   return c32islower (wc);
45 }
46 
47 int
main(int argc,char * argv[])48 main (int argc, char *argv[])
49 {
50   int is;
51   char buf[4];
52 
53   /* configure should already have checked that the locale is supported.  */
54   if (setlocale (LC_ALL, "") == NULL)
55     return 1;
56 
57   /* Test WEOF.  */
58   is = c32islower (WEOF);
59   ASSERT (is == 0);
60 
61   /* Test single-byte characters.
62      POSIX specifies in
63        <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html>
64      that
65        - in all locales, the lowercase characters include the a ... z
66          characters,
67        - in the "POSIX" locale (which is usually the same as the "C" locale),
68          the lowercase characters include only the ASCII a ... z characters.
69    */
70   {
71     int c;
72 
73     for (c = 0; c < 0x100; c++)
74       switch (c)
75         {
76         case '\t': case '\v': case '\f':
77         case ' ': case '!': case '"': case '#': case '%':
78         case '&': case '\'': case '(': case ')': case '*':
79         case '+': case ',': case '-': case '.': case '/':
80         case '0': case '1': case '2': case '3': case '4':
81         case '5': case '6': case '7': case '8': case '9':
82         case ':': case ';': case '<': case '=': case '>':
83         case '?':
84         case 'A': case 'B': case 'C': case 'D': case 'E':
85         case 'F': case 'G': case 'H': case 'I': case 'J':
86         case 'K': case 'L': case 'M': case 'N': case 'O':
87         case 'P': case 'Q': case 'R': case 'S': case 'T':
88         case 'U': case 'V': case 'W': case 'X': case 'Y':
89         case 'Z':
90         case '[': case '\\': case ']': case '^': case '_':
91         case 'a': case 'b': case 'c': case 'd': case 'e':
92         case 'f': case 'g': case 'h': case 'i': case 'j':
93         case 'k': case 'l': case 'm': case 'n': case 'o':
94         case 'p': case 'q': case 'r': case 's': case 't':
95         case 'u': case 'v': case 'w': case 'x': case 'y':
96         case 'z': case '{': case '|': case '}': case '~':
97           /* c is in the ISO C "basic character set".  */
98           buf[0] = (unsigned char) c;
99           is = for_character (buf, 1);
100           switch (c)
101             {
102             case 'a': case 'b': case 'c': case 'd': case 'e':
103             case 'f': case 'g': case 'h': case 'i': case 'j':
104             case 'k': case 'l': case 'm': case 'n': case 'o':
105             case 'p': case 'q': case 'r': case 's': case 't':
106             case 'u': case 'v': case 'w': case 'x': case 'y':
107             case 'z':
108               ASSERT (is != 0);
109               break;
110             default:
111               ASSERT (is == 0);
112               break;
113             }
114           break;
115         }
116   }
117 
118   if (argc > 1)
119     switch (argv[1][0])
120       {
121       case '0':
122         /* C locale; tested above.  */
123         return 0;
124 
125       case '1':
126         /* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
127         {
128           /* U+00B2 SUPERSCRIPT TWO */
129           is = for_character ("\262", 1);
130           ASSERT (is == 0);
131         #if !(defined __GLIBC__ || defined __sun || defined __CYGWIN__ || (defined _WIN32 && !defined __CYGWIN__))
132           /* U+00B5 MICRO SIGN */
133           is = for_character ("\265", 1);
134           ASSERT (is == 0);
135         #endif
136           /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
137           is = for_character ("\311", 1);
138           ASSERT (is == 0);
139         #if !defined __CYGWIN__
140           /* U+00DF LATIN SMALL LETTER SHARP S */
141           is = for_character ("\337", 1);
142           ASSERT (is != 0);
143         #endif
144           /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
145           is = for_character ("\351", 1);
146           ASSERT (is != 0);
147           /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
148           is = for_character ("\377", 1);
149           ASSERT (is != 0);
150         }
151         return 0;
152 
153       case '2':
154         /* Locale encoding is EUC-JP.  */
155         {
156           /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
157           is = for_character ("\217\252\261", 3);
158           ASSERT (is == 0);
159         #if !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __CYGWIN__)
160           /* U+00DF LATIN SMALL LETTER SHARP S */
161           is = for_character ("\217\251\316", 3);
162           ASSERT (is != 0);
163         #endif
164         #if !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__)
165           /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
166           is = for_character ("\217\253\261", 3);
167           ASSERT (is != 0);
168           /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
169           is = for_character ("\217\253\363", 3);
170           ASSERT (is != 0);
171         #endif
172           /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
173           is = for_character ("\217\251\250", 3);
174           ASSERT (is == 0);
175         #if !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__)
176           /* U+0142 LATIN SMALL LETTER L WITH STROKE */
177           is = for_character ("\217\251\310", 3);
178           ASSERT (is != 0);
179         #endif
180           /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
181           is = for_character ("\247\273", 2);
182           ASSERT (is == 0);
183         #if !(defined __FreeBSD__ || defined __DragonFly__)
184           /* U+0449 CYRILLIC SMALL LETTER SHCHA */
185           is = for_character ("\247\353", 2);
186           ASSERT (is != 0);
187         #endif
188           /* U+3073 HIRAGANA LETTER BI */
189           is = for_character ("\244\323", 2);
190           ASSERT (is == 0);
191         #if !defined __DragonFly__
192           /* U+FF47 FULLWIDTH LATIN SMALL LETTER G */
193           is = for_character ("\243\347", 2);
194           ASSERT (is != 0);
195         #endif
196         }
197         return 0;
198 
199       case '3':
200         /* Locale encoding is UTF-8.  */
201         {
202           /* U+00B2 SUPERSCRIPT TWO */
203           is = for_character ("\302\262", 2);
204           ASSERT (is == 0);
205         #if !(defined __GLIBC__ || (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined _AIX || defined __sun || defined __CYGWIN__ || (defined _WIN32 && !defined __CYGWIN__))
206           /* U+00B5 MICRO SIGN */
207           is = for_character ("\302\265", 2);
208           ASSERT (is == 0);
209         #endif
210           /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
211           is = for_character ("\303\211", 2);
212           ASSERT (is == 0);
213         #if !defined __CYGWIN__
214           /* U+00DF LATIN SMALL LETTER SHARP S */
215           is = for_character ("\303\237", 2);
216           ASSERT (is != 0);
217         #endif
218           /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
219           is = for_character ("\303\251", 2);
220           ASSERT (is != 0);
221           /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
222           is = for_character ("\303\277", 2);
223           ASSERT (is != 0);
224           /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
225           is = for_character ("\305\201", 2);
226           ASSERT (is == 0);
227           /* U+0142 LATIN SMALL LETTER L WITH STROKE */
228           is = for_character ("\305\202", 2);
229           ASSERT (is != 0);
230           /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
231           is = for_character ("\320\251", 2);
232           ASSERT (is == 0);
233           /* U+0449 CYRILLIC SMALL LETTER SHCHA */
234           is = for_character ("\321\211", 2);
235           ASSERT (is != 0);
236           /* U+05D5 HEBREW LETTER VAV */
237           is = for_character ("\327\225", 2);
238           ASSERT (is == 0);
239           /* U+3073 HIRAGANA LETTER BI */
240           is = for_character ("\343\201\263", 3);
241           ASSERT (is == 0);
242           /* U+3162 HANGUL LETTER YI */
243           is = for_character ("\343\205\242", 3);
244           ASSERT (is == 0);
245           /* U+FF47 FULLWIDTH LATIN SMALL LETTER G */
246           is = for_character ("\357\275\207", 3);
247           ASSERT (is != 0);
248           /* U+FFDB HALFWIDTH HANGUL LETTER YI */
249           is = for_character ("\357\277\233", 3);
250           ASSERT (is == 0);
251           /* U+10419 DESERET CAPITAL LETTER EF */
252           is = for_character ("\360\220\220\231", 4);
253           ASSERT (is == 0);
254         #if !(defined __FreeBSD__ || defined __DragonFly__ || defined __sun)
255           /* U+10441 DESERET SMALL LETTER EF */
256           is = for_character ("\360\220\221\201", 4);
257           ASSERT (is != 0);
258         #endif
259           /* U+E0041 TAG LATIN CAPITAL LETTER A */
260           is = for_character ("\363\240\201\201", 4);
261           ASSERT (is == 0);
262           /* U+E0061 TAG LATIN SMALL LETTER A */
263           is = for_character ("\363\240\201\241", 4);
264           ASSERT (is == 0);
265         }
266         return 0;
267 
268       case '4':
269         /* Locale encoding is GB18030.  */
270         {
271           /* U+00B2 SUPERSCRIPT TWO */
272           is = for_character ("\201\060\205\065", 4);
273           ASSERT (is == 0);
274         #if !(defined __GLIBC__ || (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __NetBSD__)
275           /* U+00B5 MICRO SIGN */
276           is = for_character ("\201\060\205\070", 4);
277           ASSERT (is == 0);
278         #endif
279           /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
280           is = for_character ("\201\060\207\067", 4);
281           ASSERT (is == 0);
282         #if !(defined __FreeBSD__ || defined __DragonFly__ || defined __sun)
283           /* U+00DF LATIN SMALL LETTER SHARP S */
284           is = for_character ("\201\060\211\070", 4);
285           ASSERT (is != 0);
286         #endif
287         #if !defined __DragonFly__
288           /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
289           is = for_character ("\250\246", 2);
290           ASSERT (is != 0);
291         #endif
292         #if !(defined __FreeBSD__ || defined __DragonFly__ || defined __sun)
293           /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
294           is = for_character ("\201\060\213\067", 4);
295           ASSERT (is != 0);
296         #endif
297           /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
298           is = for_character ("\201\060\221\071", 4);
299           ASSERT (is == 0);
300         #if !(defined __FreeBSD__ || defined __DragonFly__ || defined __sun)
301           /* U+0142 LATIN SMALL LETTER L WITH STROKE */
302           is = for_character ("\201\060\222\060", 4);
303           ASSERT (is != 0);
304         #endif
305           /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
306           is = for_character ("\247\273", 2);
307           ASSERT (is == 0);
308         #if !(defined __FreeBSD__ || defined __DragonFly__)
309           /* U+0449 CYRILLIC SMALL LETTER SHCHA */
310           is = for_character ("\247\353", 2);
311           ASSERT (is != 0);
312         #endif
313           /* U+05D5 HEBREW LETTER VAV */
314           is = for_character ("\201\060\371\067", 4);
315           ASSERT (is == 0);
316           /* U+3073 HIRAGANA LETTER BI */
317           is = for_character ("\244\323", 2);
318           ASSERT (is == 0);
319           /* U+3162 HANGUL LETTER YI */
320           is = for_character ("\201\071\256\062", 4);
321           ASSERT (is == 0);
322         #if !defined __DragonFly__
323           /* U+FF47 FULLWIDTH LATIN SMALL LETTER G */
324           is = for_character ("\243\347", 2);
325           ASSERT (is != 0);
326         #endif
327           /* U+FFDB HALFWIDTH HANGUL LETTER YI */
328           is = for_character ("\204\061\241\071", 4);
329           ASSERT (is == 0);
330           /* U+10419 DESERET CAPITAL LETTER EF */
331           is = for_character ("\220\060\351\071", 4);
332           ASSERT (is == 0);
333         #if !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __sun)
334           /* U+10441 DESERET SMALL LETTER EF */
335           is = for_character ("\220\060\355\071", 4);
336           ASSERT (is != 0);
337         #endif
338           /* U+E0041 TAG LATIN CAPITAL LETTER A */
339           is = for_character ("\323\066\234\063", 4);
340           ASSERT (is == 0);
341           /* U+E0061 TAG LATIN SMALL LETTER A */
342           is = for_character ("\323\066\237\065", 4);
343           ASSERT (is == 0);
344         }
345         return 0;
346 
347       }
348 
349   return 1;
350 }
351