OSDN Git Service

grab some time tests from glibc
authorMike Frysinger <vapier@gentoo.org>
Wed, 1 Mar 2006 01:07:36 +0000 (01:07 -0000)
committerMike Frysinger <vapier@gentoo.org>
Wed, 1 Mar 2006 01:07:36 +0000 (01:07 -0000)
15 files changed:
test/time/Makefile [new file with mode: 0644]
test/time/bug-asctime.c [new file with mode: 0644]
test/time/bug-asctime_r.c [new file with mode: 0644]
test/time/clocktest.c [new file with mode: 0644]
test/time/test_time.c [new file with mode: 0644]
test/time/tst-ftime_l.c [new file with mode: 0644]
test/time/tst-mktime.c [new file with mode: 0644]
test/time/tst-mktime2.c [new file with mode: 0644]
test/time/tst-mktime3.c [new file with mode: 0644]
test/time/tst-posixtz.c [new file with mode: 0644]
test/time/tst-strftime.c [new file with mode: 0644]
test/time/tst-strptime.c [new file with mode: 0644]
test/time/tst-strptime2.c [new file with mode: 0644]
test/time/tst-timezone.c [new file with mode: 0644]
test/time/tst_wcsftime.c [new file with mode: 0644]

diff --git a/test/time/Makefile b/test/time/Makefile
new file mode 100644 (file)
index 0000000..cbf7085
--- /dev/null
@@ -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 (file)
index 0000000..149e4e0
--- /dev/null
@@ -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 (file)
index 0000000..86651ef
--- /dev/null
@@ -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 (file)
index 0000000..f2b3ea7
--- /dev/null
@@ -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 (file)
index 0000000..20216ed
--- /dev/null
@@ -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 (file)
index 0000000..5ecb22f
--- /dev/null
@@ -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 (file)
index 0000000..416a856
--- /dev/null
@@ -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 (file)
index 0000000..6279218
--- /dev/null
@@ -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 (file)
index 0000000..60d0e0b
--- /dev/null
@@ -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 (file)
index 0000000..ccba63e
--- /dev/null
@@ -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 (file)
index 0000000..374fba4
--- /dev/null
@@ -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 (file)
index 0000000..6356aa0
--- /dev/null
@@ -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 (file)
index 0000000..73552bb
--- /dev/null
@@ -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 (file)
index 0000000..4c87916
--- /dev/null
@@ -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 (file)
index 0000000..6e35f1e
--- /dev/null
@@ -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