Line data Source code
1 : /* t-printf.c - Check the estream printf fucntions.
2 : * Copyright (C) 2013 g10 Code GmbH
3 : *
4 : * This file is part of libgpg-error.
5 : *
6 : * libgpg-error is free software; you can redistribute it and/or
7 : * modify it under the terms of the GNU Lesser General Public License
8 : * as published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * libgpg-error is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see <https://www.gnu.org/licenses/>.
18 : */
19 :
20 : /* Note that these tests check against glibc behaviour. On non glibc
21 : systems expect non matching return codes in some border cases. */
22 :
23 :
24 : #if HAVE_CONFIG_H
25 : # include <config.h>
26 : #endif
27 :
28 : #include <stdio.h>
29 : #include <stdlib.h>
30 : #include <string.h>
31 : #include <assert.h>
32 : #include <errno.h>
33 : #include <locale.h>
34 :
35 : #define PGM "t-printf"
36 :
37 : #include "t-common.h"
38 :
39 :
40 : static char *one_test_buf1;
41 : static int one_test_rc1;
42 :
43 : static void
44 153 : one_test_x0 (const char *format, ...)
45 : {
46 : va_list arg_ptr;
47 :
48 153 : show ("format: ->%s<-\n", format);
49 :
50 153 : errno = ENOENT; /* For the "%m" test. */
51 153 : va_start (arg_ptr, format);
52 : #ifdef HAVE_VASPRINTF
53 153 : one_test_rc1 = vasprintf (&one_test_buf1, format, arg_ptr);
54 : #else
55 : one_test_rc1 = -1;
56 : #endif
57 153 : va_end (arg_ptr);
58 153 : if (one_test_rc1 == -1)
59 : {
60 0 : fail (" sys: errno=%d (%s)\n", errno, strerror (errno));
61 0 : one_test_buf1 = NULL;
62 : }
63 : else
64 153 : show (" sys: ->%s<-\n", one_test_buf1);
65 153 : }
66 :
67 : static void
68 153 : one_test_x1 (const char *format, ...)
69 : {
70 : int rc2;
71 : va_list arg_ptr;
72 : char *buf2;
73 :
74 153 : errno = ENOENT;
75 153 : va_start (arg_ptr, format);
76 153 : rc2 = gpgrt_vasprintf (&buf2, format, arg_ptr);
77 153 : va_end (arg_ptr);
78 153 : if (rc2 == -1)
79 : {
80 0 : fail (" our: errno=%d (%s)\n", errno, strerror (errno));
81 : }
82 : else
83 153 : show (" our: ->%s<-\n", buf2);
84 :
85 153 : if (one_test_rc1 != -1 && rc2 != -1 && strcmp (one_test_buf1, buf2))
86 : {
87 0 : fail ("error: output does not match\n"
88 : "format: ->%s<-\n sys: ->%s<-\n our: ->%s<-\n",
89 : format, one_test_buf1, buf2);
90 : }
91 153 : else if ( one_test_rc1 != rc2 )
92 : {
93 0 : fail ("error: return codes are different: sys_rc=%d our_rc=%d\n",
94 : one_test_rc1, rc2);
95 : }
96 :
97 153 : free (buf2);
98 153 : }
99 :
100 : static void
101 153 : one_test_x2 (const char *format, ...)
102 : {
103 : va_list arg_ptr;
104 : char *buf2;
105 :
106 : /* Test once more using the bsprintf variant. */
107 153 : errno = ENOENT;
108 153 : va_start (arg_ptr, format);
109 153 : buf2 = gpgrt_vbsprintf (format, arg_ptr);
110 153 : va_end (arg_ptr);
111 153 : if (!buf2)
112 : {
113 0 : fail (" our(2): errno=%d (%s)\n", errno, strerror (errno));
114 : }
115 153 : else if (verbose)
116 0 : show (" our: ->%s<-\n", buf2);
117 :
118 153 : if (one_test_rc1 != -1 && buf2 && strcmp (one_test_buf1, buf2))
119 : {
120 0 : fail ("error: output does not match\n"
121 : "format(2): ->%s<-\n sys: ->%s<-\n our: ->%s<-\n",
122 : format, one_test_buf1, buf2);
123 : }
124 153 : es_free (buf2);
125 :
126 153 : free (one_test_buf1);
127 153 : one_test_buf1 = NULL;
128 153 : }
129 :
130 :
131 : #define one_test_0(a) \
132 : one_test_x0 (a); \
133 : one_test_x1 (a); \
134 : one_test_x2 (a)
135 : #define one_test_1(a, b) \
136 : one_test_x0 (a, b); \
137 : one_test_x1 (a, b); \
138 : one_test_x2 (a, b)
139 : #define one_test_2(a, b, c) \
140 : one_test_x0 (a, b, c); \
141 : one_test_x1 (a, b, c); \
142 : one_test_x2 (a, b, c)
143 : #define one_test_3(a, b, c, d) \
144 : one_test_x0 (a, b, c, d); \
145 : one_test_x1 (a, b, c, d); \
146 : one_test_x2 (a, b, c, d)
147 :
148 : static void
149 1 : run_tests (void)
150 : {
151 : #ifndef HAVE_VASPRINTF
152 : /* We do not have a system vasprintf. */
153 : show ("run-tests: disabled due to missing vasprintf.\n");
154 : #else /*HAVE_VASPRINTF */
155 :
156 : /*one_test ("%d %% %'d", 17, 19681977);*/
157 :
158 1 : one_test_2 ("%d %% %d", 17, 768114563);
159 1 : one_test_2 ("%d %% %d", 17, -768114563);
160 :
161 1 : one_test_1 ("%d", 17);
162 1 : one_test_1 ("%4d", 17);
163 1 : one_test_1 ("%40d", 17);
164 1 : one_test_1 ("%-d", 17);
165 1 : one_test_1 ("%-4d", 17);
166 1 : one_test_1 ("%-140d", 17);
167 1 : one_test_1 ("%d", -17);
168 1 : one_test_1 ("%4d", -17);
169 1 : one_test_1 ("%40d", -17);
170 1 : one_test_1 ("%-d", -17);
171 1 : one_test_1 ("%-4d", -17);
172 1 : one_test_1 ("%-40d", -17);
173 :
174 1 : one_test_1 ("%+4d", 17);
175 1 : one_test_1 ("%+4d", -17);
176 1 : one_test_1 ("%-+4d", 17);
177 1 : one_test_1 ("%-+4d", -17);
178 1 : one_test_1 ("% 4d", 17);
179 1 : one_test_1 ("% 4d", -17);
180 1 : one_test_1 ("%- +4d", 17);
181 1 : one_test_1 ("%- +4d", -17);
182 :
183 1 : one_test_1 ("%.4d", 17);
184 1 : one_test_1 ("%.0d", 17);
185 1 : one_test_1 ("%.0d", 0);
186 1 : one_test_1 ("%.4d", -17);
187 1 : one_test_1 ("%.0d", -17);
188 1 : one_test_1 ("%6.4d", 17);
189 1 : one_test_1 ("%6.4d", -17);
190 1 : one_test_1 ("%6.0d", 0);
191 1 : one_test_1 ("%4.6d", 17);
192 1 : one_test_1 ("%4.6d", -17);
193 :
194 1 : one_test_1 ("% 4.6d", 17);
195 1 : one_test_1 ("% 6.0d", 0);
196 :
197 1 : one_test_1 ("%.4d", 17);
198 1 : one_test_1 ("%04d", 17);
199 1 : one_test_1 ("%.4d", -17);
200 1 : one_test_1 ("%04d", -17);
201 1 : one_test_1 ("%0.d", 0);
202 :
203 1 : one_test_2 ("%*d", 7, 42);
204 1 : one_test_2 ("%*d", -7, 42);
205 1 : one_test_2 ("%.*d", 7, 42);
206 1 : one_test_2 ("%.*d", -7, 42);
207 1 : one_test_3 ("%*.*d", 10, 7, 42);
208 1 : one_test_3 ("%*.*d", 10, -7, 42);
209 1 : one_test_3 ("%*.*d", -10, 7, 42);
210 1 : one_test_3 ("%*.*d", -10, -7, 42);
211 :
212 1 : one_test_2 ("%*x", 7, 42);
213 1 : one_test_2 ("%*x", -7, 42);
214 1 : one_test_2 ("%.*x", 7, 42);
215 1 : one_test_2 ("%.*x", -7, 42);
216 1 : one_test_3 ("%*.*x", 10, 7, 42);
217 1 : one_test_3 ("%*.*x", 10, -7, 42);
218 1 : one_test_3 ("%*.*x", -10, 7, 42);
219 1 : one_test_3 ("%*.*x", -10, -7, 42);
220 1 : one_test_2 ("%#*x", 7, 42);
221 1 : one_test_2 ("%#*x", -7, 42);
222 1 : one_test_2 ("%#.*x", 7, 42);
223 1 : one_test_2 ("%#.*x", -7, 42);
224 1 : one_test_3 ("%#*.*x", 10, 7, 42);
225 1 : one_test_3 ("%#*.*x", 10, -7, 42);
226 1 : one_test_3 ("%#*.*x", -10, 7, 42);
227 1 : one_test_3 ("%#*.*x", -10, -7, 42);
228 :
229 1 : one_test_2 ("%*X", 7, 42);
230 1 : one_test_2 ("%*X", -7, 42);
231 1 : one_test_2 ("%.*X", 7, 42);
232 1 : one_test_2 ("%.*X", -7, 42);
233 1 : one_test_3 ("%*.*X", 10, 7, 42);
234 1 : one_test_3 ("%*.*X", 10, -7, 42);
235 1 : one_test_3 ("%*.*X", -10, 7, 42);
236 1 : one_test_3 ("%*.*X", -10, -7, 42);
237 1 : one_test_2 ("%#*X", 7, 42);
238 1 : one_test_2 ("%#*X", -7, 42);
239 1 : one_test_2 ("%#.*X", 7, 42);
240 1 : one_test_2 ("%#.*X", -7, 42);
241 1 : one_test_3 ("%#*.*X", 10, 7, 42);
242 1 : one_test_3 ("%#*.*X", 10, -7, 42);
243 1 : one_test_3 ("%#*.*X", -10, 7, 42);
244 1 : one_test_3 ("%#*.*X", -10, -7, 42);
245 :
246 1 : one_test_2 ("%*o", 7, 42);
247 1 : one_test_2 ("%*o", -7, 42);
248 1 : one_test_2 ("%.*o", 7, 42);
249 1 : one_test_2 ("%.*o", -7, 42);
250 1 : one_test_3 ("%*.*o", 10, 7, 42);
251 1 : one_test_3 ("%*.*o", 10, -7, 42);
252 1 : one_test_3 ("%*.*o", -10, 7, 42);
253 1 : one_test_3 ("%*.*o", -10, -7, 42);
254 1 : one_test_2 ("%#*o", 7, 42);
255 1 : one_test_2 ("%#*o", -7, 42);
256 1 : one_test_2 ("%#.*o", 7, 42);
257 1 : one_test_2 ("%#.*o", -7, 42);
258 1 : one_test_3 ("%#*.*o", 10, 7, 42);
259 1 : one_test_3 ("%#*.*o", 10, -7, 42);
260 1 : one_test_3 ("%#*.*o", -10, 7, 42);
261 1 : one_test_3 ("%#*.*o", -10, -7, 42);
262 :
263 1 : one_test_1 ("%s", "the quick brown fox jumps over the lazy dogs back");
264 1 : one_test_1 ("%.0s", "the quick brown fox jumps over the lazy dogs back");
265 1 : one_test_1 ("%.10s", "the quick brown fox jumps over the lazy dogs back");
266 1 : one_test_1 ("%.48s", "the quick brown fox jumps over the lazy dogs back");
267 1 : one_test_1 ("%.49s", "the quick brown fox jumps over the lazy dogs back");
268 1 : one_test_1 ("%.50s", "the quick brown fox jumps over the lazy dogs back");
269 1 : one_test_1 ("%.51s", "the quick brown fox jumps over the lazy dogs back");
270 1 : one_test_1 ("%48s", "the quick brown fox jumps over the lazy dogs back");
271 1 : one_test_1 ("%49s", "the quick brown fox jumps over the lazy dogs back");
272 1 : one_test_1 ("%50s", "the quick brown fox jumps over the lazy dogs back");
273 1 : one_test_1 ("%51s", "the quick brown fox jumps over the lazy dogs back");
274 1 : one_test_1 ("%-51s", "the quick brown fox jumps over the lazy dogs back");
275 :
276 1 : one_test_1 ("/%s=", "CN");
277 :
278 1 : one_test_1 ("%f", 3.1415926535);
279 1 : one_test_1 ("%f", -3.1415926535);
280 1 : one_test_1 ("%.10f", 3.1415926535);
281 1 : one_test_1 ("%.2f", 3.1415926535);
282 1 : one_test_1 ("%.1f", 3.1415926535);
283 1 : one_test_1 ("%.0f", 3.1415926535);
284 1 : one_test_1 ("%.20f", 3.1415926535);
285 1 : one_test_1 ("%10.10f", 3.1415926535);
286 1 : one_test_1 ("%10.2f", 3.1415926535);
287 1 : one_test_1 ("%10.1f", 3.1415926535);
288 1 : one_test_1 ("%10.0f", 3.1415926535);
289 1 : one_test_1 ("%30.20f", 3.1415926535);
290 1 : one_test_1 ("%10.10f", -3.1415926535);
291 1 : one_test_1 ("%10.2f", -3.1415926535);
292 1 : one_test_1 ("%10.1f", -3.1415926535);
293 1 : one_test_1 ("%10.0f", -3.1415926535);
294 1 : one_test_1 ("%30.20f", -3.1415926535);
295 :
296 1 : one_test_1 ("%-10f", 3.1415926535);
297 1 : one_test_1 ("%-10.10f", 3.1415926535);
298 1 : one_test_1 ("%-10.2f", 3.1415926535);
299 1 : one_test_1 ("%-10.1f", 3.1415926535);
300 1 : one_test_1 ("%-10.0f", 3.1415926535);
301 1 : one_test_1 ("%-30.20f", 3.1415926535);
302 1 : one_test_1 ("%-10f", -3.1415926535);
303 1 : one_test_1 ("%-10.10f", -3.1415926535);
304 1 : one_test_1 ("%-10.2f", -3.1415926535);
305 1 : one_test_1 ("%-10.1f", -3.1415926535);
306 1 : one_test_1 ("%-10.0f", -3.1415926535);
307 1 : one_test_1 ("%-30.20f", -3.1415926535);
308 :
309 1 : one_test_1 ("%#.0f", 3.1415926535);
310 1 : one_test_1 ("%#10.0f", 3.1415926535);
311 1 : one_test_1 ("%#10.0f", -3.1415926535);
312 1 : one_test_1 ("%-#10.0f", 3.1415926535);
313 1 : one_test_1 ("%-#10.0f", -3.1415926535);
314 :
315 1 : one_test_1 ("%e", 3.1415926535);
316 1 : one_test_1 ("%g", 3.1415926535);
317 :
318 1 : one_test_1 ("%a", 1.0);
319 1 : one_test_1 ("%a", -1.0);
320 1 : one_test_1 ("%a", 3.1415926535);
321 :
322 : #ifdef HAVE_LONG_DOUBLE
323 1 : one_test_1 ("%La", (long double)1.0);
324 1 : one_test_1 ("%La", (long double)-1.0);
325 1 : one_test_1 ("%La", (long double)3.1415926535);
326 : #endif
327 :
328 : #ifdef __GLIBC__
329 : /* "%m" is a glibc extension so this _test_ will only work on such a
330 : system. */
331 1 : one_test_0 ("%m");
332 1 : one_test_1 ("%d=%m", 17);
333 1 : one_test_2 ("%2$d:%m:%1$d", 42, 17);
334 : #endif /*__GLIBC__*/
335 :
336 : #endif /*HAVE_VASPRINTF */
337 1 : }
338 :
339 : static void
340 1 : check_snprintf (void)
341 : {
342 : char buffer[20];
343 : int rc, rc2;
344 : size_t tmplen, blen, blen2;
345 :
346 1 : rc = gpgrt_snprintf (buffer, 0, "%*s", 18, "");
347 1 : if (rc != 18)
348 0 : printf ("rc=%d\n", rc );
349 1 : rc = gpgrt_snprintf (buffer, sizeof buffer, "%*s", 18, "");
350 1 : if (rc != 18)
351 0 : printf ("rc=%d, strlen(buffer)=%d\n", rc, (int)strlen (buffer));
352 1 : rc = gpgrt_snprintf (buffer, sizeof buffer, "%*s", 19, "");
353 1 : if (rc != 19)
354 0 : printf ("rc=%d, strlen(buffer)=%d\n", rc, (int)strlen (buffer));
355 1 : rc = gpgrt_snprintf (buffer, sizeof buffer, "%*s", 20, "");
356 1 : if (rc != 20)
357 0 : printf ("rc=%d, strlen(buffer)=%d\n", rc, (int)strlen (buffer));
358 1 : rc = gpgrt_snprintf (buffer, sizeof buffer, "%*s", 21, "");
359 1 : if (rc != 21)
360 0 : printf ("rc=%d, strlen(buffer)=%d\n", rc, (int)strlen (buffer));
361 :
362 21 : for (tmplen = 0; tmplen <= sizeof buffer; tmplen++)
363 : {
364 21 : rc = gpgrt_snprintf (buffer, tmplen, "%04d%02d%02dT%02d%02d%02d",
365 : 1998, 9, 7, 16, 56, 05);
366 21 : blen = strlen (buffer);
367 21 : rc2 = snprintf (buffer, tmplen, "%04d%02d%02dT%02d%02d%02d",
368 : 1998, 9, 7, 16, 56, 05);
369 21 : blen2 = strlen (buffer);
370 21 : if (rc != rc2 || blen != blen2)
371 0 : printf ("snprintf test with len %u gives %d instead of %d (%u,%u)\n",
372 : (unsigned int)tmplen, rc, rc2,
373 : (unsigned int)blen, (unsigned int)blen2);
374 : }
375 1 : }
376 :
377 :
378 :
379 : int
380 1 : main (int argc, char **argv)
381 : {
382 : int last_argc = -1;
383 :
384 1 : if (argc)
385 : {
386 1 : argc--; argv++;
387 : }
388 1 : while (argc && last_argc != argc )
389 : {
390 : last_argc = argc;
391 0 : if (!strcmp (*argv, "--help"))
392 : {
393 0 : puts (
394 : "usage: ./" PGM " [options]\n"
395 : "\n"
396 : "Options:\n"
397 : " --verbose Show what is going on\n"
398 : " --debug Flyswatter\n"
399 : );
400 0 : exit (0);
401 : }
402 0 : if (!strcmp (*argv, "--verbose"))
403 : {
404 0 : verbose = 1;
405 0 : argc--; argv++;
406 : }
407 0 : else if (!strcmp (*argv, "--debug"))
408 : {
409 0 : verbose = debug = 1;
410 0 : argc--; argv++;
411 : }
412 : }
413 :
414 1 : setlocale (LC_NUMERIC, "");
415 1 : if (!gpg_error_check_version (GPG_ERROR_VERSION))
416 : {
417 0 : die ("gpg_error_check_version returned an error");
418 : errorcount++;
419 : }
420 :
421 1 : run_tests ();
422 1 : check_snprintf ();
423 :
424 : #ifdef __GLIBC__
425 1 : return !!errorcount;
426 : #else
427 : return 0;
428 : #endif
429 : }
|