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