diff options
author | Mike Frysinger <vapier@gentoo.org> | 2006-03-01 01:07:36 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2006-03-01 01:07:36 +0000 |
commit | efc8d9fbaa8a7bf92dec2f43c6e3b646ce3bb723 (patch) | |
tree | afb595e5813e4948b14e52766a4f1850520a003f /test/time | |
parent | 6fdc49d6b5478bdb8326e3c15ac88d863ec416cc (diff) |
grab some time tests from glibc
Diffstat (limited to 'test/time')
-rw-r--r-- | test/time/Makefile | 9 | ||||
-rw-r--r-- | test/time/bug-asctime.c | 40 | ||||
-rw-r--r-- | test/time/bug-asctime_r.c | 32 | ||||
-rw-r--r-- | test/time/clocktest.c | 36 | ||||
-rw-r--r-- | test/time/test_time.c | 116 | ||||
-rw-r--r-- | test/time/tst-ftime_l.c | 136 | ||||
-rw-r--r-- | test/time/tst-mktime.c | 70 | ||||
-rw-r--r-- | test/time/tst-mktime2.c | 141 | ||||
-rw-r--r-- | test/time/tst-mktime3.c | 50 | ||||
-rw-r--r-- | test/time/tst-posixtz.c | 88 | ||||
-rw-r--r-- | test/time/tst-strftime.c | 111 | ||||
-rw-r--r-- | test/time/tst-strptime.c | 193 | ||||
-rw-r--r-- | test/time/tst-strptime2.c | 59 | ||||
-rw-r--r-- | test/time/tst-timezone.c | 170 | ||||
-rw-r--r-- | test/time/tst_wcsftime.c | 39 |
15 files changed, 1290 insertions, 0 deletions
diff --git a/test/time/Makefile b/test/time/Makefile new file mode 100644 index 000000000..cbf708526 --- /dev/null +++ b/test/time/Makefile @@ -0,0 +1,9 @@ +# uClibc time tests +# Licensed under the GNU Library General Public License, see COPYING.LIB + +TESTS_DISABLED := bug-asctime time tst-mktime2 tst-posixtz tst-strftime \ + tst-strptime tst-timezone + +include ../Test.mak + +CFLAGS_tst-strptime2 := -std=c99 diff --git a/test/time/bug-asctime.c b/test/time/bug-asctime.c new file mode 100644 index 000000000..149e4e0a2 --- /dev/null +++ b/test/time/bug-asctime.c @@ -0,0 +1,40 @@ +/* Note: we disable this on uClibc because we dont bother + * verifying if the year is sane ... we just return ???? + * for the year value ... + */ + +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <time.h> + + +static int +do_test (void) +{ + int result = 0; + time_t t = time (NULL); + struct tm *tp = localtime (&t); + tp->tm_year = INT_MAX; + errno = 0; + char *s = asctime (tp); + if (s != NULL || errno != EOVERFLOW) + { + printf ("asctime did not fail correctly: s=%p, wanted %p; errno=%i, wanted %i\n", + s, NULL, errno, EOVERFLOW); + result = 1; + } + char buf[1000]; + errno = 0; + s = asctime_r (tp, buf); + if (s != NULL || errno != EOVERFLOW) + { + printf ("asctime_r did not fail correctly: s=%p, wanted %p; errno=%i, wanted %i\n", + s, NULL, errno, EOVERFLOW); + result = 1; + } + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/test/time/bug-asctime_r.c b/test/time/bug-asctime_r.c new file mode 100644 index 000000000..86651ef1c --- /dev/null +++ b/test/time/bug-asctime_r.c @@ -0,0 +1,32 @@ +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <time.h> + + +static int +do_test (void) +{ + int result = 0; + time_t t = time (NULL); + struct tm *tp = localtime (&t); + tp->tm_year = 10000 - 1900; + char buf[1000]; + errno = 0; + buf[26] = '\xff'; + char *s = asctime_r (tp, buf); + if (s != NULL || errno != EOVERFLOW) + { + puts ("asctime_r did not fail correctly"); + result = 1; + } + if (buf[26] != '\xff') + { + puts ("asctime_r overwrote 27th byte in buffer"); + result = 1; + } + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/test/time/clocktest.c b/test/time/clocktest.c new file mode 100644 index 000000000..f2b3ea73a --- /dev/null +++ b/test/time/clocktest.c @@ -0,0 +1,36 @@ +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +volatile int gotit = 0; + +static void +alarm_handler (int signal) +{ + gotit = 1; +} + + +int +main (int argc, char ** argv) +{ + clock_t start, stop; + + if (signal(SIGALRM, alarm_handler) == SIG_ERR) + { + perror ("signal"); + exit (1); + } + alarm(1); + start = clock (); + while (!gotit); + stop = clock (); + + printf ("%ld clock ticks per second (start=%ld,stop=%ld)\n", + stop - start, start, stop); + printf ("CLOCKS_PER_SEC=%ld, sysconf(_SC_CLK_TCK)=%ld\n", + CLOCKS_PER_SEC, sysconf(_SC_CLK_TCK)); + return 0; +} diff --git a/test/time/test_time.c b/test/time/test_time.c new file mode 100644 index 000000000..20216ed9d --- /dev/null +++ b/test/time/test_time.c @@ -0,0 +1,116 @@ +/* Copyright (C) 1991, 1992, 1994, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + + +int +main (int argc, char **argv) +{ + time_t t; + register struct tm *tp; + struct tm tbuf; + int lose = 0; + + --argc; + ++argv; + + do + { + char buf[BUFSIZ]; + if (argc > 0) + { + static char buf[BUFSIZ]; + sprintf(buf, "TZ=%s", *argv); + if (putenv(buf)) + { + puts("putenv failed."); + lose = 1; + } + else + puts (buf); + } + tzset(); + tbuf.tm_year = 72; + tbuf.tm_mon = 0; + tbuf.tm_mday = 31; + tbuf.tm_hour = 6; + tbuf.tm_min = 14; + tbuf.tm_sec = 50; + tbuf.tm_isdst = -1; + doit:; + t = mktime(&tbuf); + if (t == (time_t) -1) + { + puts("mktime() failed?"); + lose = 1; + } + tp = localtime(&t); + if (tp == NULL) + { + puts("localtime() failed."); + lose = 1; + } + else if (strftime(buf, sizeof(buf), "%a %b %d %X %Z %Y", tp) == 0) + { + puts("strftime() failed."); + lose = 1; + } + else + puts(buf); + if (tbuf.tm_year == 101) + { + tbuf.tm_year = 97; + tbuf.tm_mon = 0; + goto doit; + } + ++argv; + } while (--argc > 0); + + { +#define SIZE 256 + char buffer[SIZE]; + time_t curtime; + struct tm *loctime; + + curtime = time (NULL); + + loctime = localtime (&curtime); + + fputs (asctime (loctime), stdout); + + strftime (buffer, SIZE, "Today is %A, %B %d.\n", loctime); + fputs (buffer, stdout); + strftime (buffer, SIZE, "The time is %I:%M %p.\n", loctime); + fputs (buffer, stdout); + + loctime->tm_year = 72; + loctime->tm_mon = 8; + loctime->tm_mday = 12; + loctime->tm_hour = 20; + loctime->tm_min = 49; + loctime->tm_sec = 05; + curtime = mktime (loctime); + strftime (buffer, SIZE, "%D %T was %w the %jth.\n", loctime); + fputs (buffer, stdout); + } + + return (lose ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/test/time/tst-ftime_l.c b/test/time/tst-ftime_l.c new file mode 100644 index 000000000..5ecb22fbe --- /dev/null +++ b/test/time/tst-ftime_l.c @@ -0,0 +1,136 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <features.h> +#ifdef __UCLIBC_HAS_WCHAR__ +#include <locale.h> +#include <wchar.h> + + +int +main (void) +{ + locale_t l; + locale_t old; + struct tm tm; + char buf[1000]; + wchar_t wbuf[1000]; + int result = 0; + size_t n; + + l = newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL); + if (l == NULL) + { + puts ("newlocale failed"); + exit (1); + } + + memset (&tm, '\0', sizeof (tm)); + + tm.tm_year = 102; + tm.tm_mon = 2; + tm.tm_mday = 1; + + if (strftime (buf, sizeof (buf), "%e %^B %Y", &tm) == 0) + { + puts ("initial strftime failed"); + exit (1); + } + if (strcmp (buf, " 1 MARCH 2002") != 0) + { + printf ("initial strftime: expected \"%s\", got \"%s\"\n", + " 1 MARCH 2002", buf); + result = 1; + } + else + printf ("got \"%s\"\n", buf); + + /* Now using the extended locale model. */ + if (strftime_l (buf, sizeof (buf), "%e %^B %Y", &tm, l) == 0) + { + puts ("strftime_l failed"); + result = 1; + } + else if (strcmp (buf, " 1 M\xc4RZ 2002") != 0) + { + printf ("strftime_l: expected \"%s\", got \"%s\"\n", + " 1 M\xc4RZ 2002", buf); + result = 1; + } + else + { + setlocale (LC_ALL, "de_DE.ISO-8859-1"); + printf ("got \"%s\"\n", buf); + setlocale (LC_ALL, "C"); + } + + /* And the wide character version. */ + if (wcsftime_l (wbuf, sizeof (wbuf) / sizeof (wbuf[0]), L"%e %^B %Y", &tm, l) + == 0) + { + puts ("wcsftime_l failed"); + result = 1; + } + else if (wcscmp (wbuf, L" 1 M\x00c4RZ 2002") != 0) + { + printf ("wcsftime_l: expected \"%ls\", got \"%ls\"\n", + L" 1 M\x00c4RZ 2002", wbuf); + result = 1; + } + else + { + setlocale (LC_ALL, "de_DE.ISO-8859-1"); + printf ("got \"%ls\"\n", wbuf); + setlocale (LC_ALL, "C"); + } + + old = uselocale (l); + + n = strftime (buf, sizeof (buf), "%e %^B %Y", &tm); + + /* Switch back. */ + (void) uselocale (old); + + if (n == 0) + { + puts ("strftime after first uselocale failed"); + result = 1; + } + else if (strcmp (buf, " 1 M\xc4RZ 2002") != 0) + { + printf ("strftime in non-C locale: expected \"%s\", got \"%s\"\n", + " 1 M\xc4RZ 2002", buf); + result = 1; + } + else + { + setlocale (LC_ALL, "de_DE.ISO-8859-1"); + printf ("got \"%s\"\n", buf); + setlocale (LC_ALL, "C"); + } + + if (strftime (buf, sizeof (buf), "%e %^B %Y", &tm) == 0) + { + puts ("strftime after second uselocale failed"); + result = 1; + } + else if (strcmp (buf, " 1 MARCH 2002") != 0) + { + printf ("initial strftime: expected \"%s\", got \"%s\"\n", + " 1 MARCH 2002", buf); + result = 1; + } + else + printf ("got \"%s\"\n", buf); + + return result; +} + +#else +int main(void) +{ + puts("Test requires WCHAR support; skipping"); + return 0; +} +#endif diff --git a/test/time/tst-mktime.c b/test/time/tst-mktime.c new file mode 100644 index 000000000..416a85616 --- /dev/null +++ b/test/time/tst-mktime.c @@ -0,0 +1,70 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +int +main (void) +{ + struct tm time_str, *tm; + time_t t; + char daybuf[20]; + int result; + + time_str.tm_year = 2001 - 1900; + time_str.tm_mon = 7 - 1; + time_str.tm_mday = 4; + time_str.tm_hour = 0; + time_str.tm_min = 0; + time_str.tm_sec = 1; + time_str.tm_isdst = -1; + + if (mktime (&time_str) == -1) + { + (void) puts ("-unknown-"); + result = 1; + } + else + { + (void) strftime (daybuf, sizeof (daybuf), "%A", &time_str); + (void) puts (daybuf); + result = strcmp (daybuf, "Wednesday") != 0; + } + + setenv ("TZ", "EST+5", 1); +#define EVENING69 1 * 60 * 60 + 2 * 60 + 29 + t = EVENING69; + tm = localtime (&t); + if (tm == NULL) + { + (void) puts ("localtime returned NULL"); + result = 1; + } + else + { + time_str = *tm; + t = mktime (&time_str); + if (t != EVENING69) + { + printf ("mktime returned %ld, expected %d\n", + (long) t, EVENING69); + result = 1; + } + else + (void) puts ("Dec 31 1969 EST test passed"); + + setenv ("TZ", "CET-1", 1); + t = mktime (&time_str); +#define EVENING69_CET (EVENING69 - (5 - -1) * 60 * 60) + if (t != EVENING69_CET) + { + printf ("mktime returned %ld, expected %ld\n", + (long) t, (long) EVENING69_CET); + result = 1; + } + else + (void) puts ("Dec 31 1969 CET test passed"); + } + + return result; +} diff --git a/test/time/tst-mktime2.c b/test/time/tst-mktime2.c new file mode 100644 index 000000000..6279218cb --- /dev/null +++ b/test/time/tst-mktime2.c @@ -0,0 +1,141 @@ +/* Test program from Paul Eggert and Tony Leneis. */ +#include <time.h> +#include <stdlib.h> +#include <unistd.h> + +static time_t time_t_max; +static time_t time_t_min; + +/* Values we'll use to set the TZ environment variable. */ +static const char *tz_strings[] = + { + (const char *) 0, "GMT0", "JST-9", + "EST+3EDT+2,M10.1.0/00:00:00,M2.3.0/00:00:00" + }; +#define N_STRINGS ((int) (sizeof (tz_strings) / sizeof (tz_strings[0]))) + +/* Fail if mktime fails to convert a date in the spring-forward gap. + Based on a problem report from Andreas Jaeger. */ +static void +spring_forward_gap (void) +{ + /* glibc (up to about 1998-10-07) failed this test. */ + struct tm tm; + + /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0" + instead of "TZ=America/Vancouver" in order to detect the bug even + on systems that don't support the Olson extension, or don't have the + full zoneinfo tables installed. */ + setenv ("TZ", "PST8PDT,M4.1.0,M10.5.0", 1); + + tm.tm_year = 98; + tm.tm_mon = 3; + tm.tm_mday = 5; + tm.tm_hour = 2; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_isdst = -1; + if (mktime (&tm) == (time_t)-1) + exit (1); +} + +static void +mktime_test1 (time_t now) +{ + struct tm *lt = localtime (&now); + if (lt && mktime (lt) != now) + exit (2); +} + +static void +mktime_test (time_t now) +{ + mktime_test1 (now); + mktime_test1 ((time_t) (time_t_max - now)); + mktime_test1 ((time_t) (time_t_min + now)); +} + +static void +irix_6_4_bug (void) +{ + /* Based on code from Ariel Faigon. */ + struct tm tm; + tm.tm_year = 96; + tm.tm_mon = 3; + tm.tm_mday = 0; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_isdst = -1; + mktime (&tm); + if (tm.tm_mon != 2 || tm.tm_mday != 31) + exit (3); +} + +static void +bigtime_test (int j) +{ + struct tm tm; + time_t now; + tm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = j; + tm.tm_isdst = -1; + now = mktime (&tm); + if (now != (time_t) -1) + { + struct tm *lt = localtime (&now); + if (! (lt + && lt->tm_year == tm.tm_year + && lt->tm_mon == tm.tm_mon + && lt->tm_mday == tm.tm_mday + && lt->tm_hour == tm.tm_hour + && lt->tm_min == tm.tm_min + && lt->tm_sec == tm.tm_sec + && lt->tm_yday == tm.tm_yday + && lt->tm_wday == tm.tm_wday + && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst) + == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst)))) + exit (4); + } +} + +static int +do_test (void) +{ + time_t t, delta; + int i, j; + + setenv ("TZ", "America/Sao_Paulo", 1); + /* This test makes some buggy mktime implementations loop. + Give up after 60 seconds; a mktime slower than that + isn't worth using anyway. */ + alarm (60); + + for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2) + continue; + time_t_max--; + if ((time_t) -1 < 0) + for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2) + continue; + delta = time_t_max / 997; /* a suitable prime number */ + for (i = 0; i < N_STRINGS; i++) + { + if (tz_strings[i]) + setenv ("TZ", tz_strings[i], 1); + + for (t = 0; t <= time_t_max - delta; t += delta) + mktime_test (t); + mktime_test ((time_t) 1); + mktime_test ((time_t) (60 * 60)); + mktime_test ((time_t) (60 * 60 * 24)); + + for (j = 1; 0 < j; j *= 2) + bigtime_test (j); + bigtime_test (j - 1); + } + irix_6_4_bug (); + spring_forward_gap (); + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/test/time/tst-mktime3.c b/test/time/tst-mktime3.c new file mode 100644 index 000000000..60d0e0b32 --- /dev/null +++ b/test/time/tst-mktime3.c @@ -0,0 +1,50 @@ +/* Test program for mktime bugs with out-of-range tm_sec values. */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +struct tm tests[] = +{ + { .tm_sec = -1, .tm_mday = 1, .tm_year = 104 }, + { .tm_sec = 65, .tm_min = 59, .tm_hour = 23, .tm_mday = 31, + .tm_mon = 11, .tm_year = 101 } +}; +struct tm expected[] = +{ + { .tm_sec = 59, .tm_min = 59, .tm_hour = 23, .tm_mday = 31, + .tm_mon = 11, .tm_year = 103, .tm_wday = 3, .tm_yday = 364 }, + { .tm_sec = 5, .tm_mday = 1, .tm_year = 102, .tm_wday = 2 } +}; + +int +main (void) +{ + setenv ("TZ", "UTC", 1); + int i; + for (i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i) + { + if (mktime (&tests[i]) < 0) + { + printf ("mktime %d failed\n", i); + return 1; + } +#define CHECK(name) \ + if (tests[i].name != expected[i].name) \ + { \ + printf ("test %d " #name " got %d expected %d\n", \ + i, tests[i].name, expected[i].name); \ + return 1; \ + } + CHECK (tm_sec) + CHECK (tm_min) + CHECK (tm_hour) + CHECK (tm_mday) + CHECK (tm_mon) + CHECK (tm_year) + CHECK (tm_wday) + CHECK (tm_yday) + CHECK (tm_isdst) + } + return 0; +} diff --git a/test/time/tst-posixtz.c b/test/time/tst-posixtz.c new file mode 100644 index 000000000..ccba63e5b --- /dev/null +++ b/test/time/tst-posixtz.c @@ -0,0 +1,88 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +struct +{ + time_t when; + const char *tz; + const char *result; +} tests[] = +{ + { 909312849L, "AEST-10AEDST-11,M10.5.0,M3.5.0", + "1998/10/25 21:54:09 dst=1 zone=AEDST" }, + { 924864849L, "AEST-10AEDST-11,M10.5.0,M3.5.0", + "1999/04/23 20:54:09 dst=0 zone=AEST" }, + { 919973892L, "AEST-10AEDST-11,M10.5.0,M3.5.0", + "1999/02/26 07:18:12 dst=1 zone=AEDST" }, + { 909312849L, "EST+5EDT,M4.1.0/2,M10.5.0/2", + "1998/10/25 05:54:09 dst=0 zone=EST" }, + { 924864849L, "EST+5EDT,M4.1.0/2,M10.5.0/2", + "1999/04/23 06:54:09 dst=1 zone=EDT" }, + { 919973892L, "EST+5EDT,M4.1.0/2,M10.5.0/2", + "1999/02/25 15:18:12 dst=0 zone=EST" }, +}; + +int +main (void) +{ + int result = 0; + size_t cnt; + + for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt) + { + char buf[100]; + struct tm *tmp; + + printf ("TZ = \"%s\", time = %ld => ", tests[cnt].tz, tests[cnt].when); + fflush (stdout); + + setenv ("TZ", tests[cnt].tz, 1); + + tmp = localtime (&tests[cnt].when); + + snprintf (buf, sizeof (buf), + "%04d/%02d/%02d %02d:%02d:%02d dst=%d zone=%s", + tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec, tmp->tm_isdst, + tzname[tmp->tm_isdst ? 1 : 0]); + + fputs (buf, stdout); + + if (strcmp (buf, tests[cnt].result) == 0) + puts (", OK"); + else + { + result = 1; + puts (", FAIL"); + } + } + + setenv ("TZ", "Universal", 1); + localtime (&tests[0].when); + printf ("TZ = \"Universal\" daylight %d tzname = { \"%s\", \"%s\" }", + daylight, tzname[0], tzname[1]); + if (! daylight) + puts (", OK"); + else + { + result = 1; + puts (", FAIL"); + } + + setenv ("TZ", "AEST-10AEDST-11,M10.5.0,M3.5.0", 1); + tzset (); + printf ("TZ = \"AEST-10AEDST-11,M10.5.0,M3.5.0\" daylight %d" + " tzname = { \"%s\", \"%s\" }", daylight, tzname[0], tzname[1]); + if (daylight + && strcmp (tzname[0], "AEST") == 0 && strcmp (tzname[1], "AEDST") == 0) + puts (", OK"); + else + { + result = 1; + puts (", FAIL"); + } + + return result; +} diff --git a/test/time/tst-strftime.c b/test/time/tst-strftime.c new file mode 100644 index 000000000..374fba426 --- /dev/null +++ b/test/time/tst-strftime.c @@ -0,0 +1,111 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + + +static struct +{ + const char *fmt; + size_t min; + size_t max; +} tests[] = + { + { "%2000Y", 2000, 4000 }, + { "%02000Y", 2000, 4000 }, + { "%_2000Y", 2000, 4000 }, + { "%-2000Y", 2000, 4000 }, + }; +#define ntests (sizeof (tests) / sizeof (tests[0])) + + +static int +do_test (void) +{ + size_t cnt; + int result = 0; + + time_t tnow = time (NULL); + struct tm *now = localtime (&tnow); + + for (cnt = 0; cnt < ntests; ++cnt) + { + size_t size = 0; + int res; + char *buf = NULL; + + do + { + size += 500; + buf = (char *) realloc (buf, size); + if (buf == NULL) + { + puts ("out of memory"); + exit (1); + } + + res = strftime (buf, size, tests[cnt].fmt, now); + if (res != 0) + break; + } + while (size < tests[cnt].max); + + if (res == 0) + { + printf ("%Zu: %s: res == 0 despite size == %Zu\n", + cnt, tests[cnt].fmt, size); + result = 1; + } + else if (size < tests[cnt].min) + { + printf ("%Zu: %s: size == %Zu was enough\n", + cnt, tests[cnt].fmt, size); + result = 1; + } + else + printf ("%Zu: %s: size == %Zu: OK\n", cnt, tests[cnt].fmt, size); + + free (buf); + } + + struct tm ttm = + { + /* Initialize the fields which are needed in the tests. */ + .tm_mday = 1, + .tm_hour = 2 + }; + const struct + { + const char *fmt; + const char *exp; + size_t n; + } ftests[] = + { + { "%-e", "1", 1 }, + { "%-k", "2", 1 }, + { "%-l", "2", 1 }, + }; +#define nftests (sizeof (ftests) / sizeof (ftests[0])) + for (cnt = 0; cnt < nftests; ++cnt) + { + char buf[100]; + size_t r = strftime (buf, sizeof (buf), ftests[cnt].fmt, &ttm); + if (r != ftests[cnt].n) + { + printf ("strftime(\"%s\") returned %zu not %zu\n", + ftests[cnt].fmt, r, ftests[cnt].n); + result = 1; + } + if (strcmp (buf, ftests[cnt].exp) != 0) + { + printf ("strftime(\"%s\") produced \"%s\" not \"%s\"\n", + ftests[cnt].fmt, buf, ftests[cnt].exp); + result = 1; + } + } + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/test/time/tst-strptime.c b/test/time/tst-strptime.c new file mode 100644 index 000000000..6356aa0d4 --- /dev/null +++ b/test/time/tst-strptime.c @@ -0,0 +1,193 @@ +/* Test for strptime. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + + +static const struct +{ + const char *locale; + const char *input; + const char *format; + int wday; + int yday; + int mon; + int mday; +} day_tests[] = +{ + { "C", "2000-01-01", "%Y-%m-%d", 6, 0, 0, 1 }, + { "C", "03/03/00", "%D", 5, 62, 2, 3 }, + { "C", "9/9/99", "%x", 4, 251, 8, 9 }, + { "C", "19990502123412", "%Y%m%d%H%M%S", 0, 121, 4, 2 }, + { "C", "2001 20 Mon", "%Y %U %a", 1, 140, 4, 21 }, + { "C", "2001 21 Mon", "%Y %W %a", 1, 140, 4, 21 }, + { "ja_JP.EUC-JP", "2000-01-01 08:12:21 AM", "%Y-%m-%d %I:%M:%S %p", + 6, 0, 0, 1 }, + { "en_US.ISO-8859-1", "2000-01-01 08:12:21 PM", "%Y-%m-%d %I:%M:%S %p", + 6, 0, 0, 1 }, + { "ja_JP.EUC-JP", "2001 20 \xb7\xee", "%Y %U %a", 1, 140, 4, 21 }, + { "ja_JP.EUC-JP", "2001 21 \xb7\xee", "%Y %W %a", 1, 140, 4, 21 }, +}; + + +static const struct +{ + const char *input; + const char *format; + const char *output; + int wday; + int yday; +} tm_tests [] = +{ + {"17410105012000", "%H%M%S%d%m%Y", "2000-01-05 17:41:01", 3, 4} +}; + + + +static int +test_tm (void) +{ + struct tm tm; + size_t i; + int result = 0; + char buf[100]; + + for (i = 0; i < sizeof (tm_tests) / sizeof (tm_tests[0]); ++i) + { + memset (&tm, '\0', sizeof (tm)); + + char *ret = strptime (tm_tests[i].input, tm_tests[i].format, &tm); + if (ret == NULL) + { + printf ("strptime returned NULL for `%s'\n", tm_tests[i].input); + result = 1; + continue; + } + else if (*ret != '\0') + { + printf ("not all of `%s' read\n", tm_tests[i].input); + result = 1; + } + strftime (buf, sizeof (buf), "%F %T", &tm); + printf ("strptime (\"%s\", \"%s\", ...)\n" + "\tshould be: %s, wday = %d, yday = %3d\n" + "\t is: %s, wday = %d, yday = %3d\n", + tm_tests[i].input, tm_tests[i].format, + tm_tests[i].output, + tm_tests[i].wday, tm_tests[i].yday, + buf, tm.tm_wday, tm.tm_yday); + + if (strcmp (buf, tm_tests[i].output) != 0) + { + printf ("Time and date are not correct.\n"); + result = 1; + } + if (tm.tm_wday != tm_tests[i].wday) + { + printf ("weekday for `%s' incorrect: %d instead of %d\n", + tm_tests[i].input, tm.tm_wday, tm_tests[i].wday); + result = 1; + } + if (tm.tm_yday != tm_tests[i].yday) + { + printf ("yearday for `%s' incorrect: %d instead of %d\n", + tm_tests[i].input, tm.tm_yday, tm_tests[i].yday); + result = 1; + } + } + + return result; +} + + +int +main (int argc, char *argv[]) +{ + struct tm tm; + size_t i; + int result = 0; + + for (i = 0; i < sizeof (day_tests) / sizeof (day_tests[0]); ++i) + { + memset (&tm, '\0', sizeof (tm)); + + if (setlocale (LC_ALL, day_tests[i].locale) == NULL) + { + printf ("cannot set locale %s: %m\n", day_tests[i].locale); + exit (EXIT_FAILURE); + } + + char *ret = strptime (day_tests[i].input, day_tests[i].format, &tm); + if (ret == NULL) + { + printf ("strptime returned NULL for `%s'\n", day_tests[i].input); + result = 1; + continue; + } + else if (*ret != '\0') + { + printf ("not all of `%s' read\n", day_tests[i].input); + result = 1; + } + + printf ("strptime (\"%s\", \"%s\", ...)\n" + "\tshould be: wday = %d, yday = %3d, mon = %2d, mday = %2d\n" + "\t is: wday = %d, yday = %3d, mon = %2d, mday = %2d\n", + day_tests[i].input, day_tests[i].format, + day_tests[i].wday, day_tests[i].yday, + day_tests[i].mon, day_tests[i].mday, + tm.tm_wday, tm.tm_yday, tm.tm_mon, tm.tm_mday); + + if (tm.tm_wday != day_tests[i].wday) + { + printf ("weekday for `%s' incorrect: %d instead of %d\n", + day_tests[i].input, tm.tm_wday, day_tests[i].wday); + result = 1; + } + if (tm.tm_yday != day_tests[i].yday) + { + printf ("yearday for `%s' incorrect: %d instead of %d\n", + day_tests[i].input, tm.tm_yday, day_tests[i].yday); + result = 1; + } + if (tm.tm_mon != day_tests[i].mon) + { + printf ("month for `%s' incorrect: %d instead of %d\n", + day_tests[i].input, tm.tm_mon, day_tests[i].mon); + result = 1; + } + if (tm.tm_mday != day_tests[i].mday) + { + printf ("monthday for `%s' incorrect: %d instead of %d\n", + day_tests[i].input, tm.tm_mday, day_tests[i].mday); + result = 1; + } + } + + setlocale (LC_ALL, "C"); + + result |= test_tm (); + + return result; +} diff --git a/test/time/tst-strptime2.c b/test/time/tst-strptime2.c new file mode 100644 index 000000000..73552bb8f --- /dev/null +++ b/test/time/tst-strptime2.c @@ -0,0 +1,59 @@ +#include <limits.h> +#include <stdio.h> +#include <time.h> + + +static const struct +{ + const char *fmt; + long int gmtoff; +} tests[] = + { + { "1113472456 +1000", 36000 }, + { "1113472456 -1000", -36000 }, + { "1113472456 +10", 36000 }, + { "1113472456 -10", -36000 }, + { "1113472456 +1030", 37800 }, + { "1113472456 -1030", -37800 }, + { "1113472456 +0030", 1800 }, + { "1113472456 -0030", -1800 }, + { "1113472456 -1330", LONG_MAX }, + { "1113472456 +1330", LONG_MAX }, + { "1113472456 -1060", LONG_MAX }, + { "1113472456 +1060", LONG_MAX }, + { "1113472456 1030", LONG_MAX }, + }; +#define ntests (sizeof (tests) / sizeof (tests[0])) + + +int +main (void) +{ + int result = 0; + + for (int i = 0; i < ntests; ++i) + { + struct tm tm; + + if (strptime (tests[i].fmt, "%s %z", &tm) == NULL) + { + if (tests[i].gmtoff != LONG_MAX) + { + printf ("round %d: strptime unexpectedly failed\n", i); + result = 1; + } + continue; + } + + if (tm.tm_gmtoff != tests[i].gmtoff) + { + printf ("round %d: tm_gmtoff is %ld\n", i, (long int) tm.tm_gmtoff); + result = 1; + } + } + + if (result == 0) + puts ("all OK"); + + return 0; +} diff --git a/test/time/tst-timezone.c b/test/time/tst-timezone.c new file mode 100644 index 000000000..4c879163c --- /dev/null +++ b/test/time/tst-timezone.c @@ -0,0 +1,170 @@ +/* Copyright (C) 1998, 1999, 2000, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <time.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int failed = 0; + +struct test_times +{ + const char *name; + int daylight; + int timezone; + const char *tzname[2]; +}; + +static const struct test_times tests[] = +{ + { "Europe/Amsterdam", 1, -3600, { "CET", "CEST" }}, + { "Europe/Berlin", 1, -3600, { "CET", "CEST" }}, + { "Europe/London", 1, 0, { "GMT", "BST" }}, + { "Universal", 0, 0, {"UTC", "UTC" }}, + { "Australia/Melbourne", 1, -36000, { "EST", "EST" }}, + { "America/Sao_Paulo", 1, 10800, {"BRT", "BRST" }}, + { "America/Chicago", 1, 21600, {"CST", "CDT" }}, + { "America/Indiana/Indianapolis", 1, 18000, {"EST", "EDT" }}, + { "America/Los_Angeles", 1, 28800, {"PST", "PDT" }}, + { "Asia/Tokyo", 1, -32400, {"JST", "JDT" }}, + { "Pacific/Auckland", 1, -43200, { "NZST", "NZDT" }}, + { NULL, 0, 0 } +}; + +/* This string will be used for `putenv' calls. */ +char envstring[100]; + +static void +print_tzvars (void) +{ + printf ("tzname[0]: %s\n", tzname[0]); + printf ("tzname[1]: %s\n", tzname[1]); + printf ("daylight: %d\n", daylight); + printf ("timezone: %ld\n", timezone); +} + + +static void +check_tzvars (const char *name, int dayl, int timez, const char *const tznam[]) +{ + int i; + + if (daylight != dayl) + { + printf ("*** Timezone: %s, daylight is: %d but should be: %d\n", + name, daylight, dayl); + ++failed; + } + if (timezone != timez) + { + printf ("*** Timezone: %s, timezone is: %ld but should be: %d\n", + name, timezone, timez); + ++failed; + } + for (i = 0; i <= 1; ++i) + if (strcmp (tzname[i], tznam[i]) != 0) + { + printf ("*** Timezone: %s, tzname[%d] is: %s but should be: %s\n", + name, i, tzname[i], tznam[i]); + ++failed; + } +} + + +int +main (int argc, char ** argv) +{ + time_t t; + const struct test_times *pt; + char buf[BUFSIZ]; + + /* This should be: Fri May 15 01:02:16 1998 (UTC). */ + t = 895194136; + printf ("We use this date: %s\n", asctime (gmtime (&t))); + + for (pt = tests; pt->name != NULL; ++pt) + { + /* Start with a known state */ + printf ("Checking timezone %s\n", pt->name); + sprintf (buf, "TZ=%s", pt->name); + if (putenv (buf)) + { + puts ("putenv failed."); + failed = 1; + } + tzset (); + print_tzvars (); + check_tzvars (pt->name, pt->daylight, pt->timezone, pt->tzname); + + /* calling localtime shouldn't make a difference */ + localtime (&t); + print_tzvars (); + check_tzvars (pt->name, pt->daylight, pt->timezone, pt->tzname); + } + + /* From a post of Scott Harrington <seh4@ix.netcom.com> to the timezone + mailing list. */ + { + struct tm tmBuf = {0, 0, 0, 10, 3, 98, 0, 0, -1}; + char buf[200]; + strcpy (envstring, "TZ=Europe/London"); + putenv (envstring); + t = mktime (&tmBuf); + snprintf (buf, sizeof (buf), "TZ=%s %ld %d %d %d %d %d %d %d %d %d", + getenv ("TZ"), t, + tmBuf.tm_sec, tmBuf.tm_min, tmBuf.tm_hour, + tmBuf.tm_mday, tmBuf.tm_mon, tmBuf.tm_year, + tmBuf.tm_wday, tmBuf.tm_yday, tmBuf.tm_isdst); + fputs (buf, stdout); + puts (" should be"); + puts ("TZ=Europe/London 892162800 0 0 0 10 3 98 5 99 1"); + if (strcmp (buf, "TZ=Europe/London 892162800 0 0 0 10 3 98 5 99 1") != 0) + { + failed = 1; + fputs (" FAILED ***", stdout); + } + } + + printf("\n"); + + { + struct tm tmBuf = {0, 0, 0, 10, 3, 98, 0, 0, -1}; + char buf[200]; + strcpy (envstring, "TZ=GMT"); + /* No putenv call needed! */ + t = mktime (&tmBuf); + snprintf (buf, sizeof (buf), "TZ=%s %ld %d %d %d %d %d %d %d %d %d", + getenv ("TZ"), t, + tmBuf.tm_sec, tmBuf.tm_min, tmBuf.tm_hour, + tmBuf.tm_mday, tmBuf.tm_mon, tmBuf.tm_year, + tmBuf.tm_wday, tmBuf.tm_yday, tmBuf.tm_isdst); + fputs (buf, stdout); + puts (" should be"); + puts ("TZ=GMT 892166400 0 0 0 10 3 98 5 99 0"); + if (strcmp (buf, "TZ=GMT 892166400 0 0 0 10 3 98 5 99 0") != 0) + { + failed = 1; + fputs (" FAILED ***", stdout); + } + } + + return failed ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/test/time/tst_wcsftime.c b/test/time/tst_wcsftime.c new file mode 100644 index 000000000..6e35f1e6f --- /dev/null +++ b/test/time/tst_wcsftime.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <time.h> +#include <features.h> +#ifdef __UCLIBC_HAS_WCHAR__ +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + wchar_t buf[200]; + time_t t; + struct tm *tp; + int result = 0; + size_t n; + + time (&t); + tp = gmtime (&t); + + n = wcsftime (buf, sizeof (buf) / sizeof (buf[0]), + L"%H:%M:%S %Y-%m-%d\n", tp); + if (n != 21) + result = 1; + + wprintf (L"It is now %ls", buf); + + wcsftime (buf, sizeof (buf) / sizeof (buf[0]), L"%A\n", tp); + + wprintf (L"The weekday is %ls", buf); + + return result; +} + +#else +int main(void) +{ + puts("Test requires WCHAR support; skipping"); + return 0; +} +#endif |