add remaining tests from libc-testsuit
authornsz <nsz@port70.net>
Thu, 4 Aug 2011 22:56:27 +0000 (00:56 +0200)
committernsz <nsz@port70.net>
Thu, 4 Aug 2011 22:56:27 +0000 (00:56 +0200)
src/stdio/snprintf.c [new file with mode: 0644]
src/stdio/sscanf.c [new file with mode: 0644]
src/stdio/swprintf.c [new file with mode: 0644]
src/stdio/ungetc.c [new file with mode: 0644]
src/stdlib/strtod.c [new file with mode: 0644]
src/stdlib/strtol.c [new file with mode: 0644]
src/stdlib/wcstol.c [new file with mode: 0644]
src/thread/sem.c [new file with mode: 0644]

diff --git a/src/stdio/snprintf.c b/src/stdio/snprintf.c
new file mode 100644 (file)
index 0000000..f8768a8
--- /dev/null
@@ -0,0 +1,164 @@
+#define _XOPEN_SOURCE 700
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+#include "test.h"
+
+#define DISABLE_SLOW_TESTS
+
+#define TEST(r, f, x, m) ( \
+       ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", #f, r, x), 0) )
+
+#define TEST_S(s, x, m) ( \
+       !strcmp((s),(x)) || \
+       (error("[%s] != [%s] (%s)\n", s, x, m), 0) )
+
+static const struct {
+       const char *fmt;
+       int i;
+       const char *expect;
+} int_tests[] = {
+       /* width, precision, alignment */
+       { "%04d", 12, "0012" },
+       { "%.3d", 12, "012" },
+       { "%3d", 12, " 12" },
+       { "%-3d", 12, "12 " },
+       { "%+3d", 12, "+12" },
+       { "%+-5d", 12, "+12  " },
+       { "%+- 5d", 12, "+12  " },
+       { "%- 5d", 12, " 12  " },
+       { "% d", 12, " 12" },
+       { "%0-5d", 12, "12   " },
+       { "%-05d", 12, "12   " },
+
+       /* ...explicit precision of 0 shall be no characters. */
+       { "%.0d", 0, "" },
+       { "%.0o", 0, "" },
+       { "%#.0d", 0, "" },
+       { "%#.0o", 0, "" },
+       { "%#.0x", 0, "" },
+
+       /* ...but it still has to honor width and flags. */
+       { "%2.0u", 0, "  " },
+       { "%02.0u", 0, "  " },
+       { "%2.0d", 0, "  " },
+       { "%02.0d", 0, "  " },
+       { "% .0d", 0, " " },
+       { "%+.0d", 0, "+" },
+
+       /* hex: test alt form and case */
+       { "%x", 63, "3f" },
+       { "%#x", 63, "0x3f" },
+       { "%X", 63, "3F" },
+
+       /* octal: test alt form */
+       { "%o", 15, "17" },
+       { "%#o", 15, "017" },
+
+       { NULL, 0.0, NULL }
+};
+
+static const struct {
+       const char *fmt;
+       double f;
+       const char *expect;
+} fp_tests[] = {
+       /* basic form, handling of exponent/precision for 0 */
+       { "%e", 0.0, "0.000000e+00" },
+       { "%f", 0.0, "0.000000" },
+       { "%g", 0.0, "0" },
+       { "%#g", 0.0, "0.00000" },
+
+       /* rounding */
+       { "%f", 1.1, "1.100000" },
+       { "%f", 1.2, "1.200000" },
+       { "%f", 1.3, "1.300000" },
+       { "%f", 1.4, "1.400000" },
+       { "%f", 1.5, "1.500000" },
+       { "%.4f", 1.06125, "1.0612" },
+       { "%.2f", 1.375, "1.38" },
+       { "%.1f", 1.375, "1.4" },
+       { "%.15f", 1.1, "1.100000000000000" },
+       { "%.16f", 1.1, "1.1000000000000001" },
+       { "%.17f", 1.1, "1.10000000000000009" },
+       { "%.2e", 1500001.0, "1.50e+06" },
+       { "%.2e", 1505000.0, "1.50e+06" },
+       { "%.2e", 1505000.00000095367431640625, "1.51e+06" },
+       { "%.2e", 1505001.0, "1.51e+06" },
+       { "%.2e", 1506000.0, "1.51e+06" },
+       
+       /* correctness in DBL_DIG places */
+       { "%.15g", 1.23456789012345, "1.23456789012345" },
+
+       /* correct choice of notation for %g */
+       { "%g", 0.0001, "0.0001" },
+       { "%g", 0.00001, "1e-05" },
+       { "%g", 123456, "123456" },
+       { "%g", 1234567, "1.23457e+06" },
+       { "%.7g", 1234567, "1234567" },
+       { "%.7g", 12345678, "1.234568e+07" },
+       { "%.8g", 0.1, "0.1" },
+       { "%.9g", 0.1, "0.1" },
+       { "%.10g", 0.1, "0.1" },
+       { "%.11g", 0.1, "0.1" },
+
+       /* pi in double precision, printed to a few extra places */
+       { "%.15f", M_PI, "3.141592653589793" },
+       { "%.18f", M_PI, "3.141592653589793116" },
+
+       /* exact conversion of large integers */
+       { "%.0f", 340282366920938463463374607431768211456.0,
+                "340282366920938463463374607431768211456" },
+
+       { NULL, 0.0, NULL }
+};
+
+void test_snprintf(void)
+{
+       int i, j, k;
+       char b[2000], *s;
+
+       TEST(i, snprintf(0, 0, "%d", 123456), 6, "length returned %d != %d");
+       TEST(i, snprintf(0, 0, "%.4s", "hello"), 4, "length returned %d != %d");
+       TEST(i, snprintf(b, 0, "%.0s", "goodbye"), 0, "length returned %d != %d");
+
+       strcpy(b, "xxxxxxxx");
+       TEST(i, snprintf(b, 4, "%d", 123456), 6, "length returned %d != %d");
+       TEST_S(b, "123", "incorrect output");
+       TEST(i, b[5], 'x', "buffer overrun");
+
+       /* Perform ascii arithmetic to test printing tiny doubles */
+       TEST(i, snprintf(b, sizeof b, "%.1022f", 0x1p-1021), 1024, "%d != %d");
+       b[1] = '0';
+       for (i=0; i<1021; i++) {
+               for (k=0, j=1023; j>0; j--) {
+                       if (b[j]<'5') b[j]+=b[j]-'0'+k, k=0;
+                       else b[j]+=b[j]-'0'-10+k, k=1;
+               }
+       }
+       TEST(i, b[1], '1', "'%c' != '%c'");
+       for (j=2; b[j]=='0'; j++);
+       TEST(i, j, 1024, "%d != %d");
+
+
+#ifndef DISABLE_SLOW_TESTS
+       errno = 0;
+       TEST(i, snprintf(NULL, 0, "%.*u", 2147483647, 0), 2147483647, "cannot print max length %d");
+       TEST(i, snprintf(NULL, 0, "%.*u ", 2147483647, 0), -1, "integer overflow %d");
+       TEST(i, errno, EOVERFLOW, "after overflow: %d != %d");
+#endif
+       for (j=0; int_tests[j].fmt; j++) {
+               TEST(i, snprintf(b, sizeof b, int_tests[j].fmt, int_tests[j].i), strlen(b), "%d != %d");
+               TEST_S(b, int_tests[j].expect, "bad integer conversion");
+       }
+
+       for (j=0; fp_tests[j].fmt; j++) {
+               TEST(i, snprintf(b, sizeof b, fp_tests[j].fmt, fp_tests[j].f), strlen(b), "%d != %d");
+               TEST_S(b, fp_tests[j].expect, "bad floating point conversion");
+       }
+
+       TEST(i, snprintf(0, 0, "%.4a", 1.0), 11, "%d != %d");
+}
diff --git a/src/stdio/sscanf.c b/src/stdio/sscanf.c
new file mode 100644 (file)
index 0000000..0d49431
--- /dev/null
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include "test.h"
+
+#define TEST(r, f, x, m) ( \
+       ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", #f, r, x), 0) )
+
+#define TEST_S(s, x, m) ( \
+       !strcmp((s),(x)) || \
+       (error("[%s] != [%s] (%s)\n", s, x, m), 0) )
+
+#define TEST_F(x) ( \
+       TEST(i, sscanf(# x, "%lf", &d), 1, "got %d fields, expected %d"), \
+       TEST(t, d, (double)x, "%g != %g") )
+
+void test_sscanf(void) {
+       int i;
+       char a[100], b[100];
+       int x, y, z, u, v;
+       double d, t;
+
+       TEST(i, sscanf("hello, world\n", "%s %s", a, b), 2, "only %d fields, expected %d");
+       TEST_S(a, "hello,", "");
+       TEST_S(b, "world", "");
+
+       TEST(i, sscanf("hello, world\n", "%[hel]%s", a, b), 2, "only %d fields, expected %d");
+       TEST_S(a, "hell", "");
+       TEST_S(b, "o,", "");
+
+       TEST(i, sscanf("hello, world\n", "%[hel] %s", a, b), 2, "only %d fields, expected %d");
+       TEST_S(a, "hell", "");
+       TEST_S(b, "o,", "");
+
+       a[8] = 'X';
+       a[9] = 0;
+       TEST(i, sscanf("hello, world\n", "%8c%8c", a, b), 1, "%d fields, expected %d");
+       TEST_S(a, "hello, wX", "");
+
+       TEST(i, sscanf("56789 0123 56a72", "%2d%d%*d %[0123456789]\n", &x, &y, a), 3, "only %d fields, expected %d");
+       TEST(i, x, 56, "%d != %d");
+       TEST(i, y, 789, "%d != %d");
+       TEST_S(a, "56", "");
+
+       TEST(i, sscanf("011 0x100 11 0x100 100", "%i %i %o %x %x\n", &x, &y, &z, &u, &v), 5, "only %d fields, expected %d");
+       TEST(i, x, 9, "%d != %d");
+       TEST(i, y, 256, "%d != %d");
+       TEST(i, z, 9, "%d != %d");
+       TEST(i, u, 256, "%d != %d");
+       TEST(i, v, 256, "%d != %d");
+
+       TEST(i, sscanf("20 xyz", "%d %d\n", &x, &y), 1, "only %d fields, expected %d");
+       TEST(i, x, 20, "%d != %d");
+
+       TEST(i, sscanf("xyz", "%d\n", &x, &y), 0, "got %d fields, expected no match (%d)");
+
+       TEST(i, sscanf("", "%d\n", &x, &y), -1, "got %d fields, expected input failure (%d)");
+
+       TEST(i, sscanf(" 12345 6", "%2d%d%d", &x, &y, &z), 3, "only %d fields, expected %d");
+       TEST(i, x, 12, "%d != %d");
+       TEST(i, y, 345, "%d != %d");
+       TEST(i, z, 6, "%d != %d");
+
+       TEST(i, sscanf(" 0x12 0x34", "%5i%2i", &x, &y), 1, "got %d fields, expected %d");
+       TEST(i, x, 0x12, "%d != %d");
+
+       TEST_F(123);
+       TEST_F(123.0);
+       TEST_F(123.0e+0);
+       TEST_F(123.0e+4);
+       TEST_F(1.234e1234);
+       TEST_F(1.234e-1234);
+       TEST_F(1.234e56789);
+       TEST_F(1.234e-56789);
+       TEST_F(-0.5);
+       TEST_F(0.1);
+       TEST_F(0.2);
+       TEST_F(0.1e-10);
+       TEST_F(0x1234p56);
+
+       TEST(i, sscanf("10e", "%lf", &d), 0, "got %d fields, expected no match (%d)");
+       TEST(i, sscanf("", "%lf\n", &d), -1, "got %d fields, expected input failure (%d)");
+}
diff --git a/src/stdio/swprintf.c b/src/stdio/swprintf.c
new file mode 100644 (file)
index 0000000..f05b150
--- /dev/null
@@ -0,0 +1,136 @@
+#define _XOPEN_SOURCE 700
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+#include <wchar.h>
+#include <locale.h>
+#include <langinfo.h>
+#include "test.h"
+
+#define TEST(r, f, x, m) ( \
+       ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", #f, r, x), 0) )
+
+#define TEST_S(s, x, m) ( \
+       !wcscmp((s),(x)) || \
+       (error("[%ls] != [%ls] (%s)\n", s, x, m), 0) )
+
+static const struct {
+       const wchar_t *fmt;
+       int i;
+       const wchar_t *expect;
+} int_tests[] = {
+       /* width, precision, alignment */
+       { L"%04d", 12, L"0012" },
+       { L"%.3d", 12, L"012" },
+       { L"%3d", 12, L" 12" },
+       { L"%-3d", 12, L"12 " },
+       { L"%+3d", 12, L"+12" },
+       { L"%+-5d", 12, L"+12  " },
+       { L"%+- 5d", 12, L"+12  " },
+       { L"%- 5d", 12, L" 12  " },
+       { L"% d", 12, L" 12" },
+       { L"%0-5d", 12, L"12   " },
+       { L"%-05d", 12, L"12   " },
+
+       /* ...explicit precision of 0 shall be no characters. */
+       { L"%.0d", 0, L"" },
+       { L"%.0o", 0, L"" },
+       { L"%#.0d", 0, L"" },
+       { L"%#.0o", 0, L"" },
+       { L"%#.0x", 0, L"" },
+
+       /* hex: test alt form and case */
+       { L"%x", 63, L"3f" },
+       { L"%#x", 63, L"0x3f" },
+       { L"%X", 63, L"3F" },
+
+       /* octal: test alt form */
+       { L"%o", 15, L"17" },
+       { L"%#o", 15, L"017" },
+
+       { NULL, 0.0, NULL }
+};
+
+static const struct {
+       const wchar_t *fmt;
+       double f;
+       const wchar_t *expect;
+} fp_tests[] = {
+       /* basic form, handling of exponent/precision for 0 */
+       { L"%e", 0.0, L"0.000000e+00" },
+       { L"%f", 0.0, L"0.000000" },
+       { L"%g", 0.0, L"0" },
+       { L"%#g", 0.0, L"0.00000" },
+
+       /* rounding */
+       { L"%f", 1.1, L"1.100000" },
+       { L"%f", 1.2, L"1.200000" },
+       { L"%f", 1.3, L"1.300000" },
+       { L"%f", 1.4, L"1.400000" },
+       { L"%f", 1.5, L"1.500000" },
+       
+       /* correctness in DBL_DIG places */
+       { L"%.15g", 1.23456789012345, L"1.23456789012345" },
+
+       /* correct choice of notation for %g */
+       { L"%g", 0.0001, L"0.0001" },
+       { L"%g", 0.00001, L"1e-05" },
+       { L"%g", 123456, L"123456" },
+       { L"%g", 1234567, L"1.23457e+06" },
+       { L"%.7g", 1234567, L"1234567" },
+       { L"%.7g", 12345678, L"1.234568e+07" },
+
+       /* pi in double precision, printed to a few extra places */
+       { L"%.15f", M_PI, L"3.141592653589793" },
+       { L"%.18f", M_PI, L"3.141592653589793116" },
+
+       /* exact conversion of large integers */
+       { L"%.0f", 340282366920938463463374607431768211456.0,
+                L"340282366920938463463374607431768211456" },
+
+       { NULL, 0.0, NULL }
+};
+
+void test_swprintf(void) {
+       int i, j;
+       wchar_t b[500], *s;
+
+       setlocale(LC_CTYPE, "en_US.UTF-8") ||
+       setlocale(LC_CTYPE, "en_GB.UTF-8") ||
+       setlocale(LC_CTYPE, "en.UTF-8") ||
+       setlocale(LC_CTYPE, "POSIX.UTF-8") ||
+       setlocale(LC_CTYPE, "C.UTF-8") ||
+       setlocale(LC_CTYPE, "UTF-8") ||
+       setlocale(LC_CTYPE, "");
+
+       TEST(i, strcmp(nl_langinfo(CODESET), "UTF-8"), 0, "no UTF-8 locale; tests might fail");
+
+       TEST(i, swprintf(0, 0, L"%d", 123456)<0, 1, "%d != %d");
+
+       TEST(i, swprintf(b, 2, L"%lc", 0xc0), 1, "%d != %d");
+       TEST(i, b[0], 0xc0, "wrong character %x != %x");
+       TEST(i, swprintf(b, 2, L"%lc", 0x20ac), 1, "%d != %d");
+       TEST(i, b[0], 0x20ac, "wrong character %x != %x");
+       TEST(i, swprintf(b, 3, L"%s", "\xc3\x80!"), 2, "%d != %d");
+       TEST(i, b[0], 0xc0, "wrong character %x != %x");
+       TEST(i, swprintf(b, 2, L"%.1s", "\xc3\x80!"), 1, "%d != %d");
+       TEST(i, b[0], 0xc0, "wrong character %x != %x");
+
+       wcscpy(b, L"xxxxxxxx");
+       TEST(i, swprintf(b, 4, L"%d", 123456)<0, 1, "%d != %d");
+       TEST_S(b, L"123", "incorrect output");
+       TEST(i, b[5], 'x', "buffer overrun");
+
+       for (j=0; int_tests[j].fmt; j++) {
+               TEST(i, swprintf(b, sizeof b/sizeof *b, int_tests[j].fmt, int_tests[j].i), wcslen(b), "%d != %d");
+               TEST_S(b, int_tests[j].expect, "bad integer conversion");
+       }
+
+       for (j=0; fp_tests[j].fmt; j++) {
+               TEST(i, swprintf(b, sizeof b/sizeof *b, fp_tests[j].fmt, fp_tests[j].f), wcslen(b), "%d != %d");
+               TEST_S(b, fp_tests[j].expect, "bad floating point conversion");
+       }
+}
diff --git a/src/stdio/ungetc.c b/src/stdio/ungetc.c
new file mode 100644 (file)
index 0000000..855ffaa
--- /dev/null
@@ -0,0 +1,52 @@
+#define _POSIX_C_SOURCE 200809L
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include "test.h"
+
+#define TEST(r, f, x, m) ( \
+       errno = 0, ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", #f, r, x, strerror(errno)), 0) )
+
+#define TEST_S(s, x, m) ( \
+       !strcmp((s),(x)) || \
+       (error("[%s] != [%s] (%s)\n", s, x, m), 0) )
+
+void test_ungetc(void) {
+       int i;
+       char a[100];
+       FILE *f;
+
+       TEST(i, !(f = tmpfile()), 0, "failed to create temp file %d!=%d (%s)");
+
+       if (!f) return;
+
+       TEST(i, fprintf(f, "hello, world\n"), 13, "%d != %d (%m)");
+       TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d (%m)");
+
+       TEST(i, feof(f), 0, "%d != %d");
+       TEST(i, fgetc(f), 'h', "'%c' != '%c'");
+       TEST(i, ftell(f), 1, "%d != %d");
+       TEST(i, ungetc('x', f), 'x', "%d != %d");
+       TEST(i, ftell(f), 0, "%d != %d");
+       TEST(i, fscanf(f, "%[h]", a), 0, "got %d fields, expected %d");
+       TEST(i, ftell(f), 0, "%d != %d");
+       TEST(i, fgetc(f), 'x', "'%c' != '%c'");
+       TEST(i, ftell(f), 1, "%d != %d");
+
+       TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d");
+       TEST(i, ungetc('x', f), 'x', "%d != %d");
+       TEST(i, fread(a, 1, sizeof a, f), 14, "read %d, expected %d");
+       a[14] = 0;
+       TEST_S(a, "xhello, world\n", "mismatch reading ungot character");
+
+       TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d");
+       TEST(i, fscanf(f, "%[x]", a), 0, "got %d fields, expected %d");
+       TEST(i, ungetc('x', f), 'x', "unget failed after fscanf: %d != %d");
+       TEST(i, fgetc(f), 'x', "'%c' != '%c'");
+       TEST(i, fgetc(f), 'h', "'%c' != '%c'");
+
+       fclose(f);
+}
diff --git a/src/stdlib/strtod.c b/src/stdlib/strtod.c
new file mode 100644 (file)
index 0000000..a4a8b53
--- /dev/null
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "test.h"
+
+/* r = place to store result
+ * f = function call to test (or any expression)
+ * x = expected result
+ * m = message to print on failure (with formats for r & x)
+**/
+
+#define TEST(r, f, x, m) ( \
+       ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", #f, r, x, r-x), 0) )
+
+void test_strtod(void) {
+       int i;
+       double d, d2;
+       char buf[1000];
+
+       for (i=0; i<100; i++) {
+               d = sin(i);
+               snprintf(buf, sizeof buf, "%.300f", d);
+               TEST(d2, strtod(buf, 0), d, "round trip fail %a != %a (%a)");
+       }
+
+       TEST(d, strtod("0x1p4", 0), 16.0, "hex float %a != %a");
+       TEST(d, strtod("0x1.1p4", 0), 17.0, "hex float %a != %a");
+}
diff --git a/src/stdlib/strtol.c b/src/stdlib/strtol.c
new file mode 100644 (file)
index 0000000..7d9213f
--- /dev/null
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "test.h"
+
+/* r = place to store result
+ * f = function call to test (or any expression)
+ * x = expected result
+ * m = message to print on failure (with formats for r & x)
+**/
+
+#define TEST(r, f, x, m) ( \
+       errno = 0, msg = #f, ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", #f, r, x), 0) )
+
+#define TEST2(r, f, x, m) ( \
+       ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", msg, r, x), 0) )
+
+void test_strtol(void) {
+       int i;
+       long l;
+       unsigned long ul;
+       char *msg="";
+       char *s, *c;
+
+       TEST(l, atol("2147483647"), 2147483647L, "max 32bit signed %ld != %ld");
+       TEST(l, strtol("2147483647", 0, 0), 2147483647L, "max 32bit signed %ld != %ld");
+       TEST(ul, strtoul("4294967295", 0, 0), 4294967295UL, "max 32bit unsigned %lu != %lu");
+
+       if (sizeof(long) == 4) {
+               TEST(l, strtol(s="2147483648", &c, 0), 2147483647L, "uncaught overflow %ld != %ld");
+               TEST2(i, c-s, 10, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(l, strtol(s="-2147483649", &c, 0), -2147483647L-1, "uncaught overflow %ld != %ld");
+               TEST2(i, c-s, 11, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, strtoul(s="4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 10, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, strtoul(s="-1", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 2, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, strtoul(s="-2", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 2, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, strtoul(s="-2147483648", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 11, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, strtoul(s="-2147483649", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 11, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+       } else {
+               TEST(i, 0, 1, "64bit tests not implemented");
+       }
+
+       TEST(l, strtol("z", 0, 36), 35, "%ld != %ld");
+       TEST(l, strtol("00010010001101000101011001111000", 0, 2), 0x12345678, "%ld != %ld");
+       TEST(l, strtol(s="0F5F", &c, 16), 0x0f5f, "%ld != %ld");
+
+       TEST(l, strtol(s="0xz", &c, 16), 0, "%ld != %ld");
+       TEST2(i, c-s, 1, "wrong final position %ld != %ld");
+
+       TEST(l, strtol(s="0x1234", &c, 16), 0x1234, "%ld != %ld");
+       TEST2(i, c-s, 6, "wrong final position %ld != %ld");
+
+       c = NULL;
+       TEST(l, strtol(s="123", &c, 37), 0, "%ld != %ld");
+       TEST2(i, c-s, 0, "wrong final position %d != %d");
+       TEST2(i, errno, EINVAL, "%d != %d");
+}
diff --git a/src/stdlib/wcstol.c b/src/stdlib/wcstol.c
new file mode 100644 (file)
index 0000000..fe8d747
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <wchar.h>
+#include "test.h"
+
+#define TEST(r, f, x, m) ( \
+       errno = 0, msg = #f, ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", #f, r, x), 0) )
+
+#define TEST2(r, f, x, m) ( \
+       ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", msg, r, x), 0) )
+
+void test_wcstol(void) {
+       int i;
+       long l;
+       unsigned long ul;
+       char *msg="";
+       wchar_t *s, *c;
+
+       TEST(l, wcstol(L"2147483647", 0, 0), 2147483647L, "max 32bit signed %ld != %ld");
+       TEST(ul, wcstoul(L"4294967295", 0, 0), 4294967295UL, "max 32bit unsigned %lu != %lu");
+
+       if (sizeof(long) == 4) {
+               TEST(l, wcstol(s=L"2147483648", &c, 0), 2147483647L, "uncaught overflow %ld != %ld");
+               TEST2(i, c-s, 10, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(l, wcstol(s=L"-2147483649", &c, 0), -2147483647L-1, "uncaught overflow %ld != %ld");
+               TEST2(i, c-s, 11, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, wcstoul(s=L"4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 10, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, wcstoul(s=L"-1", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 2, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, wcstoul(s=L"-2", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 2, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, wcstoul(s=L"-2147483648", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 11, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+               TEST(ul, wcstoul(s=L"-2147483649", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
+               TEST2(i, c-s, 11, "wrong final position %d != %d");
+               TEST2(i, errno, ERANGE, "missing errno %d != %d");
+       } else {
+               TEST(i, 0, 1, "64bit tests not implemented");
+       }
+
+       TEST(l, wcstol(L"z", 0, 36), 35, "%ld != %ld");
+       TEST(l, wcstol(L"00010010001101000101011001111000", 0, 2), 0x12345678, "%ld != %ld");
+
+       TEST(l, wcstol(s=L"0xz", &c, 16), 0, "%ld != %ld");
+       TEST2(i, c-s, 1, "wrong final position %ld != %ld");
+
+       TEST(l, wcstol(s=L"0x1234", &c, 16), 0x1234, "%ld != %ld");
+       TEST2(i, c-s, 6, "wrong final position %ld != %ld");
+
+       c = NULL;
+       TEST(l, wcstol(s=L"123", &c, 37), 0, "%ld != %ld");
+       TEST2(i, c-s, 0, "wrong final position %d != %d");
+       TEST2(i, errno, EINVAL, "%d != %d");
+}
diff --git a/src/thread/sem.c b/src/thread/sem.c
new file mode 100644 (file)
index 0000000..6840cd2
--- /dev/null
@@ -0,0 +1,52 @@
+#define _POSIX_C_SOURCE 200809L
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <semaphore.h>
+#include <time.h>
+#include <fcntl.h>
+#include "test.h"
+
+#define TEST(r, f, x, m) ( \
+       ((r) = (f)) == (x) || \
+       (error("%s failed (" m ")\n", #f, r, x), 0) )
+
+#define TEST_S(s, x, m) ( \
+       !strcmp((s),(x)) || \
+       (error("[%s] != [%s] (%s)\n", s, x, m), 0) )
+
+void test_sem(void)
+{
+       int r;
+       void *res;
+       char buf[100];
+       struct timespec ts;
+       sem_t *sem, *sem2;
+       int val;
+
+       clock_gettime(CLOCK_REALTIME, &ts);
+       snprintf(buf, sizeof buf, "/testsuite-%d-%d", (int)getpid(), (int)ts.tv_nsec);
+
+       TEST(r, !(sem=sem_open(buf, O_CREAT|O_EXCL, 0700, 1)), 0, "could not open sem");
+
+       TEST(r, sem_getvalue(sem, &val), 0, "failed to get sem value");
+       TEST(r, val, 1, "wrong initial semaphore value");
+
+       TEST(r, !(sem2=sem_open(buf, 0)), 0, "could not reopen sem");
+       TEST(r, sem!=sem2, 0, "reopened sem has different address");
+
+       TEST(r, sem_wait(sem), 0, "failed on sem wait");
+       TEST(r, sem_getvalue(sem2, &val), 0, "failed to get sem value");
+       TEST(r, val, 0, "wrong semaphore value on second handle");
+
+       TEST(r, sem_post(sem), 0, "failed on sem post");
+       TEST(r, sem_getvalue(sem2, &val), 0, "failed to get sem value");
+       TEST(r, val, 1, "wrong semaphore value on second handle");
+
+       TEST(r, sem_close(sem), 0, "failed to close sem");
+       TEST(r, sem_close(sem), 0, "failed to close sem second time");
+       TEST(r, sem_unlink(buf), 0, "failed to unlink sem");
+}