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