aboutsummaryrefslogtreecommitdiffstats
path: root/trio/regression.c
diff options
context:
space:
mode:
authorMatthias Andree <matthias.andree@gmx.de>2004-11-10 19:04:29 +0000
committerMatthias Andree <matthias.andree@gmx.de>2004-11-10 19:04:29 +0000
commit13c27199231cbc2cc83969ada741b95be1cca4d3 (patch)
tree58c32705247dcf031d6f17d8bc8ef78557d74113 /trio/regression.c
parent486bdc6d20c7e7d8c6eeb3124cf845abefcd7d11 (diff)
downloadfetchmail-13c27199231cbc2cc83969ada741b95be1cca4d3.tar.gz
fetchmail-13c27199231cbc2cc83969ada741b95be1cca4d3.tar.bz2
fetchmail-13c27199231cbc2cc83969ada741b95be1cca4d3.zip
Import Trio 1.10 into fetchmail's trunk.
svn path=/trunk/; revision=3995
Diffstat (limited to 'trio/regression.c')
-rw-r--r--trio/regression.c1206
1 files changed, 1206 insertions, 0 deletions
diff --git a/trio/regression.c b/trio/regression.c
new file mode 100644
index 00000000..ccbd78b5
--- /dev/null
+++ b/trio/regression.c
@@ -0,0 +1,1206 @@
+/*************************************************************************
+ * Regression test
+ */
+
+#include "triodef.h"
+#if defined(TRIO_COMPILER_ANCIENT)
+# include <varargs.h>
+#else
+# include <stdarg.h>
+#endif
+#include <math.h>
+#include <limits.h>
+#include <float.h>
+#include <errno.h>
+
+#include "trio.h"
+#include "triop.h"
+#include "trionan.h"
+#if defined(TRIO_MINIMAL)
+# define TRIO_STRING_PUBLIC static
+# include "triostr.c"
+#else
+# include "triostr.h"
+#endif
+#undef printf
+
+#if TRIO_WIDECHAR
+# include <wchar.h>
+#endif
+
+#define QUOTE(x) #x
+
+#define DOUBLE_EQUAL(x,y) (((x)>(y)-DBL_EPSILON) && ((x)<(y)+DBL_EPSILON))
+#define FLOAT_EQUAL(x,y) (((x)>(y)-FLT_EPSILON) && ((x)<(y)+FLT_EPSILON))
+
+static TRIO_CONST char rcsid[] = "@(#)$Id: regression.c,v 1.44 2002/12/29 15:08:56 breese Exp $";
+
+
+/*************************************************************************
+ *
+ */
+static void
+Dump
+TRIO_ARGS2((buffer, rc),
+ char *buffer,
+ int rc)
+{
+ if (rc < 0)
+ {
+ printf("Err = %d (%s), Pos = %d\n",
+ TRIO_ERROR_CODE(rc),
+ TRIO_ERROR_NAME(rc),
+ TRIO_ERROR_POSITION(rc));
+ }
+ else if (buffer)
+ printf("buffer[% 3d] = \"%s\"\n", rc, buffer);
+}
+
+/*************************************************************************
+ *
+ */
+static void
+Report0
+TRIO_ARGS2((file, line),
+ TRIO_CONST char *file,
+ int line)
+{
+ printf("Verification failed in %s:%d.\n", file, line);
+}
+
+/*************************************************************************
+ *
+ */
+static void
+Report
+TRIO_ARGS4((file, line, expected, got),
+ TRIO_CONST char *file,
+ int line,
+ TRIO_CONST char *expected,
+ TRIO_CONST char *got)
+{
+ Report0(file, line);
+ printf(" Expected \"%s\"\n", expected);
+ printf(" Got \"%s\"\n", got);
+}
+
+/*************************************************************************
+ *
+ */
+int
+Verify
+TRIO_VARGS5((file, line, result, fmt, va_alist),
+ TRIO_CONST char *file,
+ int line,
+ TRIO_CONST char *result,
+ TRIO_CONST char *fmt,
+ TRIO_VA_DECL)
+{
+ int rc;
+ va_list args;
+ char buffer[4096];
+
+ TRIO_VA_START(args, fmt);
+ rc = trio_vsnprintf(buffer, sizeof(buffer), fmt, args);
+ if (rc < 0)
+ Dump(buffer, rc);
+ TRIO_VA_END(args);
+
+ if (!trio_equal_case(result, buffer))
+ {
+ Report(file, line, result, buffer);
+ return 1;
+ }
+ return 0;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyReturnValues(TRIO_NOARGS)
+{
+ int nerrors = 0;
+ int rc;
+ int count;
+ char *expected;
+ char buffer[4096];
+ char result[4096];
+
+ rc = trio_sprintf(buffer, "%s%n", "0123456789", &count);
+ trio_sprintf(result, "%d %d %s", rc, count, buffer);
+ expected = "10 10 0123456789";
+ if (!trio_equal_case(result, expected))
+ {
+ nerrors++;
+ Report(__FILE__, __LINE__, expected, result);
+ }
+
+ rc = trio_snprintf(buffer, sizeof(buffer), "%s%n", "0123456789", &count);
+ trio_sprintf(result, "%d %d %s", rc, count, buffer);
+ expected = "10 10 0123456789";
+ if (!trio_equal_case(result, expected))
+ {
+ nerrors++;
+ Report(__FILE__, __LINE__, expected, result);
+ }
+
+ rc = trio_snprintf(buffer, 4, "%s%n", "0123456789", &count);
+ trio_sprintf(result, "%d %d %s", rc, count, buffer);
+ expected = "10 3 012";
+ if (!trio_equal_case(result, expected))
+ {
+ nerrors++;
+ Report(__FILE__, __LINE__, expected, result);
+ }
+
+ /* The output buffer contains the empty string */
+ rc = trio_snprintf(buffer, 1, "%s%n", "0123456789", &count);
+ trio_sprintf(result, "%d %d %s", rc, count, buffer);
+ expected = "10 0 ";
+ if (!trio_equal_case(result, expected))
+ {
+ nerrors++;
+ Report(__FILE__, __LINE__, expected, result);
+ }
+
+ /* The output buffer should be left untouched when max size is 0 */
+ trio_sprintf(buffer, "DO NOT TOUCH");
+ rc = trio_snprintf(buffer, 0, "%s%n", "0123456789", &count);
+ trio_sprintf(result, "%d %d %s", rc, count, buffer);
+ expected = "10 0 DO NOT TOUCH";
+ if (!trio_equal_case(result, expected))
+ {
+ nerrors++;
+ Report(__FILE__, __LINE__, expected, result);
+ }
+
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+#define TEST_STRING "0123456789"
+
+int
+VerifyAllocate(TRIO_NOARGS)
+{
+ int nerrors = 0;
+ int rc;
+ char *string;
+ int count;
+ int test_size = sizeof(TEST_STRING) - 1;
+
+ /* Allocate a string with the result */
+ rc = trio_asprintf(&string, "%s%n", TEST_STRING, &count);
+ if (rc < 0)
+ {
+ nerrors++;
+ Dump(string, rc);
+ }
+ else if (count != test_size)
+ {
+ nerrors++;
+ printf("Validation failed in %s:%d\n", __FILE__, __LINE__);
+ printf(" Expected %%n = %d\n", test_size);
+ printf(" Got %%n = %d\n", count);
+ }
+ else if (!trio_equal_case(string, TEST_STRING))
+ {
+ nerrors++;
+ Report(__FILE__, __LINE__, TEST_STRING, string);
+ }
+ if (string)
+ free(string);
+
+ return nerrors;
+}
+
+
+/*************************************************************************
+ *
+ */
+int
+VerifyFormatting(TRIO_NOARGS)
+{
+ int nerrors = 0;
+ char buffer[256];
+
+ /* Normal text */
+ nerrors += Verify(__FILE__, __LINE__, "Hello world",
+ "Hello world");
+ /* String */
+ nerrors += Verify(__FILE__, __LINE__, "Hello world",
+ "%s", "Hello world");
+ /* Pointer */
+ if (sizeof(void *) == 4)
+ {
+ nerrors += Verify(__FILE__, __LINE__, "Pointer 0x01234567",
+ "Pointer %p", 0x1234567);
+ }
+ else if (sizeof(void *) == 8)
+ {
+ nerrors += Verify(__FILE__, __LINE__, "Pointer 0x0123456789012345",
+ "Pointer %p", 0x123456789012345);
+ }
+ /* Nil pointer */
+ nerrors += Verify(__FILE__, __LINE__, "Pointer (nil)",
+ "Pointer %p", NULL);
+ /* Integer */
+ nerrors += Verify(__FILE__, __LINE__, "Number 42",
+ "Number %d", 42);
+ nerrors += Verify(__FILE__, __LINE__, "Number -42",
+ "Number %d", -42);
+ nerrors += Verify(__FILE__, __LINE__, "Number 42",
+ "Number %ld", 42L);
+ nerrors += Verify(__FILE__, __LINE__, "Number -42",
+ "Number %ld", -42L);
+ /* Integer width */
+ nerrors += Verify(__FILE__, __LINE__, " 1234",
+ "%6d", 1234);
+ nerrors += Verify(__FILE__, __LINE__, " 1234",
+ "%*d", 6, 1234);
+ /* Integer width overrun */
+ nerrors += Verify(__FILE__, __LINE__, "123456",
+ "%4d", 123456);
+ /* Integer precision */
+ nerrors += Verify(__FILE__, __LINE__, "0012",
+ "%.4d", 12);
+ nerrors += Verify(__FILE__, __LINE__, "0012",
+ "%.*d", 4, 12);
+ nerrors += Verify(__FILE__, __LINE__, " 0012",
+ "%6.*d", 4, 12);
+ nerrors += Verify(__FILE__, __LINE__, " 0012",
+ "%*.*d", 6, 4, 12);
+ nerrors += Verify(__FILE__, __LINE__, " 0012",
+ "%*.*.*d", 6, 4, 2, 12);
+ nerrors += Verify(__FILE__, __LINE__, " 0012",
+ "%*.*.*i", 6, 4, 10, 12);
+ /* Integer sign, zero-padding, and width */
+ nerrors += Verify(__FILE__, __LINE__, "+01234",
+ "%+06d", 1234);
+ nerrors += Verify(__FILE__, __LINE__, " 01234",
+ "% 06d", 1234);
+ nerrors += Verify(__FILE__, __LINE__, "+01234",
+ "% +06d", 1234);
+ /* Integer adjust, zero-padding, and width */
+ nerrors += Verify(__FILE__, __LINE__, "12 ",
+ "%-08d", 12);
+ /* Integer zero-padding, width, and precision */
+ nerrors += Verify(__FILE__, __LINE__, " 000012",
+ "%08.6d", 12);
+ /* Integer base */
+ nerrors += Verify(__FILE__, __LINE__, "42",
+ "%u", 42);
+ nerrors += Verify(__FILE__, __LINE__, "-1",
+ "%d", -1);
+ nerrors += Verify(__FILE__, __LINE__, "52",
+ "%o", 42);
+ nerrors += Verify(__FILE__, __LINE__, "052",
+ "%#o", 42);
+ nerrors += Verify(__FILE__, __LINE__, "0",
+ "%#o", 0);
+ nerrors += Verify(__FILE__, __LINE__, "2a",
+ "%x", 42);
+ nerrors += Verify(__FILE__, __LINE__, "2A",
+ "%X", 42);
+ nerrors += Verify(__FILE__, __LINE__, "0x2a",
+ "%#x", 42);
+ nerrors += Verify(__FILE__, __LINE__, "0X2A",
+ "%#X", 42);
+ nerrors += Verify(__FILE__, __LINE__, "0x00c ",
+ "%-#6.3x", 12);
+ nerrors += Verify(__FILE__, __LINE__, "",
+ "%.d", 0);
+ nerrors += Verify(__FILE__, __LINE__, "",
+ "%#.d", 0);
+ nerrors += Verify(__FILE__, __LINE__, "42",
+ "%.d", 42);
+ nerrors += Verify(__FILE__, __LINE__, "",
+ "%.o", 0);
+ nerrors += Verify(__FILE__, __LINE__, " 0000",
+ "%8.4o", 0);
+ nerrors += Verify(__FILE__, __LINE__, " 0",
+ "%8o", 0);
+ nerrors += Verify(__FILE__, __LINE__, "00000000",
+ "%08o", 0);
+ nerrors += Verify(__FILE__, __LINE__, "0",
+ "%#.o", 0);
+ nerrors += Verify(__FILE__, __LINE__, "52",
+ "%.o", 42);
+ nerrors += Verify(__FILE__, __LINE__, "",
+ "%.x", 0);
+ nerrors += Verify(__FILE__, __LINE__, "",
+ "%#.x", 0);
+ nerrors += Verify(__FILE__, __LINE__, "2a",
+ "%.x", 42);
+ sprintf(buffer, "%u", UINT_MAX);
+ nerrors += Verify(__FILE__, __LINE__, buffer,
+ "%u", -1);
+ sprintf(buffer, "%x", UINT_MAX);
+ nerrors += Verify(__FILE__, __LINE__, buffer,
+ "%x", -1);
+ /* Double */
+ nerrors += Verify(__FILE__, __LINE__, "3141.000000",
+ "%f", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "3141.500000",
+ "%f", 3141.5);
+ nerrors += Verify(__FILE__, __LINE__, "3.141000e+03",
+ "%e", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, " -2.3420e-02",
+ "%16.4e", -2.342E-02);
+ nerrors += Verify(__FILE__, __LINE__, " -2.3420e-22",
+ "%16.4e", -2.342E-22);
+ nerrors += Verify(__FILE__, __LINE__, " 2.3420e-02",
+ "% 16.4e", 2.342E-02);
+ nerrors += Verify(__FILE__, __LINE__, " 2.3420e-02",
+ "% 1.4e", 2.342E-02);
+ nerrors += Verify(__FILE__, __LINE__, "3.141000E-44",
+ "%E", 3.141e-44);
+ nerrors += Verify(__FILE__, __LINE__, "0",
+ "%g", 0.0);
+ nerrors += Verify(__FILE__, __LINE__, "-0",
+ "%g", trio_nzero());
+ nerrors += Verify(__FILE__, __LINE__, "3141.5",
+ "%g", 3141.5);
+ nerrors += Verify(__FILE__, __LINE__, "3.1415E-06",
+ "%G", 3.1415e-6);
+ nerrors += Verify(__FILE__, __LINE__, "+3141.000000",
+ "%+f", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "-3141.000000",
+ "%+f", -3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "0.333333",
+ "%f", 1.0/3.0);
+ nerrors += Verify(__FILE__, __LINE__, "0.666667",
+ "%f", 2.0/3.0);
+ /* Beyond accuracy */
+ nerrors += Verify(__FILE__, __LINE__, "0.000000",
+ "%f", 1.234567890123456789e-20);
+#if defined(TRIO_BREESE)
+ nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580299875",
+ "%.32g", 1.4);
+ nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991118215802998748",
+ "%.32f", 1.4);
+ nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580300",
+ "%.28f", 1.4);
+ nerrors += Verify(__FILE__, __LINE__, "1.399999999999999911182158",
+ "%.24f", 1.4);
+ nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991",
+ "%.17f", 1.4);
+ nerrors += Verify(__FILE__, __LINE__, "1.40000000000000",
+ "%.14f", 1.4);
+ nerrors += Verify(__FILE__, __LINE__, "39413.800000000002910383045673370361",
+ "%.30f", 39413.80);
+#endif
+ /* 2^-1 + 2^-15 */
+ nerrors += Verify(__FILE__, __LINE__, "0.500030517578125",
+ "%.*g", DBL_DIG + 10, 0.500030517578125);
+ /* Double decimal point */
+ nerrors += Verify(__FILE__, __LINE__, "3141",
+ "%.0f", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "3142",
+ "%.0f", 3141.5);
+ nerrors += Verify(__FILE__, __LINE__, "3141",
+ "%.f", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "12",
+ "%.f", 12.34);
+ nerrors += Verify(__FILE__, __LINE__, "3141.000",
+ "%.3f", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "3141.000000",
+ "%#f", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "0.0000",
+ "%#.4f", 0.0);
+ nerrors += Verify(__FILE__, __LINE__, "0.000",
+ "%#.4g", 0.0);
+ nerrors += Verify(__FILE__, __LINE__, "3141.0000",
+ "%#.4f", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "3141.",
+ "%#.0f", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "3141.",
+ "%#.f", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "11.0000",
+ "%#.4f", 11.0);
+ nerrors += Verify(__FILE__, __LINE__, "100.00",
+ "%.2f", 99.9999);
+ nerrors += Verify(__FILE__, __LINE__, "3e+03",
+ "%.e", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "3.e+03",
+ "%#.e", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "100",
+ "%.2g", 99.9999);
+ nerrors += Verify(__FILE__, __LINE__, "100.",
+ "%#.2g", 99.9999);
+ nerrors += Verify(__FILE__, __LINE__, "0.123",
+ "%0g", 0.123);
+ nerrors += Verify(__FILE__, __LINE__, "1.00e+00",
+ "%.2e", 0.9999);
+ nerrors += Verify(__FILE__, __LINE__, "1",
+ "%.2g", 0.9999);
+ nerrors += Verify(__FILE__, __LINE__, "2",
+ "%.g", 1.5);
+ nerrors += Verify(__FILE__, __LINE__, "0.01",
+ "%.2g", 0.01);
+ nerrors += Verify(__FILE__, __LINE__, "0.010",
+ "%#.2g", 0.01);
+ /* Double width, precision, and zero padding */
+ nerrors += Verify(__FILE__, __LINE__, "00003.141500e+03",
+ "%016e", 3141.5);
+ nerrors += Verify(__FILE__, __LINE__, " 3.141500e+03",
+ "%16e", 3141.5);
+ nerrors += Verify(__FILE__, __LINE__, "3.141500e+03 ",
+ "%-16e", 3141.5);
+ nerrors += Verify(__FILE__, __LINE__, "03.142e+03",
+ "%010.3e", 3141.5);
+#if !defined(TRIO_COMPILER_ANCIENT)
+ /* Long double */
+ nerrors += Verify(__FILE__, __LINE__, "1.400000",
+ "%Lf", 1.4L);
+#endif
+
+ /* Special cases */
+ nerrors += Verify(__FILE__, __LINE__, "1.00",
+ "%.2f", 0.999);
+ nerrors += Verify(__FILE__, __LINE__, "100",
+ "%.0f", 99.9);
+ nerrors += Verify(__FILE__, __LINE__, "inf",
+ "%f", trio_pinf());
+ nerrors += Verify(__FILE__, __LINE__, "-inf",
+ "%f", trio_ninf());
+ nerrors += Verify(__FILE__, __LINE__, "INF",
+ "%F", trio_pinf());
+ nerrors += Verify(__FILE__, __LINE__, "-INF",
+ "%F", trio_ninf());
+ /* May fail if NaN is unsupported */
+ nerrors += Verify(__FILE__, __LINE__, "nan",
+ "%f", trio_nan());
+ nerrors += Verify(__FILE__, __LINE__, "NAN",
+ "%F", trio_nan());
+
+ /* Char width alignment */
+ nerrors += Verify(__FILE__, __LINE__, "Char X .",
+ "Char %-4c.", 'X');
+ /* String width / precision */
+ nerrors += Verify(__FILE__, __LINE__, " testing",
+ "%8s", "testing");
+ nerrors += Verify(__FILE__, __LINE__, "testing ",
+ "%-8s", "testing");
+ nerrors += Verify(__FILE__, __LINE__, " testing",
+ "%*s", 8, "testing");
+ nerrors += Verify(__FILE__, __LINE__, "testing ",
+ "%*s", -8, "testing");
+ nerrors += Verify(__FILE__, __LINE__, "test",
+ "%.4s", "testing");
+ nerrors += Verify(__FILE__, __LINE__, "test",
+ "%.*s", 4, "testing");
+ nerrors += Verify(__FILE__, __LINE__, "testing",
+ "%.*s", -4, "testing");
+#if TRIO_UNIX98
+ /* Positional */
+ nerrors += Verify(__FILE__, __LINE__, "222 111",
+ "%2$s %1$s", "111", "222");
+ nerrors += Verify(__FILE__, __LINE__, "123456 12345 0001234 00123",
+ "%4$d %3$*8$d %2$.*7$d %1$*6$.*5$d",
+ 123, 1234, 12345, 123456, 5, 6, 7, 8);
+#endif
+
+#if TRIO_GNU
+ nerrors += Verify(__FILE__, __LINE__, "256",
+ "%Zd", sizeof(buffer));
+ errno = EINTR;
+ nerrors += Verify(__FILE__, __LINE__, "Interrupted system call",
+ "%m");
+#endif
+
+#if TRIO_BSD || TRIO_GNU
+# if defined(TRIO_COMPILER_SUPPORTS_LL)
+ /* This may fail if the preprocessor does not recognize LL */
+ nerrors += Verify(__FILE__, __LINE__, "42",
+ "%qd", 42LL);
+# endif
+#endif
+
+#if TRIO_C99
+ nerrors += Verify(__FILE__, __LINE__, "0x2.ap+4",
+ "%a", 42.0);
+ nerrors += Verify(__FILE__, __LINE__, "-0x2.ap+4",
+ "%a", -42.0);
+ nerrors += Verify(__FILE__, __LINE__, "0x1.8p+0",
+ "%a", 1.5);
+ nerrors += Verify(__FILE__, __LINE__, "0x1.6666666666666p+0",
+ "%a", 1.4);
+ nerrors += Verify(__FILE__, __LINE__, "0xc.45p+8",
+ "%a", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "0XC.45P+8",
+ "%A", 3141.0);
+ nerrors += Verify(__FILE__, __LINE__, "0xb.351c434a98fa8p-148",
+ "%a", 3.141e-44);
+ nerrors += Verify(__FILE__, __LINE__, "256",
+ "%zd", sizeof(buffer));
+ nerrors += Verify(__FILE__, __LINE__, "42",
+ "%td", 42);
+# if defined(TRIO_COMPILER_SUPPORTS_LL)
+ /* Some compilers may not handle the LL suffix correctly */
+ nerrors += Verify(__FILE__, __LINE__, "42",
+ "%jd", 42LL);
+# endif
+#endif
+
+#if TRIO_WIDECHAR
+ nerrors += Verify(__FILE__, __LINE__, "Hello World",
+ "%ls", L"Hello World");
+ nerrors += Verify(__FILE__, __LINE__, "\\aHello World",
+ "%#ls", L"\aHello World");
+ nerrors += Verify(__FILE__, __LINE__, "A",
+ "%lc", L'A');
+ nerrors += Verify(__FILE__, __LINE__, "\\a",
+ "%#lc", L'\a');
+#endif
+
+#if TRIO_MICROSOFT
+ nerrors += Verify(__FILE__, __LINE__, "42",
+ "%I8d", 42);
+ nerrors += Verify(__FILE__, __LINE__, "ffffffff",
+ "%I16x", -1);
+#endif
+
+#if TRIO_EXTENSION
+ nerrors += Verify(__FILE__, __LINE__, " 42 86",
+ "%!4d %d", 42, 86);
+ nerrors += Verify(__FILE__, __LINE__, "0042 0086",
+ "%!04d %d", 42, 86);
+ nerrors += Verify(__FILE__, __LINE__, "42",
+ "%&d", sizeof(long), 42L);
+ /* Non-printable string */
+ nerrors += Verify(__FILE__, __LINE__, "NonPrintable \\x01 \\a \\\\",
+ "NonPrintable %#s", "\01 \07 \\");
+ nerrors += Verify(__FILE__, __LINE__, "\\a \\b \\t \\n \\v \\f \\r",
+ "%#s", "\007 \010 \011 \012 \013 \014 \015");
+ /* Quote flag */
+ nerrors += Verify(__FILE__, __LINE__, "Another \"quoted\" string",
+ "Another %'s string", "quoted");
+ /* Integer base */
+ nerrors += Verify(__FILE__, __LINE__, "Number 42 == 1120 (base 3)",
+ "Number %d == %..3i (base 3)", 42, 42);
+ /* Integer base (specifier base must be used instead of base modifier) */
+ nerrors += Verify(__FILE__, __LINE__, "42",
+ "%..3d", 42);
+ nerrors += Verify(__FILE__, __LINE__, "52",
+ "%..3o", 42);
+ nerrors += Verify(__FILE__, __LINE__, "2a",
+ "%..3x", 42);
+ /* Integer thousand separator */
+ nerrors += Verify(__FILE__, __LINE__, "Number 100",
+ "Number %'d", 100);
+ nerrors += Verify(__FILE__, __LINE__, "Number 1,000,000",
+ "Number %'d", 1000000);
+ /* Float thousand separator */
+ nerrors += Verify(__FILE__, __LINE__, "31,415.200000",
+ "%'f", 31415.2);
+ nerrors += Verify(__FILE__, __LINE__, "1,000,000.000000",
+ "%'f", 1000000.0);
+ /* Rounding modifier */
+ nerrors += Verify(__FILE__, __LINE__, "1.4",
+ "%.32Rf", 1.4);
+ nerrors += Verify(__FILE__, __LINE__, "1.4",
+ "%.17Rf", 1.4);
+ nerrors += Verify(__FILE__, __LINE__, "39413.8",
+ "%.30Rf", 39413.80);
+# if !defined(TRIO_COMPILER_ANCIENT)
+ /* Long double */
+ nerrors += Verify(__FILE__, __LINE__, "1.4",
+ "%RLf", 1.4L);
+ nerrors += Verify(__FILE__, __LINE__, "1.4",
+ "%.30RLf", 1.4L);
+# endif
+#endif
+
+#if defined(TRIO_BREESE)
+ /*
+ * These results depends on issues beyond our control. For example,
+ * the accuracy of floating-point numbers depends on the underlying
+ * floating-point hardware (e.g. whether IEEE 754 double or extended-
+ * double format is used).
+ *
+ * These tests are therefore not part of the normal regression test,
+ * but we keep them here for development purposes.
+ */
+ nerrors += Verify(__FILE__, __LINE__, "123456789012345680868.000000",
+ "%f", 1.234567890123456789e20);
+ nerrors += Verify(__FILE__, __LINE__, "1.23456789012345677901e-20",
+ "%.20e", 1.2345678901234567e-20);
+ nerrors += Verify(__FILE__, __LINE__, "0.666666666666666629659233",
+ "%.*g", DBL_DIG + 10, 2.0/3.0);
+ nerrors += Verify(__FILE__, __LINE__, "123456789012345700000",
+ "%Rf", 1.234567890123456789e20);
+# if !defined(TRIO_COMPILER_ANCIENT)
+ nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
+ "%RLf", (2.0L/3.0L));
+ nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
+ "%.30RLf", (2.0L/3.0L));
+# endif
+#endif
+
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyErrors(TRIO_NOARGS)
+{
+ char buffer[512];
+ int rc;
+ int nerrors = 0;
+
+ /* Error: Invalid argument 1 */
+ rc = trio_snprintf(buffer, sizeof(buffer), "%d %r", 42, "text");
+#if TRIO_ERRORS
+ trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
+ TRIO_ERROR_CODE(rc),
+ TRIO_ERROR_NAME(rc),
+ TRIO_ERROR_POSITION(rc));
+ nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 5",
+ "%s", buffer);
+#else
+ nerrors += (rc != -1);
+#endif
+ /* Error: Invalid argument 2 */
+ rc = trio_snprintf(buffer, sizeof(buffer), "%#");
+#if TRIO_ERRORS
+ trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
+ TRIO_ERROR_CODE(rc),
+ TRIO_ERROR_NAME(rc),
+ TRIO_ERROR_POSITION(rc));
+ nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
+ "%s", buffer);
+#else
+ nerrors += (rc != -1);
+#endif
+ /* Error: Invalid argument 3 */
+ rc = trio_snprintf(buffer, sizeof(buffer), "%hhhd", 42);
+#if TRIO_ERRORS
+ trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
+ TRIO_ERROR_CODE(rc),
+ TRIO_ERROR_NAME(rc),
+ TRIO_ERROR_POSITION(rc));
+ nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 4",
+ "%s", buffer);
+#else
+ nerrors += (rc != -1);
+#endif
+ /* Error: Double reference */
+ rc = trio_snprintf(buffer, sizeof(buffer), "hello %1$d %1$d", 31, 32);
+#if TRIO_ERRORS
+ trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
+ TRIO_ERROR_CODE(rc),
+ TRIO_ERROR_NAME(rc),
+ TRIO_ERROR_POSITION(rc));
+# if TRIO_UNIX98
+ nerrors += Verify(__FILE__, __LINE__, "Err = 4 (Double reference), Pos = 0",
+ "%s", buffer);
+# else
+ nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 9",
+ "%s", buffer);
+# endif
+#else
+ nerrors += (rc != -1);
+#endif
+ /* Error: Reference gap */
+ rc = trio_snprintf(buffer, sizeof(buffer), "%3$d %1$d", 31, 32, 33);
+#if TRIO_ERRORS
+ trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
+ TRIO_ERROR_CODE(rc),
+ TRIO_ERROR_NAME(rc),
+ TRIO_ERROR_POSITION(rc));
+# if TRIO_UNIX98
+ nerrors += Verify(__FILE__, __LINE__, "Err = 5 (Reference gap), Pos = 1",
+ "%s", buffer);
+# else
+ nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
+ "%s", buffer);
+# endif
+#else
+ nerrors += (rc != -1);
+#endif
+
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyScanningOneInteger
+TRIO_ARGS5((file, line, expected, format, original),
+ TRIO_CONST char *file,
+ int line,
+ TRIO_CONST char *expected,
+ TRIO_CONST char *format,
+ int original)
+{
+ int number;
+ char data[512];
+
+ trio_snprintf(data, sizeof(data), format, original);
+ trio_sscanf(data, format, &number);
+ return Verify(file, line, expected, format, number);
+}
+
+int
+VerifyScanningIntegers(TRIO_NOARGS)
+{
+ int nerrors = 0;
+
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
+ "%i", 42);
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
+ "%d", 42);
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "-42",
+ "%d", -42);
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2147483647",
+ "%d", 2147483647);
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
+ "%u", 42);
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2a",
+ "%x", 42);
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "52",
+ "%o", 42);
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "101010",
+ "%..2i", 42);
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "0x2a",
+ "%#x", 42);
+ nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "052",
+ "%#o", 42);
+
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyScanningOneFloat
+TRIO_ARGS5((file, line, expected, format, original),
+ TRIO_CONST char *file,
+ int line,
+ TRIO_CONST char *expected,
+ TRIO_CONST char *format,
+ double original)
+{
+ double number;
+ char data[512];
+
+ trio_snprintf(data, sizeof(data), format, original);
+ trio_sscanf(data, format, &number);
+ return Verify(file, line, expected, format, number);
+}
+
+int
+VerifyScanningFloats(TRIO_NOARGS)
+{
+ int nerrors = 0;
+
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42.000000",
+ "%f", 42.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-42.000000",
+ "%f", -42.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000e+01",
+ "%e", 42.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000E+01",
+ "%E", 42.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42",
+ "%g", 42.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
+ "%g", 1234567.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e-06",
+ "%g", 1.234567e-6);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457E+06",
+ "%G", 1234567.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
+ "%12e", 1234567.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234500e+00",
+ "%6e", 1234567.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
+ "%.6e", 1234567.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.2345670000e+06",
+ "%.10e", 1234567.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
+ "%.6g", 1234567.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1234567",
+ "%.10g", 1234567.0);
+#if TRIO_C99
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x2.ap+4",
+ "%a", 42.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x1.2d687p+20",
+ "%a", 1234567.0);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0X1.2D687P+20",
+ "%A", 1234567.0);
+#endif
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.79769e+308",
+ "%g", 1.79769e+308);
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "nan",
+ "%f", trio_nan());
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "NAN",
+ "%F", trio_nan());
+ nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-inf",
+ "%f", trio_ninf());
+
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyScanningOneString
+TRIO_ARGS5((file, line, expected, format, original),
+ TRIO_CONST char *file,
+ int line,
+ TRIO_CONST char *expected,
+ TRIO_CONST char *format,
+ char *original)
+{
+ char string[512];
+ char data[512];
+
+ trio_snprintf(data, sizeof(data), "%s", original);
+ trio_sscanf(data, format, string);
+ return Verify(file, line, expected, "%s", string);
+}
+
+int
+VerifyScanningStrings(TRIO_NOARGS)
+{
+ int nerrors = 0;
+
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
+ "%s", "hello");
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
+ "%s", "hello world");
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello world",
+ "%[^\n]", "hello world");
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "(nil)",
+ "%s", NULL);
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
+ "%20s", "hello");
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "he",
+ "%2s", "hello");
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ab",
+ "%[ab]", "abcba");
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
+ "%[abc]", "abcba");
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
+ "%[a-c]", "abcba");
+#if TRIO_EXTENSION
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
+ "%[[:alpha:]]", "abcba");
+#endif
+ nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ba",
+ "%*[ab]c%[^\n]", "abcba");
+
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyScanningRegression(TRIO_NOARGS)
+{
+ int nerrors = 0;
+ int rc;
+ int index;
+ double dnumber;
+ trio_long_double_t ldnumber;
+ long lnumber;
+ int number;
+ char ch;
+
+ rc = trio_sscanf("1.5", "%lf%n", &dnumber, &index);
+ nerrors += Verify(__FILE__, __LINE__, "1 3 1.500000",
+ "%d %d %f", rc, index, dnumber);
+ rc = trio_sscanf("q 123", "%c%ld", &ch, &lnumber);
+ nerrors += Verify(__FILE__, __LINE__, "q 123",
+ "%c %ld", ch, lnumber);
+ rc = trio_sscanf("abc", "%*s%n", &number);
+ nerrors += Verify(__FILE__, __LINE__, "0 3",
+ "%d %d", rc, number);
+ rc = trio_sscanf("abc def", "%*s%n", &number);
+ nerrors += Verify(__FILE__, __LINE__, "0 3",
+ "%d %d", rc, number);
+ rc = trio_sscanf("0.141882295971771490", "%lf", &dnumber);
+ number = 33;
+ rc = trio_sscanf("total 1", "total %d", &number);
+ nerrors += Verify(__FILE__, __LINE__, "1 1",
+ "%d %d", rc, number);
+#if defined(TRIO_BREESE)
+ nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771488",
+ "%d %.18f", rc, dnumber);
+ rc = trio_sscanf("0.141882295971771490", "%Lf", &ldnumber);
+ nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771490",
+ "%d %.18Lf", rc, ldnumber);
+#endif
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyScanning(TRIO_NOARGS)
+{
+ int nerrors = 0;
+
+ nerrors += VerifyScanningIntegers();
+ nerrors += VerifyScanningFloats();
+ nerrors += VerifyScanningStrings();
+ nerrors += VerifyScanningRegression();
+
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyStrings(TRIO_NOARGS)
+{
+ int nerrors = 0;
+#if !defined(TRIO_MINIMAL)
+ char buffer[512];
+ double dnumber;
+ float fnumber;
+ char *end;
+
+ /* Comparison */
+ trio_copy(buffer, "Find me now");
+ if (trio_length(buffer) != sizeof("Find me now") - 1) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (!trio_equal(buffer, "Find me now")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (!trio_equal_case(buffer, "Find me now")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (trio_equal_case(buffer, "FIND ME NOW")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (!trio_equal_max(buffer, sizeof("Find me") - 1, "Find ME")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (!trio_contains(buffer, "me")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (trio_contains(buffer, "and me")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (trio_substring(buffer, "me") == NULL) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (trio_substring_max(buffer, 4, "me") != NULL) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (!trio_match(buffer, "* me *")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (trio_match_case(buffer, "* ME *")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (trio_index(buffer, 'n') == NULL) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (trio_index(buffer, '_') != NULL) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (trio_index_last(buffer, 'n') == NULL) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+
+ /* Append */
+ trio_copy(buffer, "Find me now");
+ if (!trio_append(buffer, " and again")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (!trio_equal(buffer, "Find me now and again")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (!trio_append_max(buffer, 0, "should not appear")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (!trio_equal(buffer, "Find me now and again")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+
+ /* To upper/lower */
+ trio_copy(buffer, "Find me now");
+ trio_upper(buffer);
+ if (!trio_equal_case(buffer, "FIND ME NOW")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ trio_lower(buffer);
+ if (!trio_equal_case(buffer, "find me now")) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+
+ /* Double conversion */
+ trio_copy(buffer, "3.1415");
+ dnumber = trio_to_double(buffer, NULL);
+ if (!DOUBLE_EQUAL(dnumber, 3.1415)) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ fnumber = trio_to_float(buffer, NULL);
+ if (!FLOAT_EQUAL(fnumber, 3.1415)) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+
+ /* Long conversion */
+ trio_copy(buffer, "3.1415");
+ if (trio_to_long(buffer, NULL, 10) != 3L) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ if (trio_to_long(buffer, NULL, 4) != 3L) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+ trio_to_long(buffer, &end, 2);
+ if (end != buffer) {
+ nerrors++;
+ Report0(__FILE__, __LINE__);
+ }
+
+#endif /* !defined(TRIO_MINIMAL) */
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyDynamicStrings(TRIO_NOARGS)
+{
+ int nerrors = 0;
+#if !defined(TRIO_MINIMAL)
+ trio_string_t *string;
+
+ string = trio_xstring_duplicate("Find me now");
+ if (string == NULL) {
+ nerrors++;
+ goto error;
+ }
+ if (!trio_xstring_equal(string, "FIND ME NOW"))
+ nerrors++;
+ if (!trio_xstring_append(string, " and again") ||
+ !trio_xstring_equal(string, "FIND ME NOW AND AGAIN"))
+ nerrors++;
+ if (!trio_xstring_contains(string, "me"))
+ nerrors++;
+ if (trio_xstring_contains(string, "ME"))
+ nerrors++;
+ if (!trio_xstring_match(string, "* me *"))
+ nerrors++;
+ if (trio_xstring_match_case(string, "* ME *"))
+ nerrors++;
+
+ error:
+ if (string)
+ trio_string_destroy(string);
+
+#endif /* !defined(TRIO_MINIMAL) */
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+VerifyNaN(TRIO_NOARGS)
+{
+ double ninf_number = trio_ninf();
+ double pinf_number = trio_pinf();
+ double nan_number = trio_nan();
+ int nerrors = 0;
+
+ nerrors += Verify(__FILE__, __LINE__, "-1",
+ "%d", trio_isinf(ninf_number));
+ nerrors += Verify(__FILE__, __LINE__, "0",
+ "%d", trio_isinf(42.0));
+ nerrors += Verify(__FILE__, __LINE__, "1",
+ "%d", trio_isinf(pinf_number));
+ nerrors += Verify(__FILE__, __LINE__, "1",
+ "%d", trio_isnan(nan_number));
+ nerrors += Verify(__FILE__, __LINE__, "0",
+ "%d", trio_isnan(42.0));
+
+ return nerrors;
+}
+
+/*************************************************************************
+ *
+ */
+int
+main(TRIO_NOARGS)
+{
+ int nerrors = 0;
+
+ printf("%s\n", rcsid);
+
+ /* Override system locale settings */
+ trio_locale_set_decimal_point(".");
+ trio_locale_set_thousand_separator(",");
+ trio_locale_set_grouping("\3");
+
+ printf("Verifying strings\n");
+ nerrors += VerifyStrings();
+
+ printf("Verifying dynamic strings\n");
+ nerrors += VerifyDynamicStrings();
+
+ printf("Verifying special quantities\n");
+ nerrors += VerifyNaN();
+
+ printf("Verifying formatting\n");
+ nerrors += VerifyFormatting();
+
+ printf("Verifying scanning\n");
+ nerrors += VerifyScanning();
+
+ printf("Verifying return values\n");
+ nerrors += VerifyErrors();
+ nerrors += VerifyReturnValues();
+
+ printf("Verifying allocation\n");
+ nerrors += VerifyAllocate();
+
+ if (nerrors == 0)
+ printf("Regression test suceeded\n");
+ else
+ printf("Regression test failed in %d instance(s)\n", nerrors);
+
+ return nerrors ? 1 : 0;
+}