]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/tst-widetext.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / libio / tst-widetext.c
CommitLineData
a3b231b7
UD
1/* Test program for the wide character stream functions handling larger
2 amounts of text.
04277e02 3 Copyright (C) 2000-2019 Free Software Foundation, Inc.
a3b231b7
UD
4 This file is part of the GNU C Library.
5 Contributed by Ulrich Drepper <drepper@cygnus.com>.
6
7 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
a3b231b7
UD
11
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 15 Lesser General Public License for more details.
a3b231b7 16
41bdb6e2 17 You should have received a copy of the GNU Lesser General Public
59ba27a6 18 License along with the GNU C Library; if not, see
5a82c748 19 <https://www.gnu.org/licenses/>. */
a3b231b7
UD
20
21#include <assert.h>
22#include <iconv.h>
23#include <locale.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <unistd.h>
28#include <wchar.h>
29
30/* Approximate size of the file (must be larger). */
31#define SIZE 210000
32
33
29955b5d
AS
34static int
35do_test (void)
a3b231b7
UD
36{
37 char name[] = "/tmp/widetext.out.XXXXXX";
38 char mbbuf[SIZE];
39 char mb2buf[SIZE];
40 wchar_t wcbuf[SIZE];
41 wchar_t wc2buf[SIZE];
42 size_t mbsize;
43 size_t wcsize;
44 int fd;
45 FILE *fp;
46 size_t n;
47 int res;
48 int status = 0;
49 wchar_t *wcp;
50
51 setlocale (LC_ALL, "de_DE.UTF-8");
52 printf ("locale used: %s\n\n", setlocale (LC_ALL, NULL));
53
54 /* Read the file into memory. */
55 mbsize = fread (mbbuf, 1, SIZE, stdin);
56 if (mbsize == 0)
57 {
6d497bbe 58 printf ("%u: cannot read input file from standard input: %m\n",
a3b231b7
UD
59 __LINE__);
60 exit (1);
61 }
62
63 printf ("INFO: input file has %Zd bytes\n", mbsize);
64
65 /* First convert the text to wide characters. We use iconv here. */
66 {
67 iconv_t cd;
68 char *inbuf = mbbuf;
69 size_t inleft = mbsize;
70 char *outbuf = (char *) wcbuf;
71 size_t outleft = sizeof (wcbuf);
72 size_t nonr;
73
74 cd = iconv_open ("WCHAR_T", "UTF-8");
75 if (cd == (iconv_t) -1)
76 {
6d497bbe 77 printf ("%u: cannot get iconv descriptor for conversion to UCS4\n",
a3b231b7
UD
78 __LINE__);
79 exit (1);
80 }
81
82 /* We must need only one call and there must be no losses. */
83 nonr = iconv (cd, &inbuf, &inleft, &outbuf, &outleft);
84 if (nonr != 0 && nonr != (size_t) -1)
85 {
6d497bbe 86 printf ("%u: iconv performed %Zd nonreversible conversions\n",
a3b231b7
UD
87 __LINE__, nonr);
88 exit (1);
89 }
90
57b36a0a 91 if (nonr == (size_t) -1)
a3b231b7
UD
92 {
93 printf ("\
6d497bbe 94%u: iconv returned with %Zd and errno = %m (inleft: %Zd, outleft: %Zd)\n",
a3b231b7
UD
95 __LINE__, nonr, inleft, outleft);
96 exit (1);
97 }
98
99 if (inleft != 0)
100 {
6d497bbe 101 printf ("%u: iconv didn't convert all input\n", __LINE__);
a3b231b7
UD
102 exit (1);
103 }
104
105 iconv_close (cd);
106
107 if ((sizeof (wcbuf) - outleft) % sizeof (wchar_t) != 0)
108 {
6d497bbe 109 printf ("%u: iconv converted not complete wchar_t\n", __LINE__);
a3b231b7
UD
110 exit (1);
111 }
112
113 wcsize = (sizeof (wcbuf) - outleft) / sizeof (wchar_t);
114 assert (wcsize + 1 <= SIZE);
115 }
116
117 /* Now that we finished the preparations, run the first test. We
118 are writing the wide char data out and read it back in. We write
119 and read single characters. */
120
121 fd = mkstemp (name);
122 if (fd == -1)
123 {
6d497bbe 124 printf ("%u: cannot open temporary file: %m\n", __LINE__);
a3b231b7
UD
125 exit (1);
126 }
127
128 unlink (name);
129
130 fp = fdopen (dup (fd), "w");
131 if (fp == NULL)
132 {
6d497bbe 133 printf ("%u: fdopen of temp file for writing failed: %m\n", __LINE__);
a3b231b7
UD
134 exit (1);
135 }
136
137 for (n = 0; n < wcsize; ++n)
138 {
139 if (fputwc (wcbuf[n], fp) == WEOF)
140 {
6d497bbe 141 printf ("%u: fputwc failed: %m\n", __LINE__);
a3b231b7
UD
142 exit (1);
143 }
144 }
145
146 res = fclose (fp);
147 if (res != 0)
148 {
6d497bbe 149 printf ("%u: fclose after single-character writing failed (%d): %m\n",
a3b231b7
UD
150 __LINE__, res);
151 exit (1);
152 }
153
154 lseek (fd, SEEK_SET, 0);
155 fp = fdopen (dup (fd), "r");
156 if (fp == NULL)
157 {
6d497bbe 158 printf ("%u: fdopen of temp file for reading failed: %m\n", __LINE__);
a3b231b7
UD
159 exit (1);
160 }
161
162 for (n = 0; n < wcsize; ++n)
163 {
164 wint_t wch = fgetwc (fp);
165 if (wch == WEOF)
166 {
6d497bbe 167 printf ("%u: fgetwc failed (idx %Zd): %m\n", __LINE__, n);
a3b231b7
UD
168 exit (1);
169 }
170 wc2buf[n] = wch;
171 }
172
173 /* There should be nothing else. */
174 if (fgetwc (fp) != WEOF)
175 {
6d497bbe 176 printf ("%u: too many characters available with fgetwc\n", __LINE__);
a3b231b7
UD
177 status = 1;
178 }
179 else if (wmemcmp (wcbuf, wc2buf, wcsize) != 0)
180 {
6d497bbe 181 printf ("%u: buffer read with fgetwc differs\n", __LINE__);
a3b231b7
UD
182 status = 1;
183 }
184
185 res = fclose (fp);
186 if (res != 0)
187 {
6d497bbe 188 printf ("%u: fclose after single-character reading failed (%d): %m\n",
a3b231b7
UD
189 __LINE__, res);
190 exit (1);
191 }
192
193 /* Just make sure there are no two errors which hide each other, read the
194 file using the `char' functions. */
195
196 lseek (fd, SEEK_SET, 0);
197 fp = fdopen (fd, "r");
198 if (fp == NULL)
199 {
6d497bbe 200 printf ("%u: fdopen of temp file for reading failed: %m\n", __LINE__);
a3b231b7
UD
201 exit (1);
202 }
203
204 if (fread (mb2buf, 1, mbsize, fp) != mbsize)
205 {
6d497bbe 206 printf ("%u: cannot read all of the temp file\n", __LINE__);
a3b231b7
UD
207 status = 1;
208 }
209 else
210 {
211 /* Make sure there is nothing left. */
212 if (fgetc (fp) != EOF)
213 {
6d497bbe 214 printf ("%u: more input available\n", __LINE__);
a3b231b7
UD
215 status = 1;
216 }
217
218 if (memcmp (mb2buf, mbbuf, mbsize) != 0)
219 {
6d497bbe 220 printf ("%u: buffer written with fputwc differs\n", __LINE__);
a3b231b7
UD
221 status = 1;
222 }
223 }
224
225 res = fclose (fp);
226 if (res != 0)
227 {
6d497bbe 228 printf ("%u: fclose after single-character reading failed (%d): %m\n",
a3b231b7
UD
229 __LINE__, res);
230 exit (1);
231 }
232
233 /* Now to reading and writing line-wise. */
234
235 fd = mkstemp (strcpy (name, "/tmp/widetext.out.XXXXXX"));
236 if (fd == -1)
237 {
6d497bbe 238 printf ("%u: cannot open temporary file: %m\n", __LINE__);
a3b231b7
UD
239 exit (1);
240 }
241
242 unlink (name);
243
244 fp = fdopen (dup (fd), "w");
245 if (fp == NULL)
246 {
6d497bbe 247 printf ("%u: fdopen of temp file for writing failed: %m\n", __LINE__);
a3b231b7
UD
248 exit (1);
249 }
250
251 for (wcp = wcbuf; wcp < &wcbuf[wcsize]; )
252 {
253 wchar_t *wendp = wcschr (wcp, L'\n');
254
255 if (wendp != NULL)
256 {
257 /* Temporarily NUL terminate the line. */
258 wchar_t save = wendp[1];
259 wendp[1] = L'\0';
260
261 fputws (wcp, fp);
262
263 wendp[1] = save;
264 wcp = &wendp[1];
265 }
266 else
267 {
268 fputws (wcp, fp);
269 wcp = wcschr (wcp, L'\0');
270 assert (wcp == &wcbuf[wcsize]);
271 }
272 }
273
274 res = fclose (fp);
275 if (res != 0)
276 {
6d497bbe 277 printf ("%u: fclose after line-wise writing failed (%d): %m\n",
a3b231b7
UD
278 __LINE__, res);
279 exit (1);
280 }
281
282 lseek (fd, SEEK_SET, 0);
283 fp = fdopen (dup (fd), "r");
284 if (fp == NULL)
285 {
6d497bbe 286 printf ("%u: fdopen of temp file for reading failed: %m\n", __LINE__);
a3b231b7
UD
287 exit (1);
288 }
289
290 for (wcp = wc2buf; wcp < &wc2buf[wcsize]; )
291 {
292 if (fgetws (wcp, &wc2buf[wcsize] - wcp + 1, fp) == NULL)
293 {
eca2772b 294 printf ("%u: short read using fgetws (only %td of %Zd)\n",
a3b231b7
UD
295 __LINE__, wcp - wc2buf, wcsize);
296 status = 1;
297 break;
298 }
299 wcp = wcschr (wcp, L'\0');
300 }
301
302 if (wcp > &wc2buf[wcsize])
303 {
6d497bbe 304 printf ("%u: fgetws read too much\n", __LINE__);
a3b231b7
UD
305 status = 1;
306 }
307 else if (fgetwc (fp) != WEOF)
308 {
309 /* There should be nothing else. */
6d497bbe 310 printf ("%u: too many characters available with fgetws\n", __LINE__);
a3b231b7
UD
311 status = 1;
312 }
313
314 if (wcp >= &wc2buf[wcsize] && wmemcmp (wcbuf, wc2buf, wcsize) != 0)
315 {
6d497bbe 316 printf ("%u: buffer read with fgetws differs\n", __LINE__);
a3b231b7
UD
317 status = 1;
318 }
319
320 res = fclose (fp);
321 if (res != 0)
322 {
6d497bbe 323 printf ("%u: fclose after single-character reading failed (%d): %m\n",
a3b231b7
UD
324 __LINE__, res);
325 exit (1);
326 }
327
328 /* Just make sure there are no two errors which hide each other, read the
329 file using the `char' functions. */
330
331 lseek (fd, SEEK_SET, 0);
332 fp = fdopen (fd, "r");
333 if (fp == NULL)
334 {
6d497bbe 335 printf ("%u: fdopen of temp file for reading failed: %m\n", __LINE__);
a3b231b7
UD
336 exit (1);
337 }
338
339 if (fread (mb2buf, 1, mbsize, fp) != mbsize)
340 {
6d497bbe 341 printf ("%u: cannot read all of the temp file\n", __LINE__);
a3b231b7
UD
342 status = 1;
343 }
344 else
345 {
346 /* Make sure there is nothing left. */
347 if (fgetc (fp) != EOF)
348 {
6d497bbe 349 printf ("%u: more input available\n", __LINE__);
a3b231b7
UD
350 status = 1;
351 }
352
353 if (memcmp (mb2buf, mbbuf, mbsize) != 0)
354 {
6d497bbe 355 printf ("%u: buffer written with fputws differs\n", __LINE__);
a3b231b7
UD
356 status = 1;
357 }
358 }
359
360 res = fclose (fp);
361 if (res != 0)
362 {
6d497bbe 363 printf ("%u: fclose after single-character reading failed (%d): %m\n",
a3b231b7
UD
364 __LINE__, res);
365 exit (1);
366 }
367
368 return status;
369}
29955b5d
AS
370
371#define TEST_FUNCTION do_test ()
372#include "../test-skeleton.c"