tests: add signature checks
[gnulib.git] / tests / test-wcsrtombs.c
1 /* Test of conversion of wide string to string.
2    Copyright (C) 2008, 2009 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 <http://www.gnu.org/licenses/>.  */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2008.  */
18
19 #include <config.h>
20
21 #include <wchar.h>
22
23 #include "signature.h"
24 SIGNATURE_CHECK (wcsrtombs, size_t, (char *, wchar_t const **, size_t,
25                                      mbstate_t *));
26
27 #include <locale.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #define ASSERT(expr) \
33   do                                                                         \
34     {                                                                        \
35       if (!(expr))                                                           \
36         {                                                                    \
37           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
38           fflush (stderr);                                                   \
39           abort ();                                                          \
40         }                                                                    \
41     }                                                                        \
42   while (0)
43
44 int
45 main (int argc, char *argv[])
46 {
47   /* configure should already have checked that the locale is supported.  */
48   if (setlocale (LC_ALL, "") == NULL)
49     return 1;
50
51   if (argc > 1)
52     {
53       wchar_t input[10];
54       size_t n;
55       const wchar_t *src;
56       #define BUFSIZE 20
57       char buf[BUFSIZE];
58       size_t ret;
59
60       {
61         size_t i;
62         for (i = 0; i < BUFSIZE; i++)
63           buf[i] = '_';
64       }
65
66       switch (argv[1][0])
67         {
68         case '1':
69           /* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
70           {
71             const char original[] = "B\374\337er"; /* "Büßer" */
72
73             ret = mbstowcs (input, original, 10);
74             ASSERT (ret == 5);
75
76             for (n = 0; n < 10; n++)
77               {
78                 src = input;
79                 ret = wcsrtombs (NULL, &src, n, NULL);
80                 ASSERT (ret == 5);
81                 ASSERT (src == input);
82
83                 src = input;
84                 ret = wcsrtombs (buf, &src, n, NULL);
85                 ASSERT (ret == (n <= 5 ? n : 5));
86                 ASSERT (src == (n <= 5 ? input + n : NULL));
87                 ASSERT (memcmp (buf, original, ret) == 0);
88                 if (src == NULL)
89                   ASSERT (buf[ret] == '\0');
90                 ASSERT (buf[ret + (src == NULL) + 0] == '_');
91                 ASSERT (buf[ret + (src == NULL) + 1] == '_');
92                 ASSERT (buf[ret + (src == NULL) + 2] == '_');
93               }
94           }
95           break;
96
97         case '2':
98           /* Locale encoding is UTF-8.  */
99           {
100             const char original[] = "B\303\274\303\237er"; /* "Büßer" */
101
102             ret = mbstowcs (input, original, 10);
103             ASSERT (ret == 5);
104
105             for (n = 0; n < 10; n++)
106               {
107                 src = input;
108                 ret = wcsrtombs (NULL, &src, n, NULL);
109                 ASSERT (ret == 7);
110                 ASSERT (src == input);
111
112                 src = input;
113                 ret = wcsrtombs (buf, &src, n, NULL);
114                 ASSERT (ret == (n < 1 ? n :
115                                 n < 3 ? 1 :
116                                 n < 5 ? 3 :
117                                 n <= 7 ? n : 7));
118                 ASSERT (src == (n < 1 ? input + n :
119                                 n < 3 ? input + 1 :
120                                 n < 5 ? input + 2 :
121                                 n <= 7 ? input + (n - 2) : NULL));
122                 ASSERT (memcmp (buf, original, ret) == 0);
123                 if (src == NULL)
124                   ASSERT (buf[ret] == '\0');
125                 ASSERT (buf[ret + (src == NULL) + 0] == '_');
126                 ASSERT (buf[ret + (src == NULL) + 1] == '_');
127                 ASSERT (buf[ret + (src == NULL) + 2] == '_');
128               }
129           }
130           break;
131
132         case '3':
133           /* Locale encoding is EUC-JP.  */
134           {
135             const char original[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */
136
137             ret = mbstowcs (input, original, 10);
138             ASSERT (ret == 5);
139
140             for (n = 0; n < 10; n++)
141               {
142                 src = input;
143                 ret = wcsrtombs (NULL, &src, n, NULL);
144                 ASSERT (ret == 8);
145                 ASSERT (src == input);
146
147                 src = input;
148                 ret = wcsrtombs (buf, &src, n, NULL);
149                 ASSERT (ret == (n < 1 ? n :
150                                 n < 3 ? 1 :
151                                 n < 5 ? 3 :
152                                 n < 7 ? 5 :
153                                 n <= 8 ? n : 8));
154                 ASSERT (src == (n < 1 ? input + n :
155                                 n < 3 ? input + 1 :
156                                 n < 5 ? input + 2 :
157                                 n < 7 ? input + 3 :
158                                 n <= 8 ? input + (n - 3) : NULL));
159                 ASSERT (memcmp (buf, original, ret) == 0);
160                 if (src == NULL)
161                   ASSERT (buf[ret] == '\0');
162                 ASSERT (buf[ret + (src == NULL) + 0] == '_');
163                 ASSERT (buf[ret + (src == NULL) + 1] == '_');
164                 ASSERT (buf[ret + (src == NULL) + 2] == '_');
165               }
166           }
167           break;
168
169
170         case '4':
171           /* Locale encoding is GB18030.  */
172           {
173             const char original[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
174
175             ret = mbstowcs (input, original, 10);
176             ASSERT (ret == 5);
177
178             for (n = 0; n < 10; n++)
179               {
180                 src = input;
181                 ret = wcsrtombs (NULL, &src, n, NULL);
182                 ASSERT (ret == 9);
183                 ASSERT (src == input);
184
185                 src = input;
186                 ret = wcsrtombs (buf, &src, n, NULL);
187                 ASSERT (ret == (n < 1 ? n :
188                                 n < 3 ? 1 :
189                                 n < 7 ? 3 :
190                                 n <= 9 ? n : 9));
191                 ASSERT (src == (n < 1 ? input + n :
192                                 n < 3 ? input + 1 :
193                                 n < 7 ? input + 2 :
194                                 n <= 9 ? input + (n - 4) : NULL));
195                 ASSERT (memcmp (buf, original, ret) == 0);
196                 if (src == NULL)
197                   ASSERT (buf[ret] == '\0');
198                 ASSERT (buf[ret + (src == NULL) + 0] == '_');
199                 ASSERT (buf[ret + (src == NULL) + 1] == '_');
200                 ASSERT (buf[ret + (src == NULL) + 2] == '_');
201               }
202           }
203           break;
204
205         default:
206           return 1;
207         }
208
209       return 0;
210     }
211
212   return 1;
213 }