1 /* Copyright (C) 2000-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library 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 GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <ctype.h>
19 #include <langinfo.h>
20 #include <locale.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <wchar.h>
26 #include <wctype.h>
27 #include <sys/types.h>
28 
29 
30 #define ZERO  "\xe2\x82\x80"
31 #define ONE   "\xe2\x82\x81"
32 #define TWO   "\xe2\x82\x82"
33 #define THREE "\xe2\x82\x83"
34 #define FOUR  "\xe2\x82\x84"
35 #define FIVE  "\xe2\x82\x85"
36 #define SIX   "\xe2\x82\x86"
37 #define SEVEN "\xe2\x82\x87"
38 #define EIGHT "\xe2\x82\x88"
39 #define NINE  "\xe2\x82\x89"
40 
41 static struct printf_int_test
42 {
43   int n;
44   const char *format;
45   const char *expected;
46 } printf_int_tests[] =
47 {
48   {       0, "%I'10d", "       " ZERO },
49   {       1, "%I'10d", "       " ONE },
50   {       2, "%I'10d", "       " TWO },
51   {       3, "%I'10d", "       " THREE },
52   {       4, "%I'10d", "       " FOUR },
53   {       5, "%I'10d", "       " FIVE },
54   {       6, "%I'10d", "       " SIX },
55   {       7, "%I'10d", "       " SEVEN },
56   {       8, "%I'10d", "       " EIGHT },
57   {       9, "%I'10d", "       " NINE },
58   {      11, "%I'10d", "    " ONE ONE },
59   {      12, "%I'10d", "    " ONE TWO },
60   {     123, "%I10d",  " " ONE TWO THREE },
61   {     123, "%I'10d", " " ONE TWO THREE },
62   {    1234, "%I10d",  ONE TWO THREE FOUR },
63   {    1234, "%I'10d", ONE "," TWO THREE FOUR },
64   {   12345, "%I'10d", ONE TWO "," THREE FOUR FIVE },
65   {  123456, "%I'10d", ONE TWO THREE "," FOUR FIVE SIX },
66   { 1234567, "%I'10d", ONE "," TWO THREE FOUR "," FIVE SIX SEVEN }
67 };
68 #define nprintf_int_tests \
69   (sizeof (printf_int_tests) / sizeof (printf_int_tests[0]))
70 
71 #define WZERO  L"\x2080"
72 #define WONE   L"\x2081"
73 #define WTWO   L"\x2082"
74 #define WTHREE L"\x2083"
75 #define WFOUR  L"\x2084"
76 #define WFIVE  L"\x2085"
77 #define WSIX   L"\x2086"
78 #define WSEVEN L"\x2087"
79 #define WEIGHT L"\x2088"
80 #define WNINE  L"\x2089"
81 
82 static struct wprintf_int_test
83 {
84   int n;
85   const wchar_t *format;
86   const wchar_t *expected;
87 } wprintf_int_tests[] =
88 {
89   {       0, L"%I'10d", L"         " WZERO },
90   {       1, L"%I'10d", L"         " WONE },
91   {       2, L"%I'10d", L"         " WTWO },
92   {       3, L"%I'10d", L"         " WTHREE },
93   {       4, L"%I'10d", L"         " WFOUR },
94   {       5, L"%I'10d", L"         " WFIVE },
95   {       6, L"%I'10d", L"         " WSIX },
96   {       7, L"%I'10d", L"         " WSEVEN },
97   {       8, L"%I'10d", L"         " WEIGHT },
98   {       9, L"%I'10d", L"         " WNINE },
99   {      11, L"%I'10d", L"        " WONE WONE },
100   {      12, L"%I'10d", L"        " WONE WTWO },
101   {     123, L"%I10d",  L"       " WONE WTWO WTHREE },
102   {     123, L"%I'10d", L"       " WONE WTWO WTHREE },
103   {    1234, L"%I10d",  L"      " WONE WTWO WTHREE WFOUR },
104   {    1234, L"%I'10d", L"     " WONE L"," WTWO WTHREE WFOUR },
105   {   12345, L"%I'10d", L"    " WONE WTWO L"," WTHREE WFOUR WFIVE },
106   {  123456, L"%I'10d", L"   " WONE WTWO WTHREE L"," WFOUR WFIVE WSIX },
107   { 1234567, L"%I'10d", L" " WONE L"," WTWO WTHREE WFOUR L"," WFIVE WSIX WSEVEN }
108 };
109 #define nwprintf_int_tests \
110   (sizeof (wprintf_int_tests) / sizeof (wprintf_int_tests[0]))
111 
112 
113 static int
do_test(void)114 do_test (void)
115 {
116   int cnt;
117   int failures;
118   int status;
119 
120   if (setlocale (LC_ALL, "test7") == NULL)
121     {
122       puts ("cannot set locale `test7'");
123       exit (1);
124     }
125   printf ("CODESET = \"%s\"\n", nl_langinfo (CODESET));
126 
127   /* First: printf tests.  */
128   failures = 0;
129   for (cnt = 0; cnt < (int) nprintf_int_tests; ++cnt)
130     {
131       char buf[100];
132       ssize_t n;
133 
134       n = snprintf (buf, sizeof buf, printf_int_tests[cnt].format,
135 		    printf_int_tests[cnt].n);
136 
137       printf ("%3d: got \"%s\", expected \"%s\"",
138 	      cnt, buf, printf_int_tests[cnt].expected);
139 
140       if (n != (ssize_t) strlen (printf_int_tests[cnt].expected)
141 	  || strcmp (buf, printf_int_tests[cnt].expected) != 0)
142 	{
143 	  puts ("  -> FAILED");
144 	  ++failures;
145 	}
146       else
147 	puts ("  -> OK");
148     }
149 
150   printf ("%d failures in printf tests\n", failures);
151   status = failures != 0;
152 
153   /* wprintf tests.  */
154   failures = 0;
155   for (cnt = 0; cnt < (int) nwprintf_int_tests; ++cnt)
156     {
157       wchar_t buf[100];
158       ssize_t n;
159 
160       n = swprintf (buf, sizeof buf / sizeof (buf[0]),
161 		    wprintf_int_tests[cnt].format,
162 		    wprintf_int_tests[cnt].n);
163 
164       printf ("%3d: got \"%ls\", expected \"%ls\"",
165 	      cnt, buf, wprintf_int_tests[cnt].expected);
166 
167       if (n != (ssize_t) wcslen (wprintf_int_tests[cnt].expected)
168 	  || wcscmp (buf, wprintf_int_tests[cnt].expected) != 0)
169 	{
170 	  puts ("  -> FAILED");
171 	  ++failures;
172 	}
173       else
174 	puts ("  -> OK");
175     }
176 
177   printf ("%d failures in wprintf tests\n", failures);
178   status = failures != 0;
179 
180   /* ctype tests.  This makes sure that the multibyte character digit
181      representations are not handle in this table.  */
182   failures = 0;
183   for (cnt = 0; cnt < 256; ++cnt)
184     if (cnt >= '0' && cnt <= '9')
185       {
186 	if (! isdigit (cnt))
187 	  {
188 	    printf ("isdigit ('%c') == 0\n", cnt);
189 	    ++failures;
190 	  }
191       }
192     else
193       {
194 	if (isdigit (cnt))
195 	  {
196 	    printf ("isdigit (%d) != 0\n", cnt);
197 	    ++failures;
198 	  }
199       }
200 
201   printf ("%d failures in ctype tests\n", failures);
202   status = failures != 0;
203 
204   /* wctype tests.  This makes sure the second set of digits is also
205      recorded.  */
206   failures = 0;
207   for (cnt = 0; cnt < 256; ++cnt)
208     if (cnt >= '0' && cnt <= '9')
209       {
210 	if (! iswdigit (cnt))
211 	  {
212 	    printf ("iswdigit (L'%c') == 0\n", cnt);
213 	    ++failures;
214 	  }
215       }
216     else
217       {
218 	if (iswdigit (cnt))
219 	  {
220 	    printf ("iswdigit (%d) != 0\n", cnt);
221 	    ++failures;
222 	  }
223       }
224 
225   for (cnt = 0x2070; cnt < 0x2090; ++cnt)
226     if (cnt >= 0x2080 && cnt <= 0x2089)
227       {
228 	if (! iswdigit (cnt))
229 	  {
230 	    printf ("iswdigit (U%04X) == 0\n", cnt);
231 	    ++failures;
232 	  }
233       }
234     else
235       {
236 	if (iswdigit (cnt))
237 	  {
238 	    printf ("iswdigit (U%04X) != 0\n", cnt);
239 	    ++failures;
240 	  }
241       }
242 
243   printf ("%d failures in wctype tests\n", failures);
244   status = failures != 0;
245 
246   return status;
247 }
248 
249 #define TEST_FUNCTION do_test ()
250 #include "../test-skeleton.c"
251