1 /*************************************************************************
2 * Regression test
3 */
4
5 #include "triodef.h"
6 #if defined(TRIO_COMPILER_ANCIENT)
7 # include <varargs.h>
8 #else
9 # include <stdarg.h>
10 #endif
11 #include <math.h>
12 #include <limits.h>
13 #include <float.h>
14 #include <errno.h>
15
16 #include "trio.h"
17 #include "triop.h"
18 #if defined(TRIO_EMBED_NAN)
19 # define TRIO_PUBLIC_NAN static
20 # define TRIO_FUNC_NINF
21 # define TRIO_FUNC_PINF
22 # define TRIO_FUNC_NAN
23 # define TRIO_FUNC_ISINF
24 # define TRIO_FUNC_ISNAN
25 # if TRIO_FEATURE_FLOAT
26 # define TRIO_FUNC_NZERO
27 # endif
28 #endif
29 #include "trionan.h"
30 #if defined(TRIO_EMBED_STRING)
31 # define TRIO_PUBLIC_STRING static
32 # define TRIO_FUNC_EQUAL_CASE
33 #endif
34 #include "triostr.h"
35 #undef printf
36
37 #if TRIO_FEATURE_WIDECHAR
38 # include <wchar.h>
39 #endif
40
41 #define QUOTE(x) #x
42
43 #define DOUBLE_EQUAL(x,y) (((x)>(y)-DBL_EPSILON) && ((x)<(y)+DBL_EPSILON))
44 #define FLOAT_EQUAL(x,y) (((x)>(y)-FLT_EPSILON) && ((x)<(y)+FLT_EPSILON))
45
46 static TRIO_CONST char rcsid[] = "@(#)$Id: regression.c,v 1.67 2010/01/26 13:02:02 breese Exp $";
47
48 #if defined(TRIO_EMBED_NAN)
49 # include "trionan.c"
50 #endif
51 #if defined(TRIO_EMBED_STRING)
52 # include "triostr.c"
53 #endif
54
55 /*************************************************************************
56 *
57 */
58 static void
59 Dump
60 TRIO_ARGS2((buffer, rc),
61 char *buffer,
62 int rc)
63 {
64 if (rc < 0)
65 {
66 printf("Err = %d (%s), Pos = %d\n",
67 TRIO_ERROR_CODE(rc),
68 TRIO_ERROR_NAME(rc),
69 TRIO_ERROR_POSITION(rc));
70 }
71 else if (buffer)
72 printf("buffer[% 3d] = \"%s\"\n", rc, buffer);
73 }
74
75 /*************************************************************************
76 *
77 */
78 static void
79 Report0
80 TRIO_ARGS2((file, line),
81 TRIO_CONST char *file,
82 int line)
83 {
84 printf("Verification failed in %s:%d.\n", file, line);
85 }
86
87 /*************************************************************************
88 *
89 */
90 static void
91 Report
92 TRIO_ARGS4((file, line, expected, got),
93 TRIO_CONST char *file,
94 int line,
95 TRIO_CONST char *expected,
96 TRIO_CONST char *got)
97 {
98 Report0(file, line);
99 printf(" Expected \"%s\"\n", expected);
100 printf(" Got \"%s\"\n", got);
101 }
102
103 /*************************************************************************
104 *
105 */
106 int
107 Verify
108 TRIO_VARGS5((file, line, result, fmt, va_alist),
109 TRIO_CONST char *file,
110 int line,
111 TRIO_CONST char *result,
112 TRIO_CONST char *fmt,
113 TRIO_VA_DECL)
114 {
115 int rc;
116 va_list args;
117 char buffer[4096];
118
119 TRIO_VA_START(args, fmt);
120 rc = trio_vsnprintf(buffer, sizeof(buffer), fmt, args);
121 if (rc < 0)
122 Dump(buffer, rc);
123 TRIO_VA_END(args);
124
125 if (!trio_equal_case(result, buffer))
126 {
127 Report(file, line, result, buffer);
128 return 1;
129 }
130 return 0;
131 }
132
133 /*************************************************************************
134 *
135 */
136 int
VerifyReturnValues(TRIO_NOARGS)137 VerifyReturnValues(TRIO_NOARGS)
138 {
139 int nerrors = 0;
140 int rc;
141 int count;
142 char *expected;
143 char buffer[4096];
144 char result[4096];
145
146 rc = trio_sprintf(buffer, "%s%n", "0123456789", &count);
147 trio_sprintf(result, "%d %d %s", rc, count, buffer);
148 expected = "10 10 0123456789";
149 if (!trio_equal_case(result, expected))
150 {
151 nerrors++;
152 Report(__FILE__, __LINE__, expected, result);
153 }
154
155 rc = trio_snprintf(buffer, sizeof(buffer), "%s%n", "0123456789", &count);
156 trio_sprintf(result, "%d %d %s", rc, count, buffer);
157 expected = "10 10 0123456789";
158 if (!trio_equal_case(result, expected))
159 {
160 nerrors++;
161 Report(__FILE__, __LINE__, expected, result);
162 }
163
164 rc = trio_snprintf(buffer, 4, "%s%n", "0123456789", &count);
165 trio_sprintf(result, "%d %d %s", rc, count, buffer);
166 expected = "10 3 012";
167 if (!trio_equal_case(result, expected))
168 {
169 nerrors++;
170 Report(__FILE__, __LINE__, expected, result);
171 }
172
173 /* The output buffer contains the empty string */
174 rc = trio_snprintf(buffer, 1, "%s%n", "0123456789", &count);
175 trio_sprintf(result, "%d %d %s", rc, count, buffer);
176 expected = "10 0 ";
177 if (!trio_equal_case(result, expected))
178 {
179 nerrors++;
180 Report(__FILE__, __LINE__, expected, result);
181 }
182
183 /* The output buffer should be left untouched when max size is 0 */
184 trio_sprintf(buffer, "DO NOT TOUCH");
185 rc = trio_snprintf(buffer, 0, "%s%n", "0123456789", &count);
186 trio_sprintf(result, "%d %d %s", rc, count, buffer);
187 expected = "10 0 DO NOT TOUCH";
188 if (!trio_equal_case(result, expected))
189 {
190 nerrors++;
191 Report(__FILE__, __LINE__, expected, result);
192 }
193
194 return nerrors;
195 }
196
197 /*************************************************************************
198 *
199 */
200 #define TEST_STRING "0123456789"
201
202 int
VerifyAllocate(TRIO_NOARGS)203 VerifyAllocate(TRIO_NOARGS)
204 {
205 int nerrors = 0;
206 #if TRIO_FEATURE_DYNAMICSTRING
207 int rc;
208 char *string;
209 int count;
210 int test_size = sizeof(TEST_STRING) - 1;
211
212 /* Allocate a string with the result */
213 rc = trio_asprintf(&string, "%s%n", TEST_STRING, &count);
214 if (rc < 0)
215 {
216 nerrors++;
217 Dump(string, rc);
218 }
219 else if (count != test_size)
220 {
221 nerrors++;
222 printf("Validation failed in %s:%d\n", __FILE__, __LINE__);
223 printf(" Expected %%n = %d\n", test_size);
224 printf(" Got %%n = %d\n", count);
225 }
226 else if (!trio_equal_case(string, TEST_STRING))
227 {
228 nerrors++;
229 Report(__FILE__, __LINE__, TEST_STRING, string);
230 }
231 if (string)
232 free(string);
233 #endif
234
235 return nerrors;
236 }
237
238
239 /*************************************************************************
240 *
241 */
242 int
VerifyFormattingStrings(TRIO_NOARGS)243 VerifyFormattingStrings(TRIO_NOARGS)
244 {
245 int nerrors = 0;
246
247 /* Normal text */
248 nerrors += Verify(__FILE__, __LINE__, "Hello world",
249 "Hello world");
250 /* String */
251 nerrors += Verify(__FILE__, __LINE__, "Hello world",
252 "%s", "Hello world");
253
254 return nerrors;
255 }
256
257 /*************************************************************************
258 *
259 */
260 int
VerifyFormattingIntegers(TRIO_NOARGS)261 VerifyFormattingIntegers(TRIO_NOARGS)
262 {
263 int nerrors = 0;
264 char buffer[256];
265
266 /* Integer */
267 nerrors += Verify(__FILE__, __LINE__, "Number 42",
268 "Number %d", 42);
269 nerrors += Verify(__FILE__, __LINE__, "Number -42",
270 "Number %d", -42);
271 nerrors += Verify(__FILE__, __LINE__, "Number 42",
272 "Number %ld", 42L);
273 nerrors += Verify(__FILE__, __LINE__, "Number -42",
274 "Number %ld", -42L);
275 /* Integer width */
276 nerrors += Verify(__FILE__, __LINE__, " 1234",
277 "%6d", 1234);
278 nerrors += Verify(__FILE__, __LINE__, " 1234",
279 "%*d", 6, 1234);
280 /* Integer width overrun */
281 nerrors += Verify(__FILE__, __LINE__, "123456",
282 "%4d", 123456);
283 /* Integer precision */
284 nerrors += Verify(__FILE__, __LINE__, "0012",
285 "%.4d", 12);
286 nerrors += Verify(__FILE__, __LINE__, "0012",
287 "%.*d", 4, 12);
288 nerrors += Verify(__FILE__, __LINE__, " 0012",
289 "%6.*d", 4, 12);
290 nerrors += Verify(__FILE__, __LINE__, " 0012",
291 "%*.*d", 6, 4, 12);
292 nerrors += Verify(__FILE__, __LINE__, " 0012",
293 "%*.*.*d", 6, 4, 2, 12);
294 nerrors += Verify(__FILE__, __LINE__, " 0012",
295 "%*.*.*i", 6, 4, 10, 12);
296 /* Integer sign, zero-padding, and width */
297 nerrors += Verify(__FILE__, __LINE__, "+01234",
298 "%+06d", 1234);
299 nerrors += Verify(__FILE__, __LINE__, " 01234",
300 "% 06d", 1234);
301 nerrors += Verify(__FILE__, __LINE__, "+01234",
302 "% +06d", 1234);
303 /* Integer adjust, zero-padding, and width */
304 nerrors += Verify(__FILE__, __LINE__, "12 ",
305 "%-08d", 12);
306 /* Integer zero-padding, width, and precision */
307 nerrors += Verify(__FILE__, __LINE__, " 000012",
308 "%08.6d", 12);
309 /* Integer base */
310 nerrors += Verify(__FILE__, __LINE__, "42",
311 "%u", 42);
312 nerrors += Verify(__FILE__, __LINE__, "-1",
313 "%d", -1);
314 nerrors += Verify(__FILE__, __LINE__, "52",
315 "%o", 42);
316 nerrors += Verify(__FILE__, __LINE__, "052",
317 "%#o", 42);
318 nerrors += Verify(__FILE__, __LINE__, "0",
319 "%#o", 0);
320 nerrors += Verify(__FILE__, __LINE__, "2a",
321 "%x", 42);
322 nerrors += Verify(__FILE__, __LINE__, "2A",
323 "%X", 42);
324 nerrors += Verify(__FILE__, __LINE__, "0x2a",
325 "%#x", 42);
326 nerrors += Verify(__FILE__, __LINE__, "0X2A",
327 "%#X", 42);
328 nerrors += Verify(__FILE__, __LINE__, "0x00c ",
329 "%-#6.3x", 12);
330 nerrors += Verify(__FILE__, __LINE__, "",
331 "%.d", 0);
332 nerrors += Verify(__FILE__, __LINE__, "",
333 "%#.d", 0);
334 nerrors += Verify(__FILE__, __LINE__, "42",
335 "%.d", 42);
336 nerrors += Verify(__FILE__, __LINE__, "",
337 "%.o", 0);
338 nerrors += Verify(__FILE__, __LINE__, " 0000",
339 "%8.4o", 0);
340 nerrors += Verify(__FILE__, __LINE__, " 0",
341 "%8o", 0);
342 nerrors += Verify(__FILE__, __LINE__, "00000000",
343 "%08o", 0);
344 nerrors += Verify(__FILE__, __LINE__, "0",
345 "%#.o", 0);
346 nerrors += Verify(__FILE__, __LINE__, "52",
347 "%.o", 42);
348 nerrors += Verify(__FILE__, __LINE__, "",
349 "%.x", 0);
350 nerrors += Verify(__FILE__, __LINE__, "",
351 "%#.x", 0);
352 nerrors += Verify(__FILE__, __LINE__, "2a",
353 "%.x", 42);
354 sprintf(buffer, "%u", UINT_MAX);
355 nerrors += Verify(__FILE__, __LINE__, buffer,
356 "%u", -1);
357 sprintf(buffer, "%x", UINT_MAX);
358 nerrors += Verify(__FILE__, __LINE__, buffer,
359 "%x", -1);
360
361 return nerrors;
362 }
363
364 /*************************************************************************
365 *
366 */
367 int
VerifyFormattingFloats(TRIO_NOARGS)368 VerifyFormattingFloats(TRIO_NOARGS)
369 {
370 int nerrors = 0;
371
372 #if TRIO_FEATURE_FLOAT
373 /* Double */
374 nerrors += Verify(__FILE__, __LINE__, "3141.000000",
375 "%f", 3141.0);
376 nerrors += Verify(__FILE__, __LINE__, "3141.500000",
377 "%f", 3141.5);
378 nerrors += Verify(__FILE__, __LINE__, "3.141000e+03",
379 "%e", 3141.0);
380 nerrors += Verify(__FILE__, __LINE__, " -2.3420e-02",
381 "%16.4e", -2.342E-02);
382 nerrors += Verify(__FILE__, __LINE__, " -2.3420e-22",
383 "%16.4e", -2.342E-22);
384 nerrors += Verify(__FILE__, __LINE__, " 2.3420e-02",
385 "% 16.4e", 2.342E-02);
386 nerrors += Verify(__FILE__, __LINE__, " 2.3420e-02",
387 "% 1.4e", 2.342E-02);
388 nerrors += Verify(__FILE__, __LINE__, "3.141000E-44",
389 "%E", 3.141e-44);
390 nerrors += Verify(__FILE__, __LINE__, "0",
391 "%g", 0.0);
392 nerrors += Verify(__FILE__, __LINE__, "-0",
393 "%g", trio_nzero());
394 nerrors += Verify(__FILE__, __LINE__, "3141.5",
395 "%g", 3141.5);
396 nerrors += Verify(__FILE__, __LINE__, "3.1415E-06",
397 "%G", 3.1415e-6);
398 nerrors += Verify(__FILE__, __LINE__, "+3141.000000",
399 "%+f", 3141.0);
400 nerrors += Verify(__FILE__, __LINE__, "-3141.000000",
401 "%+f", -3141.0);
402 nerrors += Verify(__FILE__, __LINE__, "0.333333",
403 "%f", 1.0/3.0);
404 nerrors += Verify(__FILE__, __LINE__, "0.666667",
405 "%f", 2.0/3.0);
406 /* Beyond accuracy */
407 nerrors += Verify(__FILE__, __LINE__, "0.000000",
408 "%f", 1.234567890123456789e-20);
409 # if defined(TRIO_BREESE)
410 nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580299875",
411 "%.32g", 1.4);
412 nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991118215802998748",
413 "%.32f", 1.4);
414 nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580300",
415 "%.28f", 1.4);
416 nerrors += Verify(__FILE__, __LINE__, "1.399999999999999911182158",
417 "%.24f", 1.4);
418 nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991",
419 "%.17f", 1.4);
420 nerrors += Verify(__FILE__, __LINE__, "1.40000000000000",
421 "%.14f", 1.4);
422 nerrors += Verify(__FILE__, __LINE__, "39413.800000000002910383045673370361",
423 "%.30f", 39413.80);
424 # endif
425 /* 2^-1 + 2^-15 */
426 nerrors += Verify(__FILE__, __LINE__, "0.500030517578125",
427 "%.*g", DBL_DIG + 10, 0.500030517578125);
428 /* Double decimal point */
429 nerrors += Verify(__FILE__, __LINE__, "3141",
430 "%.0f", 3141.0);
431 nerrors += Verify(__FILE__, __LINE__, "3142",
432 "%.0f", 3141.5);
433 nerrors += Verify(__FILE__, __LINE__, "3141",
434 "%.f", 3141.0);
435 nerrors += Verify(__FILE__, __LINE__, "12",
436 "%.f", 12.34);
437 nerrors += Verify(__FILE__, __LINE__, "3141.000",
438 "%.3f", 3141.0);
439 nerrors += Verify(__FILE__, __LINE__, "3141.000000",
440 "%#f", 3141.0);
441 nerrors += Verify(__FILE__, __LINE__, "0.0000",
442 "%#.4f", 0.0);
443 nerrors += Verify(__FILE__, __LINE__, "0.000",
444 "%#.4g", 0.0);
445 nerrors += Verify(__FILE__, __LINE__, "0.001000",
446 "%#.4g", 1e-3);
447 nerrors += Verify(__FILE__, __LINE__, "3141.0000",
448 "%#.4f", 3141.0);
449 nerrors += Verify(__FILE__, __LINE__, "3141.",
450 "%#.0f", 3141.0);
451 nerrors += Verify(__FILE__, __LINE__, "3141.",
452 "%#.f", 3141.0);
453 nerrors += Verify(__FILE__, __LINE__, "11.0000",
454 "%#.4f", 11.0);
455 nerrors += Verify(__FILE__, __LINE__, "100.00",
456 "%.2f", 99.9999);
457 nerrors += Verify(__FILE__, __LINE__, "3e+03",
458 "%.e", 3141.0);
459 nerrors += Verify(__FILE__, __LINE__, "3.e+03",
460 "%#.e", 3141.0);
461 nerrors += Verify(__FILE__, __LINE__, "1.23457e+06",
462 "%g", 1234567.0);
463 nerrors += Verify(__FILE__, __LINE__, "1e+02",
464 "%.2g", 99.9999);
465 nerrors += Verify(__FILE__, __LINE__, "1.0e+02",
466 "%#.2g", 99.9999);
467 nerrors += Verify(__FILE__, __LINE__, "0.123",
468 "%0g", 0.123);
469 nerrors += Verify(__FILE__, __LINE__, "1.00e+00",
470 "%.2e", 0.9999);
471 nerrors += Verify(__FILE__, __LINE__, "1",
472 "%.2g", 0.9999);
473 nerrors += Verify(__FILE__, __LINE__, "2",
474 "%.0g", 1.5);
475 nerrors += Verify(__FILE__, __LINE__, "2",
476 "%.g", 1.5);
477 nerrors += Verify(__FILE__, __LINE__, "0.01",
478 "%.2g", 0.01);
479 nerrors += Verify(__FILE__, __LINE__, "0.010",
480 "%#.2g", 0.01);
481 nerrors += Verify(__FILE__, __LINE__, "1e-04",
482 "%5.g", 0.999999e-4);
483 /* Double width and precision */
484 nerrors += Verify(__FILE__, __LINE__, " 1e-05",
485 "%11.5g", 1e-5);
486 nerrors += Verify(__FILE__, __LINE__, " 0.0001",
487 "%11.5g", 1e-4);
488 nerrors += Verify(__FILE__, __LINE__, " 0.001",
489 "%11.5g", 1e-3);
490 nerrors += Verify(__FILE__, __LINE__, " 0.01",
491 "%11.5g", 1e-2);
492 nerrors += Verify(__FILE__, __LINE__, " 0.1",
493 "%11.5g", 1e-1);
494 nerrors += Verify(__FILE__, __LINE__, " 1",
495 "%11.5g", 1e0);
496 nerrors += Verify(__FILE__, __LINE__, " 10",
497 "%11.5g", 1e1);
498 nerrors += Verify(__FILE__, __LINE__, " 100",
499 "%11.5g", 1e2);
500 nerrors += Verify(__FILE__, __LINE__, " 1000",
501 "%11.5g", 1e3);
502 nerrors += Verify(__FILE__, __LINE__, " 10000",
503 "%11.5g", 1e4);
504 nerrors += Verify(__FILE__, __LINE__, " 1e+05",
505 "%11.5g", 1e5);
506 nerrors += Verify(__FILE__, __LINE__, " 9.9e-05",
507 "%11.2g", 0.99e-4);
508 nerrors += Verify(__FILE__, __LINE__, " 0.00099",
509 "%11.2g", 0.99e-3);
510 nerrors += Verify(__FILE__, __LINE__, " 0.0099",
511 "%11.2g", 0.99e-2);
512 nerrors += Verify(__FILE__, __LINE__, " 0.099",
513 "%11.2g", 0.99e-1);
514 nerrors += Verify(__FILE__, __LINE__, " 0.99",
515 "%11.2g", 0.99e0);
516 nerrors += Verify(__FILE__, __LINE__, " 9.9",
517 "%11.2g", 0.99e1);
518 nerrors += Verify(__FILE__, __LINE__, " 99",
519 "%11.2g", 0.99e2);
520 nerrors += Verify(__FILE__, __LINE__, " 9.9e+02",
521 "%11.2g", 0.99e3);
522 nerrors += Verify(__FILE__, __LINE__, " 9.9e+03",
523 "%11.2g", 0.99e4);
524 nerrors += Verify(__FILE__, __LINE__, " 9.9e+04",
525 "%11.2g", 0.99e5);
526 /* Double width, precision, and alternative */
527 nerrors += Verify(__FILE__, __LINE__, " 1.0000e-05",
528 "%#11.5g", 1e-5);
529 nerrors += Verify(__FILE__, __LINE__, " 0.00010000",
530 "%#11.5g", 1e-4);
531 nerrors += Verify(__FILE__, __LINE__, " 0.0010000",
532 "%#11.5g", 1e-3);
533 nerrors += Verify(__FILE__, __LINE__, " 0.0010000",
534 "%#11.5g", 0.999999e-3);
535 nerrors += Verify(__FILE__, __LINE__, " 0.010000",
536 "%#11.5g", 1e-2);
537 nerrors += Verify(__FILE__, __LINE__, " 0.010000",
538 "%#11.5g", 0.999999e-2);
539 nerrors += Verify(__FILE__, __LINE__, " 0.10000",
540 "%#11.5g", 1e-1);
541 nerrors += Verify(__FILE__, __LINE__, " 0.10000",
542 "%#11.5g", 0.999999e-1);
543 nerrors += Verify(__FILE__, __LINE__, " 1.0000",
544 "%#11.5g", 1e0);
545 nerrors += Verify(__FILE__, __LINE__, " 1.0000",
546 "%#11.5g", 0.999999e0);
547 nerrors += Verify(__FILE__, __LINE__, " 10.000",
548 "%#11.5g", 1e1);
549 nerrors += Verify(__FILE__, __LINE__, " 100.00",
550 "%#11.5g", 1e2);
551 nerrors += Verify(__FILE__, __LINE__, " 1000.0",
552 "%#11.5g", 1e3);
553 nerrors += Verify(__FILE__, __LINE__, " 10000.",
554 "%#11.5g", 1e4);
555 nerrors += Verify(__FILE__, __LINE__, " 1.0000e+05",
556 "%#11.5g", 1e5);
557 nerrors += Verify(__FILE__, __LINE__, " 9.9e-05",
558 "%#11.2g", 0.99e-4);
559 nerrors += Verify(__FILE__, __LINE__, " 0.00099",
560 "%#11.2g", 0.99e-3);
561 nerrors += Verify(__FILE__, __LINE__, " 0.0099",
562 "%#11.2g", 0.99e-2);
563 nerrors += Verify(__FILE__, __LINE__, " 0.099",
564 "%#11.2g", 0.99e-1);
565 nerrors += Verify(__FILE__, __LINE__, " 0.99",
566 "%#11.2g", 0.99e0);
567 nerrors += Verify(__FILE__, __LINE__, " 9.9",
568 "%#11.2g", 0.99e1);
569 nerrors += Verify(__FILE__, __LINE__, " 99.",
570 "%#11.2g", 0.99e2);
571 nerrors += Verify(__FILE__, __LINE__, " 9.9e+02",
572 "%#11.2g", 0.99e3);
573 nerrors += Verify(__FILE__, __LINE__, " 9.9e+03",
574 "%#11.2g", 0.99e4);
575 nerrors += Verify(__FILE__, __LINE__, " 9.9e+04",
576 "%#11.2g", 0.99e5);
577 /* Double width, precision, and zero padding */
578 nerrors += Verify(__FILE__, __LINE__, "00003.141500e+03",
579 "%016e", 3141.5);
580 nerrors += Verify(__FILE__, __LINE__, " 3.141500e+03",
581 "%16e", 3141.5);
582 nerrors += Verify(__FILE__, __LINE__, "3.141500e+03 ",
583 "%-16e", 3141.5);
584 nerrors += Verify(__FILE__, __LINE__, "03.142e+03",
585 "%010.3e", 3141.5);
586 #if !defined(TRIO_COMPILER_ANCIENT)
587 /* Long double */
588 nerrors += Verify(__FILE__, __LINE__, "1.400000",
589 "%Lf", 1.4L);
590 #endif
591
592 /* Special cases */
593 nerrors += Verify(__FILE__, __LINE__, "1.00",
594 "%.2f", 0.999);
595 nerrors += Verify(__FILE__, __LINE__, "100",
596 "%.0f", 99.9);
597 nerrors += Verify(__FILE__, __LINE__, "inf",
598 "%f", trio_pinf());
599 nerrors += Verify(__FILE__, __LINE__, "-inf",
600 "%f", trio_ninf());
601 nerrors += Verify(__FILE__, __LINE__, "INF",
602 "%F", trio_pinf());
603 nerrors += Verify(__FILE__, __LINE__, "-INF",
604 "%F", trio_ninf());
605 /* May fail if NaN is unsupported */
606 nerrors += Verify(__FILE__, __LINE__, "nan",
607 "%f", trio_nan());
608 nerrors += Verify(__FILE__, __LINE__, "NAN",
609 "%F", trio_nan());
610
611 # if TRIO_FEATURE_HEXFLOAT
612 nerrors += Verify(__FILE__, __LINE__, "0x2.ap+4",
613 "%a", 42.0);
614 nerrors += Verify(__FILE__, __LINE__, "-0x2.ap+4",
615 "%a", -42.0);
616 nerrors += Verify(__FILE__, __LINE__, "0x1.8p+0",
617 "%a", 1.5);
618 nerrors += Verify(__FILE__, __LINE__, "0x1.6666666666666p+0",
619 "%a", 1.4);
620 nerrors += Verify(__FILE__, __LINE__, "0xc.45p+8",
621 "%a", 3141.0);
622 nerrors += Verify(__FILE__, __LINE__, "0XC.45P+8",
623 "%A", 3141.0);
624 nerrors += Verify(__FILE__, __LINE__, "0xb.351c434a98fa8p-148",
625 "%a", 3.141e-44);
626 # endif
627
628 #endif /* TRIO_FEATURE_FLOAT */
629
630 return nerrors;
631 }
632
633 /*************************************************************************
634 *
635 */
636 #if TRIO_EXTENSION
number_writer(void * ref)637 int number_writer(void *ref)
638 {
639 const char *format;
640 int *data;
641
642 format = trio_get_format(ref);
643 if ((format) && trio_equal(format, "integer"))
644 {
645 data = trio_get_argument(ref);
646 if (data)
647 {
648 trio_print_int(ref, *data);
649 }
650 }
651 return 0;
652 }
653
654 #endif
655
656 int
VerifyFormattingUserDefined(TRIO_NOARGS)657 VerifyFormattingUserDefined(TRIO_NOARGS)
658 {
659 int nerrors = 0;
660 #if TRIO_EXTENSION
661 void *number_handle;
662 int integer = 123;
663
664 number_handle = trio_register(number_writer, "number");
665
666 /* Old style */
667 nerrors += Verify(__FILE__, __LINE__, "123",
668 "%<number:integer>", &integer);
669
670 /* New style */
671 nerrors += Verify(__FILE__, __LINE__, "123",
672 "$<number:integer|%p>", &integer);
673 nerrors += Verify(__FILE__, __LINE__, "123",
674 "$<integer|%p%p>", number_handle, &integer);
675 nerrors += Verify(__FILE__, __LINE__, "$<integer|123",
676 "$<integer|%d", 123);
677 nerrors += Verify(__FILE__, __LINE__, "$integer|123>",
678 "$integer|%d>", 123);
679
680 trio_unregister(number_handle);
681 #endif
682
683 return nerrors;
684 }
685
686 /*************************************************************************
687 *
688 */
689 int
VerifyFormattingRegression(TRIO_NOARGS)690 VerifyFormattingRegression(TRIO_NOARGS)
691 {
692 int nerrors = 0;
693
694 #if TRIO_FEATURE_FLOAT
695 /* 0.6 was formatted as 0.600000e+00 */
696 nerrors += Verify(__FILE__, __LINE__, "5.000000e-01",
697 "%e", 0.5);
698 nerrors += Verify(__FILE__, __LINE__, "6.000000e-01",
699 "%e", 0.6);
700 #endif
701
702 return nerrors;
703 }
704
705 /*************************************************************************
706 *
707 */
708 int
VerifyFormatting(TRIO_NOARGS)709 VerifyFormatting(TRIO_NOARGS)
710 {
711 int nerrors = 0;
712 #if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
713 char buffer[256];
714 #endif
715
716 nerrors += VerifyFormattingStrings();
717 nerrors += VerifyFormattingIntegers();
718 nerrors += VerifyFormattingFloats();
719 nerrors += VerifyFormattingRegression();
720 nerrors += VerifyFormattingUserDefined();
721
722 /* Pointer */
723 if (sizeof(void *) == 4)
724 {
725 nerrors += Verify(__FILE__, __LINE__, "Pointer 0x01234567",
726 "Pointer %p", 0x1234567);
727 }
728 #if defined(TRIO_COMPILER_SUPPORTS_LL)
729 else if (sizeof(void *) == 8)
730 {
731 nerrors += Verify(__FILE__, __LINE__, "Pointer 0x0123456789012345",
732 "Pointer %p", 0x123456789012345LL);
733 }
734 #endif
735 /* Nil pointer */
736 nerrors += Verify(__FILE__, __LINE__, "Pointer (nil)",
737 "Pointer %p", NULL);
738
739 /* Char width alignment */
740 nerrors += Verify(__FILE__, __LINE__, "Char X .",
741 "Char %-4c.", 'X');
742 /* String width / precision */
743 nerrors += Verify(__FILE__, __LINE__, " testing",
744 "%8s", "testing");
745 nerrors += Verify(__FILE__, __LINE__, "testing ",
746 "%-8s", "testing");
747 nerrors += Verify(__FILE__, __LINE__, " testing",
748 "%*s", 8, "testing");
749 nerrors += Verify(__FILE__, __LINE__, "testing ",
750 "%*s", -8, "testing");
751 nerrors += Verify(__FILE__, __LINE__, "test",
752 "%.4s", "testing");
753 nerrors += Verify(__FILE__, __LINE__, "test",
754 "%.*s", 4, "testing");
755 nerrors += Verify(__FILE__, __LINE__, "testing",
756 "%.*s", -4, "testing");
757 #if TRIO_FEATURE_POSITIONAL
758 /* Positional */
759 nerrors += Verify(__FILE__, __LINE__, "222 111",
760 "%2$s %1$s", "111", "222");
761 nerrors += Verify(__FILE__, __LINE__, "123456 12345 0001234 00123",
762 "%4$d %3$*8$d %2$.*7$d %1$*6$.*5$d",
763 123, 1234, 12345, 123456, 5, 6, 7, 8);
764 #endif
765
766 #if TRIO_FEATURE_SIZE_T_UPPER
767 nerrors += Verify(__FILE__, __LINE__, "256",
768 "%Zd", sizeof(buffer));
769 #endif
770
771 #if TRIO_FEATURE_ERRNO
772 errno = EINTR;
773 # if defined(TRIO_PLATFORM_LYNX)
774 # if defined(PREDEF_STANDARD_POSIX_1996)
775 nerrors += Verify(__FILE__, __LINE__, "Interrupted system call ",
776 "%m");
777 # else
778 nerrors += Verify(__FILE__, __LINE__, "System call interrupted",
779 "%m");
780 # endif
781 # else
782 nerrors += Verify(__FILE__, __LINE__, "Interrupted system call",
783 "%m");
784 # endif
785 #endif
786
787 #if TRIO_FEATURE_QUAD
788 # if defined(TRIO_COMPILER_SUPPORTS_LL)
789 /* This may fail if the preprocessor does not recognize LL */
790 nerrors += Verify(__FILE__, __LINE__, "42",
791 "%qd", 42LL);
792 # endif
793 #endif
794
795 #if TRIO_FEATURE_SIZE_T
796 nerrors += Verify(__FILE__, __LINE__, "256",
797 "%zd", sizeof(buffer));
798 #endif
799 #if TRIO_FEATURE_PTRDIFF_T
800 nerrors += Verify(__FILE__, __LINE__, "42",
801 "%td", 42);
802 #endif
803 #if TRIO_FEATURE_INTMAX_T
804 # if defined(TRIO_COMPILER_SUPPORTS_LL)
805 /* Some compilers may not handle the LL suffix correctly */
806 nerrors += Verify(__FILE__, __LINE__, "42",
807 "%jd", 42LL);
808 # endif
809 #endif
810
811 #if TRIO_FEATURE_WIDECHAR
812 nerrors += Verify(__FILE__, __LINE__, "Hello World",
813 "%ls", L"Hello World");
814 nerrors += Verify(__FILE__, __LINE__, "\\aHello World",
815 "%#ls", L"\aHello World");
816 nerrors += Verify(__FILE__, __LINE__, "A",
817 "%lc", L'A');
818 nerrors += Verify(__FILE__, __LINE__, "\\a",
819 "%#lc", L'\a');
820 #endif
821
822 #if TRIO_FEATURE_FIXED_SIZE
823 nerrors += Verify(__FILE__, __LINE__, "42",
824 "%I8d", 42);
825 nerrors += Verify(__FILE__, __LINE__, "ffffffff",
826 "%I16x", -1);
827 #endif
828
829 #if TRIO_EXTENSION
830 nerrors += Verify(__FILE__, __LINE__, " 42 86",
831 "%!4d %d", 42, 86);
832 nerrors += Verify(__FILE__, __LINE__, "0042 0086",
833 "%!04d %d", 42, 86);
834 nerrors += Verify(__FILE__, __LINE__, "42",
835 "%&d", sizeof(long), 42L);
836 /* Non-printable string */
837 nerrors += Verify(__FILE__, __LINE__, "NonPrintable \\x01 \\a \\\\",
838 "NonPrintable %#s", "\01 \07 \\");
839 nerrors += Verify(__FILE__, __LINE__, "\\a \\b \\t \\n \\v \\f \\r",
840 "%#s", "\007 \010 \011 \012 \013 \014 \015");
841 /* Quote flag */
842 nerrors += Verify(__FILE__, __LINE__, "Another \"quoted\" string",
843 "Another %'s string", "quoted");
844 /* Integer base */
845 nerrors += Verify(__FILE__, __LINE__, "Number 42 == 1120 (base 3)",
846 "Number %d == %..3i (base 3)", 42, 42);
847 /* Integer base (specifier base must be used instead of base modifier) */
848 nerrors += Verify(__FILE__, __LINE__, "42",
849 "%..3d", 42);
850 nerrors += Verify(__FILE__, __LINE__, "52",
851 "%..3o", 42);
852 nerrors += Verify(__FILE__, __LINE__, "2a",
853 "%..3x", 42);
854 /* Integer thousand separator */
855 nerrors += Verify(__FILE__, __LINE__, "Number 100",
856 "Number %'d", 100);
857 nerrors += Verify(__FILE__, __LINE__, "Number 1,000,000",
858 "Number %'d", 1000000);
859 # if TRIO_FEATURE_FLOAT
860 /* Float thousand separator */
861 nerrors += Verify(__FILE__, __LINE__, "31,415.200000",
862 "%'f", 31415.2);
863 nerrors += Verify(__FILE__, __LINE__, "1,000,000.000000",
864 "%'f", 1000000.0);
865 /* Rounding modifier */
866 nerrors += Verify(__FILE__, __LINE__, "1.4",
867 "%.32Rf", 1.4);
868 nerrors += Verify(__FILE__, __LINE__, "1.4",
869 "%.17Rf", 1.4);
870 nerrors += Verify(__FILE__, __LINE__, "39413.8",
871 "%.30Rf", 39413.80);
872 # if !defined(TRIO_COMPILER_ANCIENT)
873 /* Long double */
874 nerrors += Verify(__FILE__, __LINE__, "1.4",
875 "%RLf", 1.4L);
876 nerrors += Verify(__FILE__, __LINE__, "1.4",
877 "%.30RLf", 1.4L);
878 # endif
879 # endif
880 #endif
881
882 #if defined(TRIO_BREESE)
883 /*
884 * These results depends on issues beyond our control. For example,
885 * the accuracy of floating-point numbers depends on the underlying
886 * floating-point hardware (e.g. whether IEEE 754 double or extended-
887 * double format is used).
888 *
889 * These tests are therefore not part of the normal regression test,
890 * but we keep them here for development purposes.
891 */
892 nerrors += Verify(__FILE__, __LINE__, "123456789012345680868.000000",
893 "%f", 1.234567890123456789e20);
894 nerrors += Verify(__FILE__, __LINE__, "1.23456789012345677901e-20",
895 "%.20e", 1.2345678901234567e-20);
896 nerrors += Verify(__FILE__, __LINE__, "0.666666666666666629659233",
897 "%.*g", DBL_DIG + 10, 2.0/3.0);
898 nerrors += Verify(__FILE__, __LINE__, "123456789012345700000",
899 "%Rf", 1.234567890123456789e20);
900 # if !defined(TRIO_COMPILER_ANCIENT)
901 nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
902 "%RLf", (2.0L/3.0L));
903 nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
904 "%.30RLf", (2.0L/3.0L));
905 # endif
906 #endif
907
908 return nerrors;
909 }
910
911 /*************************************************************************
912 *
913 */
914 int
VerifyErrors(TRIO_NOARGS)915 VerifyErrors(TRIO_NOARGS)
916 {
917 char buffer[512];
918 int rc;
919 int nerrors = 0;
920
921 /* Error: Invalid argument 1 */
922 rc = trio_snprintf(buffer, sizeof(buffer), "%d %r", 42, "text");
923 #if TRIO_FEATURE_ERRORCODE
924 # if TRIO_FEATURE_STRERR
925 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
926 TRIO_ERROR_CODE(rc),
927 TRIO_ERROR_NAME(rc),
928 TRIO_ERROR_POSITION(rc));
929 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 5",
930 "%s", buffer);
931 # else
932 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
933 TRIO_ERROR_CODE(rc),
934 TRIO_ERROR_POSITION(rc));
935 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 5",
936 "%s", buffer);
937 # endif
938 #else
939 nerrors += (rc != -1);
940 #endif
941
942 /* Error: Invalid argument 2 */
943 rc = trio_snprintf(buffer, sizeof(buffer), "%#");
944 #if TRIO_FEATURE_ERRORCODE
945 # if TRIO_FEATURE_STRERR
946 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
947 TRIO_ERROR_CODE(rc),
948 TRIO_ERROR_NAME(rc),
949 TRIO_ERROR_POSITION(rc));
950 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
951 "%s", buffer);
952 # else
953 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
954 TRIO_ERROR_CODE(rc),
955 TRIO_ERROR_POSITION(rc));
956 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 3",
957 "%s", buffer);
958 # endif
959 #else
960 nerrors += (rc != -1);
961 #endif
962
963 /* Error: Invalid argument 3 */
964 rc = trio_snprintf(buffer, sizeof(buffer), "%hhhd", 42);
965 #if TRIO_FEATURE_ERRORCODE
966 # if TRIO_FEATURE_STRERR
967 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
968 TRIO_ERROR_CODE(rc),
969 TRIO_ERROR_NAME(rc),
970 TRIO_ERROR_POSITION(rc));
971 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 4",
972 "%s", buffer);
973 # else
974 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
975 TRIO_ERROR_CODE(rc),
976 TRIO_ERROR_POSITION(rc));
977 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 4",
978 "%s", buffer);
979 # endif
980 #else
981 nerrors += (rc != -1);
982 #endif
983
984 /* Error: Double reference */
985 rc = trio_snprintf(buffer, sizeof(buffer), "hello %1$d %1$d", 31, 32);
986 #if TRIO_FEATURE_ERRORCODE
987 # if TRIO_FEATURE_STRERR
988 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
989 TRIO_ERROR_CODE(rc),
990 TRIO_ERROR_NAME(rc),
991 TRIO_ERROR_POSITION(rc));
992 # if TRIO_UNIX98
993 nerrors += Verify(__FILE__, __LINE__, "Err = 4 (Double reference), Pos = 0",
994 "%s", buffer);
995 # else
996 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 9",
997 "%s", buffer);
998 # endif
999 # else
1000 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
1001 TRIO_ERROR_CODE(rc),
1002 TRIO_ERROR_POSITION(rc));
1003 # if TRIO_UNIX98
1004 nerrors += Verify(__FILE__, __LINE__, "Err = 4, Pos = 0",
1005 "%s", buffer);
1006 # else
1007 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 9",
1008 "%s", buffer);
1009 # endif
1010 # endif
1011 #else
1012 nerrors += (rc != -1);
1013 #endif
1014
1015 /* Error: Reference gap */
1016 rc = trio_snprintf(buffer, sizeof(buffer), "%3$d %1$d", 31, 32, 33);
1017 #if TRIO_FEATURE_ERRORCODE
1018 # if TRIO_FEATURE_STRERR
1019 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
1020 TRIO_ERROR_CODE(rc),
1021 TRIO_ERROR_NAME(rc),
1022 TRIO_ERROR_POSITION(rc));
1023 # if TRIO_UNIX98
1024 nerrors += Verify(__FILE__, __LINE__, "Err = 5 (Reference gap), Pos = 1",
1025 "%s", buffer);
1026 # else
1027 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
1028 "%s", buffer);
1029 # endif
1030 # else
1031 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
1032 TRIO_ERROR_CODE(rc),
1033 TRIO_ERROR_POSITION(rc));
1034 # if TRIO_UNIX98
1035 nerrors += Verify(__FILE__, __LINE__, "Err = 5, Pos = 1",
1036 "%s", buffer);
1037 # else
1038 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 3",
1039 "%s", buffer);
1040 # endif
1041 # endif
1042 #else
1043 nerrors += (rc != -1);
1044 #endif
1045
1046 return nerrors;
1047 }
1048
1049 /*************************************************************************
1050 *
1051 */
1052 #if TRIO_FEATURE_SCANF
1053 int
1054 VerifyScanningOneInteger
1055 TRIO_ARGS5((file, line, expected, format, original),
1056 TRIO_CONST char *file,
1057 int line,
1058 TRIO_CONST char *expected,
1059 TRIO_CONST char *format,
1060 int original)
1061 {
1062 int number;
1063 char data[512];
1064
1065 trio_snprintf(data, sizeof(data), format, original);
1066 trio_sscanf(data, format, &number);
1067 return Verify(file, line, expected, format, number);
1068 }
1069
1070 int
VerifyScanningIntegers(TRIO_NOARGS)1071 VerifyScanningIntegers(TRIO_NOARGS)
1072 {
1073 int nerrors = 0;
1074
1075 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
1076 "%i", 42);
1077 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
1078 "%d", 42);
1079 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "-42",
1080 "%d", -42);
1081 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2147483647",
1082 "%d", 2147483647);
1083 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
1084 "%u", 42);
1085 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2a",
1086 "%x", 42);
1087 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "52",
1088 "%o", 42);
1089 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "101010",
1090 "%..2i", 42);
1091 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "0x2a",
1092 "%#x", 42);
1093 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "052",
1094 "%#o", 42);
1095
1096 return nerrors;
1097 }
1098 #endif
1099
1100 /*************************************************************************
1101 *
1102 */
1103 #if TRIO_FEATURE_SCANF
1104 int
1105 VerifyScanningOneFloat
1106 TRIO_ARGS5((file, line, expected, format, original),
1107 TRIO_CONST char *file,
1108 int line,
1109 TRIO_CONST char *expected,
1110 TRIO_CONST char *format,
1111 double original)
1112 {
1113 float number;
1114 char data[512];
1115
1116 trio_snprintf(data, sizeof(data), format, original);
1117 trio_sscanf(data, format, &number);
1118 return Verify(file, line, expected, format, number);
1119 }
1120
1121 int
1122 VerifyScanningOneDouble
1123 TRIO_ARGS5((file, line, expected, format, original),
1124 TRIO_CONST char *file,
1125 int line,
1126 TRIO_CONST char *expected,
1127 TRIO_CONST char *format,
1128 double original)
1129 {
1130 double number;
1131 char data[512];
1132
1133 trio_snprintf(data, sizeof(data), format, original);
1134 trio_sscanf(data, format, &number);
1135 return Verify(file, line, expected, format, number);
1136 }
1137
1138 int
VerifyScanningFloats(TRIO_NOARGS)1139 VerifyScanningFloats(TRIO_NOARGS)
1140 {
1141 int nerrors = 0;
1142
1143 #if TRIO_FEATURE_FLOAT
1144 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42.000000",
1145 "%f", 42.0);
1146 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-42.000000",
1147 "%f", -42.0);
1148 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000e+01",
1149 "%e", 42.0);
1150 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000E+01",
1151 "%E", 42.0);
1152 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42",
1153 "%g", 42.0);
1154 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
1155 "%g", 1234567.0);
1156 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e-06",
1157 "%g", 1.234567e-6);
1158 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457E+06",
1159 "%G", 1234567.0);
1160 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
1161 "%12e", 1234567.0);
1162 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234500e+00",
1163 "%6e", 1234567.0);
1164 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
1165 "%.6e", 1234567.0);
1166 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.2345670000e+06",
1167 "%.10e", 1234567.0);
1168 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
1169 "%.6g", 1234567.0);
1170 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1234567",
1171 "%.10g", 1234567.0);
1172 # if TRIO_FEATURE_HEXFLOAT
1173 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x2.ap+4",
1174 "%a", 42.0);
1175 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x1.2d687p+20",
1176 "%a", 1234567.0);
1177 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0X1.2D687P+20",
1178 "%A", 1234567.0);
1179 # endif
1180 nerrors += VerifyScanningOneDouble(__FILE__, __LINE__, "1.79769e+308",
1181 "%lg", 1.79769e+308);
1182 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "nan",
1183 "%f", trio_nan());
1184 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "NAN",
1185 "%F", trio_nan());
1186 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-inf",
1187 "%f", trio_ninf());
1188 #endif
1189
1190 return nerrors;
1191 }
1192 #endif
1193
1194 /*************************************************************************
1195 *
1196 */
1197 #if TRIO_FEATURE_SCANF
1198 int
1199 VerifyScanningOneString
1200 TRIO_ARGS5((file, line, expected, format, original),
1201 TRIO_CONST char *file,
1202 int line,
1203 TRIO_CONST char *expected,
1204 TRIO_CONST char *format,
1205 char *original)
1206 {
1207 char string[512];
1208 char data[512];
1209
1210 trio_snprintf(data, sizeof(data), "%s", original);
1211 string[0] = 0;
1212 trio_sscanf(data, format, string);
1213 return Verify(file, line, expected, "%s", string);
1214 }
1215
1216 int
VerifyScanningStrings(TRIO_NOARGS)1217 VerifyScanningStrings(TRIO_NOARGS)
1218 {
1219 int nerrors = 0;
1220
1221 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "",
1222 "hello", "hello");
1223 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "",
1224 "", "");
1225 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
1226 "%s", "hello");
1227 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
1228 "%s", "hello world");
1229 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello world",
1230 "%[^\n]", "hello world");
1231 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "(nil)",
1232 "%s", NULL);
1233 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
1234 "%20s", "hello");
1235 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "he",
1236 "%2s", "hello");
1237 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ab",
1238 "%[ab]", "abcba");
1239 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
1240 "%[abc]", "abcba");
1241 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
1242 "%[a-c]", "abcba");
1243 #if TRIO_EXTENSION
1244 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
1245 "%[[:alpha:]]", "abcba");
1246 #endif
1247 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ba",
1248 "%*[ab]c%[^\n]", "abcba");
1249
1250 return nerrors;
1251 }
1252 #endif
1253
1254 /*************************************************************************
1255 *
1256 */
1257 #if TRIO_FEATURE_SCANF
1258 int
VerifyScanningRegression(TRIO_NOARGS)1259 VerifyScanningRegression(TRIO_NOARGS)
1260 {
1261 int nerrors = 0;
1262 int rc;
1263 #if TRIO_FEATURE_FLOAT
1264 int offset;
1265 double dnumber;
1266 # if defined(TRIO_BREESE)
1267 trio_long_double_t ldnumber;
1268 # endif
1269 #endif
1270 long lnumber;
1271 int number;
1272 char ch;
1273 char buffer[4096];
1274 FILE *stream;
1275
1276 #if TRIO_FEATURE_FLOAT
1277 rc = trio_sscanf("1.5", "%lf%n", &dnumber, &offset);
1278 nerrors += Verify(__FILE__, __LINE__, "1 3 1.500000",
1279 "%d %d %f", rc, offset, dnumber);
1280 #endif
1281 rc = trio_sscanf("q 123", "%c%ld", &ch, &lnumber);
1282 nerrors += Verify(__FILE__, __LINE__, "q 123",
1283 "%c %ld", ch, lnumber);
1284 rc = trio_sscanf("abc", "%*s%n", &number);
1285 nerrors += Verify(__FILE__, __LINE__, "0 3",
1286 "%d %d", rc, number);
1287 rc = trio_sscanf("abc def", "%*s%n", &number);
1288 nerrors += Verify(__FILE__, __LINE__, "0 3",
1289 "%d %d", rc, number);
1290 #if TRIO_FEATURE_FLOAT
1291 rc = trio_sscanf("0.141882295971771490", "%lf", &dnumber);
1292 /* FIXME: Verify */
1293 #endif
1294 number = 33;
1295 rc = trio_sscanf("total 1", "total %d", &number);
1296 nerrors += Verify(__FILE__, __LINE__, "1 1",
1297 "%d %d", rc, number);
1298 #if defined(TRIO_BREESE)
1299 # if TRIO_FEATURE_FLOAT
1300 nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771488",
1301 "%d %.18f", rc, dnumber);
1302 rc = trio_sscanf("0.141882295971771490", "%Lf", &ldnumber);
1303 nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771490",
1304 "%d %.18Lf", rc, ldnumber);
1305 # endif
1306 #endif
1307 #if TRIO_FEATURE_FLOAT
1308 rc = trio_sscanf("1.e-6", "%lg", &dnumber);
1309 nerrors += Verify(__FILE__, __LINE__, "1e-06",
1310 "%g", dnumber);
1311 rc = trio_sscanf("1e-6", "%lg", &dnumber);
1312 nerrors += Verify(__FILE__, __LINE__, "1e-06",
1313 "%g", dnumber);
1314 #endif
1315
1316 /* Do not overwrite result on matching error */
1317 ch = 'a';
1318 rc = trio_sscanf("0123456789", "%1[c]", &ch);
1319 nerrors += Verify(__FILE__, __LINE__, "a",
1320 "%c", ch);
1321
1322 /* Scan plus prefix for unsigned integer */
1323 rc = trio_sscanf("+42", "%u", &number);
1324 nerrors += Verify(__FILE__, __LINE__, "1 42",
1325 "%d %u", rc, number);
1326
1327 /* Scan minus prefix even for unsigned integer */
1328 rc = trio_sscanf("-42", "%u", &number);
1329 sprintf(buffer, "1 %u", -42U);
1330 nerrors += Verify(__FILE__, __LINE__, buffer,
1331 "%d %u", rc, number);
1332
1333 /* A scangroup match failure should not bind its argument,
1334 * i.e., it shouldn't match the empty string. */
1335 sprintf(buffer, "SPQR");
1336 rc = trio_sscanf("asdf", "%[c]", buffer);
1337 nerrors += Verify(__FILE__, __LINE__, "0 SPQR",
1338 "%d %s", rc, buffer);
1339
1340 /* Even whitespace scanning shouldn't try to read past EOF */
1341 stream = tmpfile();
1342 trio_fprintf(stream, "");
1343 rewind(stream);
1344 rc = trio_fscanf(stream, " ");
1345 nerrors += Verify(__FILE__, __LINE__, "0",
1346 "%d", rc);
1347 fclose(stream);
1348
1349 /* Idem, after a succesfull read */
1350 stream = tmpfile();
1351 trio_fprintf(stream, "123");
1352 rewind(stream);
1353 rc = trio_fscanf(stream, "%i ", &number);
1354 nerrors += Verify(__FILE__, __LINE__, "1 123",
1355 "%d %i", rc, number);
1356 fclose(stream);
1357
1358 /* The scanner should unget its read-ahead char */
1359 stream = tmpfile();
1360 trio_fprintf(stream, "123");
1361 rewind(stream);
1362 trio_fscanf(stream, "%*c");
1363 trio_fscanf(stream, "%c", &ch);
1364 nerrors += Verify(__FILE__, __LINE__, "2",
1365 "%c", ch);
1366 fclose(stream);
1367
1368 return nerrors;
1369 }
1370 #endif
1371
1372 /*************************************************************************
1373 *
1374 */
1375 int
VerifyScanning(TRIO_NOARGS)1376 VerifyScanning(TRIO_NOARGS)
1377 {
1378 int nerrors = 0;
1379 #if TRIO_FEATURE_SCANF
1380 nerrors += VerifyScanningIntegers();
1381 nerrors += VerifyScanningFloats();
1382 nerrors += VerifyScanningStrings();
1383 nerrors += VerifyScanningRegression();
1384 #endif
1385 return nerrors;
1386 }
1387
1388 /*************************************************************************
1389 *
1390 */
1391 int
VerifyStrings(TRIO_NOARGS)1392 VerifyStrings(TRIO_NOARGS)
1393 {
1394 int nerrors = 0;
1395 #if !defined(TRIO_MINIMAL)
1396 char buffer[512];
1397 #if TRIO_FEATURE_FLOAT
1398 double dnumber;
1399 float fnumber;
1400 #endif
1401 char *end;
1402
1403 /* Comparison */
1404 trio_copy(buffer, "Find me now");
1405 if (trio_length(buffer) != sizeof("Find me now") - 1) {
1406 nerrors++;
1407 Report0(__FILE__, __LINE__);
1408 }
1409 if (!trio_equal(buffer, "Find me now")) {
1410 nerrors++;
1411 Report0(__FILE__, __LINE__);
1412 }
1413 if (!trio_equal_case(buffer, "Find me now")) {
1414 nerrors++;
1415 Report0(__FILE__, __LINE__);
1416 }
1417 if (trio_equal_case(buffer, "FIND ME NOW")) {
1418 nerrors++;
1419 Report0(__FILE__, __LINE__);
1420 }
1421 if (!trio_equal_max(buffer, sizeof("Find me") - 1, "Find ME")) {
1422 nerrors++;
1423 Report0(__FILE__, __LINE__);
1424 }
1425 if (!trio_contains(buffer, "me")) {
1426 nerrors++;
1427 Report0(__FILE__, __LINE__);
1428 }
1429 if (trio_contains(buffer, "and me")) {
1430 nerrors++;
1431 Report0(__FILE__, __LINE__);
1432 }
1433 if (trio_substring(buffer, "me") == NULL) {
1434 nerrors++;
1435 Report0(__FILE__, __LINE__);
1436 }
1437 if (trio_substring_max(buffer, 4, "me") != NULL) {
1438 nerrors++;
1439 Report0(__FILE__, __LINE__);
1440 }
1441 if (!trio_match(buffer, "* me *")) {
1442 nerrors++;
1443 Report0(__FILE__, __LINE__);
1444 }
1445 if (trio_match_case(buffer, "* ME *")) {
1446 nerrors++;
1447 Report0(__FILE__, __LINE__);
1448 }
1449 if (trio_index(buffer, 'n') == NULL) {
1450 nerrors++;
1451 Report0(__FILE__, __LINE__);
1452 }
1453 if (trio_index(buffer, '_') != NULL) {
1454 nerrors++;
1455 Report0(__FILE__, __LINE__);
1456 }
1457 if (trio_index_last(buffer, 'n') == NULL) {
1458 nerrors++;
1459 Report0(__FILE__, __LINE__);
1460 }
1461
1462 /* Append */
1463 trio_copy(buffer, "Find me now");
1464 if (!trio_append(buffer, " and again")) {
1465 nerrors++;
1466 Report0(__FILE__, __LINE__);
1467 }
1468 if (!trio_equal(buffer, "Find me now and again")) {
1469 nerrors++;
1470 Report0(__FILE__, __LINE__);
1471 }
1472 if (!trio_append_max(buffer, 0, "should not appear")) {
1473 nerrors++;
1474 Report0(__FILE__, __LINE__);
1475 }
1476 if (!trio_equal(buffer, "Find me now and again")) {
1477 nerrors++;
1478 Report0(__FILE__, __LINE__);
1479 }
1480
1481 /* To upper/lower */
1482 trio_copy(buffer, "Find me now");
1483 trio_upper(buffer);
1484 if (!trio_equal_case(buffer, "FIND ME NOW")) {
1485 nerrors++;
1486 Report0(__FILE__, __LINE__);
1487 }
1488 trio_lower(buffer);
1489 if (!trio_equal_case(buffer, "find me now")) {
1490 nerrors++;
1491 Report0(__FILE__, __LINE__);
1492 }
1493
1494 #if TRIO_FEATURE_FLOAT
1495 /* Double conversion */
1496 trio_copy(buffer, "3.1415");
1497 dnumber = trio_to_double(buffer, NULL);
1498 if (!DOUBLE_EQUAL(dnumber, 3.1415)) {
1499 nerrors++;
1500 Report0(__FILE__, __LINE__);
1501 }
1502 fnumber = trio_to_float(buffer, NULL);
1503 if (!FLOAT_EQUAL(fnumber, 3.1415)) {
1504 nerrors++;
1505 Report0(__FILE__, __LINE__);
1506 }
1507 #endif
1508
1509 /* Long conversion */
1510 trio_copy(buffer, "3.1415");
1511 if (trio_to_long(buffer, NULL, 10) != 3L) {
1512 nerrors++;
1513 Report0(__FILE__, __LINE__);
1514 }
1515 if (trio_to_long(buffer, NULL, 4) != 3L) {
1516 nerrors++;
1517 Report0(__FILE__, __LINE__);
1518 }
1519 trio_to_long(buffer, &end, 2);
1520 if (end != buffer) {
1521 nerrors++;
1522 Report0(__FILE__, __LINE__);
1523 }
1524
1525 #endif /* !defined(TRIO_MINIMAL) */
1526 return nerrors;
1527 }
1528
1529 /*************************************************************************
1530 *
1531 */
1532 int
VerifyDynamicStrings(TRIO_NOARGS)1533 VerifyDynamicStrings(TRIO_NOARGS)
1534 {
1535 int nerrors = 0;
1536 #if !defined(TRIO_MINIMAL)
1537 trio_string_t *string;
1538 const char no_terminate[5] = { 'h', 'e', 'l', 'l', 'o' };
1539
1540 string = trio_xstring_duplicate("Find me now");
1541 if (string == NULL) {
1542 nerrors++;
1543 goto error;
1544 }
1545 if (!trio_xstring_equal(string, "FIND ME NOW"))
1546 nerrors++;
1547 if (!trio_xstring_append(string, " and again") ||
1548 !trio_xstring_equal(string, "FIND ME NOW AND AGAIN"))
1549 nerrors++;
1550 if (!trio_xstring_contains(string, "me"))
1551 nerrors++;
1552 if (trio_xstring_contains(string, "ME"))
1553 nerrors++;
1554 if (!trio_xstring_match(string, "* me *"))
1555 nerrors++;
1556 if (trio_xstring_match_case(string, "* ME *"))
1557 nerrors++;
1558 if (!trio_xstring_append_max(string, no_terminate, 5) ||
1559 !trio_xstring_equal(string, "FIND ME NOW AND AGAINhello"))
1560 nerrors++;
1561
1562 error:
1563 if (string)
1564 trio_string_destroy(string);
1565
1566 #endif /* !defined(TRIO_MINIMAL) */
1567 return nerrors;
1568 }
1569
1570 /*************************************************************************
1571 *
1572 */
1573 int
VerifyNaN(TRIO_NOARGS)1574 VerifyNaN(TRIO_NOARGS)
1575 {
1576 double ninf_number = trio_ninf();
1577 double pinf_number = trio_pinf();
1578 double nan_number = trio_nan();
1579 int nerrors = 0;
1580
1581 nerrors += Verify(__FILE__, __LINE__, "-1",
1582 "%d", trio_isinf(ninf_number));
1583 nerrors += Verify(__FILE__, __LINE__, "0",
1584 "%d", trio_isinf(42.0));
1585 nerrors += Verify(__FILE__, __LINE__, "1",
1586 "%d", trio_isinf(pinf_number));
1587 nerrors += Verify(__FILE__, __LINE__, "1",
1588 "%d", trio_isnan(nan_number));
1589 nerrors += Verify(__FILE__, __LINE__, "0",
1590 "%d", trio_isnan(42.0));
1591
1592 return nerrors;
1593 }
1594
1595 /*************************************************************************
1596 *
1597 */
1598 int
main(TRIO_NOARGS)1599 main(TRIO_NOARGS)
1600 {
1601 int nerrors = 0;
1602
1603 printf("%s\n", rcsid);
1604
1605 #if TRIO_EXTENSION
1606 /* Override system locale settings */
1607 trio_locale_set_decimal_point(".");
1608 trio_locale_set_thousand_separator(",");
1609 trio_locale_set_grouping("\3");
1610 #endif
1611
1612 printf("Verifying strings\n");
1613 nerrors += VerifyStrings();
1614
1615 printf("Verifying dynamic strings\n");
1616 nerrors += VerifyDynamicStrings();
1617
1618 printf("Verifying special quantities\n");
1619 nerrors += VerifyNaN();
1620
1621 printf("Verifying formatting\n");
1622 nerrors += VerifyFormatting();
1623
1624 printf("Verifying scanning\n");
1625 nerrors += VerifyScanning();
1626
1627 printf("Verifying return values\n");
1628 nerrors += VerifyErrors();
1629 nerrors += VerifyReturnValues();
1630
1631 printf("Verifying allocation\n");
1632 nerrors += VerifyAllocate();
1633
1634 if (nerrors == 0)
1635 printf("Regression test succeeded\n");
1636 else
1637 printf("Regression test failed in %d instance(s)\n", nerrors);
1638
1639 return nerrors ? 1 : 0;
1640 }
1641