From d6b2a407783dbbd6c9680601da005de0bb0ff37d Mon Sep 17 00:00:00 2001
From: Manuel Novoa III <mjn3@codepoet.org>
Date: Mon, 17 Jun 2002 09:45:15 +0000
Subject: Commit the new time stuff, even though I haven't made it threadsafe
 yet. At least people can play with it.  Also, fix a buglet in setenv.c.

---
 libc/misc/time/Makefile        |   20 +-
 libc/misc/time/README          |    8 -
 libc/misc/time/__time_locale.c |   30 -
 libc/misc/time/__time_static.c |   17 -
 libc/misc/time/asc_conv.c      |   80 --
 libc/misc/time/asctime.c       |   18 -
 libc/misc/time/asctime_r.c     |   16 -
 libc/misc/time/clock.c         |   43 -
 libc/misc/time/ctime.c         |   14 -
 libc/misc/time/ctime_r.c       |   10 -
 libc/misc/time/difftime.c      |   64 --
 libc/misc/time/gmtime.c        |   13 -
 libc/misc/time/gmtime_r.c      |   12 -
 libc/misc/time/localtime.c     |   24 -
 libc/misc/time/localtime_r.c   |   22 -
 libc/misc/time/mktime.c        |  327 -------
 libc/misc/time/strftime.c      |  395 ---------
 libc/misc/time/strptime.c      |  983 ---------------------
 libc/misc/time/time.c          | 1864 ++++++++++++++++++++++++++++++++++++++++
 libc/misc/time/tm_conv.c       |  105 ---
 libc/misc/time/utimes.c        |   17 -
 libc/stdlib/setenv.c           |    3 +-
 22 files changed, 1881 insertions(+), 2204 deletions(-)
 delete mode 100644 libc/misc/time/README
 delete mode 100644 libc/misc/time/__time_locale.c
 delete mode 100644 libc/misc/time/__time_static.c
 delete mode 100644 libc/misc/time/asc_conv.c
 delete mode 100644 libc/misc/time/asctime.c
 delete mode 100644 libc/misc/time/asctime_r.c
 delete mode 100644 libc/misc/time/clock.c
 delete mode 100644 libc/misc/time/ctime.c
 delete mode 100644 libc/misc/time/ctime_r.c
 delete mode 100644 libc/misc/time/difftime.c
 delete mode 100644 libc/misc/time/gmtime.c
 delete mode 100644 libc/misc/time/gmtime_r.c
 delete mode 100644 libc/misc/time/localtime.c
 delete mode 100644 libc/misc/time/localtime_r.c
 delete mode 100644 libc/misc/time/mktime.c
 delete mode 100644 libc/misc/time/strftime.c
 delete mode 100644 libc/misc/time/strptime.c
 create mode 100644 libc/misc/time/time.c
 delete mode 100644 libc/misc/time/tm_conv.c
 delete mode 100644 libc/misc/time/utimes.c

(limited to 'libc')

diff --git a/libc/misc/time/Makefile b/libc/misc/time/Makefile
index 3e0845799..425e2713d 100644
--- a/libc/misc/time/Makefile
+++ b/libc/misc/time/Makefile
@@ -24,13 +24,19 @@
 TOPDIR=../../../
 include $(TOPDIR)Rules.mak
 
-CSRC=localtime.c gmtime.c asctime.c ctime.c asc_conv.c tm_conv.c mktime.c \
-	localtime_r.c gmtime_r.c asctime_r.c ctime_r.c utimes.c adjtime.c \
-	clock.c difftime.c ftime.c strftime.c strptime.c __time_locale.c \
-	__time_static.c
+MSRC= time.c
+MOBJ= asctime.o asctime_r.o clock.o ctime.o ctime_r.o gmtime.o gmtime_r.o \
+	localtime.o localtime_r.o mktime.o strftime.o strptime.o tzset.o \
+	_time_t2tm.o __time_tm.o _time_mktime.o
 
+ifeq ($(HAS_FLOATING_POINT),true)
+	MOBJ += difftime.o 
+endif
+
+CSRC= adjtime.c ftime.c
 COBJS=$(patsubst %.c,%.o, $(CSRC))
-OBJS=$(COBJS)
+
+OBJS=$(COBJS) $(MOBJ)
 
 all: $(OBJS) $(LIBC)
 
@@ -39,6 +45,10 @@ $(LIBC): ar-target
 ar-target: $(OBJS)
 	$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
 
+$(MOBJ): $(MSRC)
+	$(CC) $(CFLAGS) -DTARGET_ARCH=$(TARGET_ARCH) -DL_$* $< -c -o $*.o
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
 $(COBJS): %.o : %.c
 	$(CC) $(CFLAGS) -c $< -o $@
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
diff --git a/libc/misc/time/README b/libc/misc/time/README
deleted file mode 100644
index da4f4e67f..000000000
--- a/libc/misc/time/README
+++ /dev/null
@@ -1,8 +0,0 @@
-Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk>
-This file is part of the Linux-8086 C library and is distributed
-under the GNU Library General Public License.
-
-There are two ways of converting the time_t to a struct tm, I'm not
-quite sure which is better.
-
--Robert
diff --git a/libc/misc/time/__time_locale.c b/libc/misc/time/__time_locale.c
deleted file mode 100644
index 0d78a0a67..000000000
--- a/libc/misc/time/__time_locale.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __UCLIBC_HAS_LOCALE__
-char const __weekday_name[][10] =
-  {
-    "Sunday", "Monday", "Tuesday", "Wednesday",
-    "Thursday", "Friday", "Saturday"
-  };
-char const __ab_weekday_name[][4] =
-  {
-    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-  };
-char const __month_name[][10] =
-  {
-    "January", "February", "March", "April", "May", "June",
-    "July", "August", "September", "October", "November", "December"
-  };
-char const __ab_month_name[][4] =
-  {
-    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-  };
-
-const unsigned short int __mon_yday[2][13] =
-  {
-    /* Normal years.  */
-    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
-    /* Leap years.  */
-    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
-  };
-#endif
-
diff --git a/libc/misc/time/__time_static.c b/libc/misc/time/__time_static.c
deleted file mode 100644
index d921ced90..000000000
--- a/libc/misc/time/__time_static.c
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#include <time.h>
-
-/* These globals are exported by the C library */
-char *__tzname[2] = { (char *) "GMT", (char *) "GMT" };
-int __daylight = 0;
-long int __timezone = 0L;
-/* Grumble */
-weak_alias (__tzname, tzname);
-weak_alias (__daylight, daylight);
-weak_alias (__timezone, timezone);
-
-
-/* static data for gmtime() and localtime() */
-struct tm __tmb;
-
-
diff --git a/libc/misc/time/asc_conv.c b/libc/misc/time/asc_conv.c
deleted file mode 100644
index 50c7e0834..000000000
--- a/libc/misc/time/asc_conv.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <features.h>
-#include <ctype.h>
-#include <langinfo.h>
-#include <string.h>
-#include <time.h>
-
-/*
- * Internal ascii conversion routine, avoid use of printf, it's a bit big!
- */
-
-/*
- * Modified      Manuel Novoa III       Jan 2001
- *
- * Removed static function "hit" and did time-field fills inline and
- * put day, hour, min, and sec conversions in a loop using a small
- * table to reduce code size.
- *
- * Made daysp[] and mons[] const to move them from bss to text.
- *
- * Also fixed day conversion ... ANSI says no leading 0.
- *
- * Modified	Erik Andersen	    May 2002
- * Changed to optionally support real locales.
- *
- */
-
-#ifdef __UCLIBC_HAS_LOCALE__
-/* This is defined in locale/C-time.c in the GNU libc.  */
-extern const struct locale_data _nl_C_LC_TIME;
-#define __ab_weekday_name(DAY) (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)+(DAY)].string)
-#define __ab_month_name(MON)   (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)+(MON)].string)
-#else
-extern char const __ab_weekday_name[][4];
-extern char const __ab_month_name[][4];
-#define __ab_weekday_name(DAY) (__ab_weekday_name[DAY])
-#define __ab_month_name(MON)   (__ab_month_name[MON])
-#endif
-
-void __asctime(register char *buffer, struct tm *ptm)
-{
-	char *p;
-	int tmp, i, tm_field[4];
-	/*                              012345678901234567890123456 */
-	static const char template[] = "??? ??? 00 00:00:00 0000\n";
-
-	/* Since we need memcpy below, use it here instead of strcpy. */
-	memcpy(buffer, template, sizeof(template));
-
-	if ((ptm->tm_wday >= 0) && (ptm->tm_wday <= 6)) {
-		memcpy(buffer, __ab_weekday_name(ptm->tm_wday), 3);
-	}
-
-	if ((ptm->tm_mon >= 0) && (ptm->tm_mon <= 11)) {
-		memcpy(buffer + 4, __ab_month_name(ptm->tm_mon), 3);
-	}
-
-	tm_field[0] = ptm->tm_mday;
-	tm_field[1] = ptm->tm_hour;
-	tm_field[2] = ptm->tm_min;
-	tm_field[3] = ptm->tm_sec;
-
-	p = buffer + 9;
-	for (i=0 ; i<4 ; i++) {
-		tmp = tm_field[i];
-		*p-- += tmp % 10;
-		*p += (tmp/10) % 10;
-		p += 4 ;				/* skip to end of next field */
-	}
-
-	tmp = ptm->tm_year + 1900;
-	p = buffer + 23;
-	for (i=0 ; i<4 ; i++) {
-		*p-- += tmp % 10;
-		tmp /= 10;
-	}
-
-	if (buffer[8] == '0') {
-		buffer[8] = ' ';
-	}
-}
diff --git a/libc/misc/time/asctime.c b/libc/misc/time/asctime.c
deleted file mode 100644
index 9d5772335..000000000
--- a/libc/misc/time/asctime.c
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#include <time.h>
-#include <errno.h>
-
-extern void __asctime();
-
-
-char * asctime (__const struct tm *timeptr)
-{
-    static char __time_buf[26];
-    if (timeptr == NULL) {
-	__set_errno (EINVAL);
-	return NULL;
-    }
-    __asctime(__time_buf, timeptr);
-    return __time_buf;
-}
-
diff --git a/libc/misc/time/asctime_r.c b/libc/misc/time/asctime_r.c
deleted file mode 100644
index 215031949..000000000
--- a/libc/misc/time/asctime_r.c
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#include <time.h>
-#include <errno.h>
-
-extern void __asctime();
-
-char *asctime_r(__const struct tm *timeptr, char *buf)
-{
-    if (timeptr == NULL || buf == NULL) {
-	__set_errno (EINVAL);
-	return NULL;
-    }
-    __asctime(buf, timeptr);
-    return buf;
-}
-
diff --git a/libc/misc/time/clock.c b/libc/misc/time/clock.c
deleted file mode 100644
index 139d35868..000000000
--- a/libc/misc/time/clock.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (C) 1991, 1992, 1996, 1999 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 Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <time.h>
-#include <unistd.h>
-#include <sys/times.h>
-
-/* Return the time used by the program so far (user time + system time).  */
-clock_t
-clock (void)
-{
-  struct tms buf;
-  long clk_tck = CLK_TCK;
-
-  /* We don't check for errors here.  The only error the kernel
-     returns is EFAULT if the value cannot be written to the struct we
-     pass a pointer to.  Otherwise the kernel returns an `unsigned
-     long' value which is the number of jiffies since system start.
-     But this number can be negative (when read as `long') when the
-     system is up for some time.  Ignoring errors should therefore
-     have no negative impacts but solve the problem.  */
-  times (&buf);
-
-  return
-      (clk_tck <= CLOCKS_PER_SEC) ? 
-      ((unsigned long) buf.tms_utime + buf.tms_stime) * (CLOCKS_PER_SEC / clk_tck) : 
-      ((unsigned long) buf.tms_utime + buf.tms_stime) / (clk_tck / CLOCKS_PER_SEC);
-}
diff --git a/libc/misc/time/ctime.c b/libc/misc/time/ctime.c
deleted file mode 100644
index 027f5d5a7..000000000
--- a/libc/misc/time/ctime.c
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#include <time.h>
-#include <sys/time.h>
-
-char * ctime (const time_t *t)
-{
-
-    /* According to IEEE Std 1003.1-2001: The ctime() function shall
-     * convert the time pointed to by clock, representing time in
-     * seconds since the Epoch, to local time in the form of a string.
-     * It shall be equivalent to: asctime(localtime(clock)) */
-    return asctime (localtime (t));
-}
-
diff --git a/libc/misc/time/ctime_r.c b/libc/misc/time/ctime_r.c
deleted file mode 100644
index 1b323a258..000000000
--- a/libc/misc/time/ctime_r.c
+++ /dev/null
@@ -1,10 +0,0 @@
-
-#include <time.h>
-#include <sys/time.h>
-
-char * ctime_r(const time_t *t, char *buf)
-{
-    struct tm tm;
-    return asctime_r(localtime_r(t, &tm), buf);
-} 
-
diff --git a/libc/misc/time/difftime.c b/libc/misc/time/difftime.c
deleted file mode 100644
index 88a9244ba..000000000
--- a/libc/misc/time/difftime.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright (C) 1991, 1994, 1996 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 Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <time.h>
-#include <limits.h>
-#include <sys/types.h>
-
-
-/* Return the difference between TIME1 and TIME0.  */
-double difftime (time_t time1, time_t time0)
-{
-  /* Algorithm courtesy Paul Eggert (eggert@twinsun.com).  */
-
-  time_t delta, hibit;
-
-  if (sizeof (time_t) < sizeof (double))
-    return (double) time1 - (double) time0;
-  if (sizeof (time_t) < sizeof (long double))
-    return (long double) time1 - (long double) time0;
-
-  if (time1 < time0)
-    return - difftime (time0, time1);
-
-  /* As much as possible, avoid loss of precision by computing the
-    difference before converting to double.  */
-  delta = time1 - time0;
-  if (delta >= 0)
-    return delta;
-
-  /* Repair delta overflow.  */
-  hibit = (~ (time_t) 0) << ((sizeof (time_t) * CHAR_BIT) - 1);
-
-  /* The following expression rounds twice, which means the result may not
-     be the closest to the true answer.  For example, suppose time_t is
-     64-bit signed int, long_double is IEEE 754 double with default
-     rounding, time1 = 9223372036854775807 and time0 = -1536.  Then the
-     true difference is 9223372036854777343, which rounds to
-     9223372036854777856 with a total error of 513.  But delta overflows to
-     -9223372036854774273, which rounds to -9223372036854774784, and
-     correcting this by subtracting 2 * (long_double) hibit (i.e. by adding
-     2**64 = 18446744073709551616) yields 9223372036854776832, which rounds
-     to 9223372036854775808 with a total error of 1535 instead.  This
-     problem occurs only with very large differences.  It's too painful to
-     fix this portably.  We are not alone in this problem; many C compilers
-     round twice when converting large unsigned types to small floating
-     types, so if time_t is unsigned the "return delta" above has the same
-     double-rounding problem.  */
-  return delta - 2 * (long double) hibit;
-}
diff --git a/libc/misc/time/gmtime.c b/libc/misc/time/gmtime.c
deleted file mode 100644
index e9d648037..000000000
--- a/libc/misc/time/gmtime.c
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#include <time.h>
-
-extern void __tm_conv();
-
-/* Our static data lives in __time_static.c */
-extern struct tm __tmb;
-
-struct tm *gmtime(__const time_t *timep)
-{
-    __tm_conv(&__tmb, timep, 0L);
-    return &__tmb;
-}
diff --git a/libc/misc/time/gmtime_r.c b/libc/misc/time/gmtime_r.c
deleted file mode 100644
index a1502e275..000000000
--- a/libc/misc/time/gmtime_r.c
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#include <time.h>
-
-extern void __tm_conv();
-
-struct tm *gmtime_r(timep, tp)
-__const time_t *timep;
-struct tm *tp;
-{
-	__tm_conv(tp, timep, 0L);
-	return tp;
-}
diff --git a/libc/misc/time/localtime.c b/libc/misc/time/localtime.c
deleted file mode 100644
index 22f5035e9..000000000
--- a/libc/misc/time/localtime.c
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#include <time.h>
-#include <sys/time.h>
-
-/* Our static data lives in __time_static.c */
-extern struct tm __tmb;
-
-
-extern void __tm_conv();
-
-struct tm *localtime(__const time_t *timep)
-{
-    struct timezone tz;
-    time_t offt;
-
-    gettimeofday((void *) 0, &tz);
-
-    offt = -tz.tz_minuteswest * 60L;
-
-    /* tmb.tm_isdst = ? */
-    __tm_conv(&__tmb, timep, offt);
-
-    return &__tmb;
-}
diff --git a/libc/misc/time/localtime_r.c b/libc/misc/time/localtime_r.c
deleted file mode 100644
index 139864506..000000000
--- a/libc/misc/time/localtime_r.c
+++ /dev/null
@@ -1,22 +0,0 @@
-
-#include <time.h>
-#include <sys/time.h>
-
-extern void __tm_conv();
-
-struct tm *localtime_r(timep, tp)
-__const time_t *timep;
-struct tm *tp;
-{
-	struct timezone tz;
-	time_t offt;
-
-	gettimeofday((void *) 0, &tz);
-
-	offt = -tz.tz_minuteswest * 60L;
-
-	/* tmb.tm_isdst = ? */
-	__tm_conv(tp, timep, offt);
-
-	return tp;
-}
diff --git a/libc/misc/time/mktime.c b/libc/misc/time/mktime.c
deleted file mode 100644
index 065126e0e..000000000
--- a/libc/misc/time/mktime.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/* Convert a `struct tm' to a time_t value.
-   Copyright (C) 1993, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Paul Eggert (eggert@twinsun.com).
-
-   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.  */
-
-/* Define this to have a standalone program to test this implementation of
-   mktime.  */
-
-#include <features.h>
-/* Assume that leap seconds are not possible */
-#undef LEAP_SECONDS_POSSIBLE 
-#include <sys/types.h>		/* Some systems define `time_t' here.  */
-#include <time.h>
-#include <limits.h>
-
-#if 0
-#ifndef CHAR_BIT
-# define CHAR_BIT 8
-#endif
-
-/* The extra casts work around common compiler bugs.  */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
-   It is necessary at least when t == time_t.  */
-#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
-			      ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
-#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
-
-#ifndef INT_MIN
-# define INT_MIN TYPE_MINIMUM (int)
-#endif
-#ifndef INT_MAX
-# define INT_MAX TYPE_MAXIMUM (int)
-#endif
-
-#ifndef TIME_T_MIN
-# define TIME_T_MIN TYPE_MINIMUM (time_t)
-#endif
-#ifndef TIME_T_MAX
-# define TIME_T_MAX TYPE_MAXIMUM (time_t)
-#endif
-
-#define TM_YEAR_BASE 1900
-#define EPOCH_YEAR 1970
-
-
-/* How many days come before each month (0-12).  */
-extern const unsigned short int __mon_yday[2][13];
-
-
-
-/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
-   measured in seconds, ignoring leap seconds.
-   YEAR uses the same numbering as TM->tm_year.
-   All values are in range, except possibly YEAR.
-   If TP is null, return a nonzero value.
-   If overflow occurs, yield the low order bits of the correct answer.  */
-static time_t
-__ydhms_tm_diff (int year, int yday, int hour, int min, int sec,
-	       const struct tm *tp)
-{
-    if (!tp)
-	return 1;
-    else
-    {
-	/* Compute intervening leap days correctly even if year is negative.
-	   Take care to avoid int overflow.  time_t overflow is OK, since
-	   only the low order bits of the correct time_t answer are needed.
-	   Don't convert to time_t until after all divisions are done, since
-	   time_t might be unsigned.  */
-	int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
-	int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
-	int a100 = a4 / 25 - (a4 % 25 < 0);
-	int b100 = b4 / 25 - (b4 % 25 < 0);
-	int a400 = a100 >> 2;
-	int b400 = b100 >> 2;
-	int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
-	time_t years = year - (time_t) tp->tm_year;
-	time_t days = (365 * years + intervening_leap_days
-		+ (yday - tp->tm_yday));
-	return (60 * (60 * (24 * days + (hour - tp->tm_hour))
-		    + (min - tp->tm_min))
-		+ (sec - tp->tm_sec));
-    }
-}
-
-/* Use CONVERT to convert *T to a broken down time in *TP.
-   If *T is out of range for conversion, adjust it so that
-   it is the nearest in-range value and then convert that.  */
-static struct tm *
-__ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
-		time_t *t, struct tm *tp)
-{
-    struct tm *r;
-
-    if (! (r = (*convert) (t, tp)) && *t)
-    {
-	time_t bad = *t;
-	time_t ok = 0;
-	struct tm tm;
-
-	/* BAD is a known unconvertible time_t, and OK is a known good one.
-	   Use binary search to narrow the range between BAD and OK until
-	   they differ by 1.  */
-	while (bad != ok + (bad < 0 ? -1 : 1))
-	{
-	    time_t mid = *t = (bad < 0
-		    ? bad + ((ok - bad) >> 1)
-		    : ok + ((bad - ok) >> 1));
-	    if ((r = (*convert) (t, tp)))
-	    {
-		tm = *r;
-		ok = mid;
-	    }
-	    else
-		bad = mid;
-	}
-
-	if (!r && ok)
-	{
-	    /* The last conversion attempt failed;
-	       revert to the most recent successful attempt.  */
-	    *t = ok;
-	    *tp = tm;
-	    r = tp;
-	}
-    }
-
-    return r;
-}
-
-
-/* Convert *TP to a time_t value, inverting
-   the monotonic and mostly-unit-linear conversion function CONVERT.
-   Use *OFFSET to keep track of a guess at the offset of the result,
-   compared to what the result would be for UTC without leap seconds.
-   If *OFFSET's guess is correct, only one CONVERT call is needed.  */
-time_t __mktime_internal (struct tm *tp, 
-	struct tm *(*convert) (const time_t *, struct tm *), time_t *offset)
-{
-    time_t t, dt, t0, t1, t2;
-    struct tm tm;
-
-    /* The maximum number of probes (calls to CONVERT) should be enough
-       to handle any combinations of time zone rule changes, solar time,
-       leap seconds, and oscillations around a spring-forward gap.
-       POSIX.1 prohibits leap seconds, but some hosts have them anyway.  */
-    int remaining_probes = 6;
-
-    /* Time requested.  Copy it in case CONVERT modifies *TP; this can
-       occur if TP is localtime's returned value and CONVERT is localtime.  */
-    int sec = tp->tm_sec;
-    int min = tp->tm_min;
-    int hour = tp->tm_hour;
-    int mday = tp->tm_mday;
-    int mon = tp->tm_mon;
-    int year_requested = tp->tm_year;
-    int isdst = tp->tm_isdst;
-
-    /* Ensure that mon is in range, and set year accordingly.  */
-    int mon_remainder = mon % 12;
-    int negative_mon_remainder = mon_remainder < 0;
-    int mon_years = mon / 12 - negative_mon_remainder;
-    int year = year_requested + mon_years;
-
-    /* The other values need not be in range:
-       the remaining code handles minor overflows correctly,
-       assuming int and time_t arithmetic wraps around.
-       Major overflows are caught at the end.  */
-
-    /* Calculate day of year from year, month, and day of month.
-       The result need not be in range.  */
-    int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
-		[mon_remainder + 12 * negative_mon_remainder])
-	    + mday - 1);
-
-    int sec_requested = sec;
-#if LEAP_SECONDS_POSSIBLE
-    /* Handle out-of-range seconds specially,
-       since __ydhms_tm_diff assumes every minute has 60 seconds.  */
-    if (sec < 0)
-	sec = 0;
-    if (59 < sec)
-	sec = 59;
-#endif
-
-    /* Invert CONVERT by probing.  First assume the same offset as last time.
-       Then repeatedly use the error to improve the guess.  */
-
-    tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
-    tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
-    t0 = __ydhms_tm_diff (year, yday, hour, min, sec, &tm);
-
-    for (t = t1 = t2 = t0 + *offset;
-	    (dt = __ydhms_tm_diff (year, yday, hour, min, sec,
-				 __ranged_convert (convert, &t, &tm)));
-	    t1 = t2, t2 = t, t += dt)
-	if (t == t1 && t != t2
-		&& (isdst < 0 || tm.tm_isdst < 0
-		    || (isdst != 0) != (tm.tm_isdst != 0)))
-	    /* We can't possibly find a match, as we are oscillating
-	       between two values.  The requested time probably falls
-	       within a spring-forward gap of size DT.  Follow the common
-	       practice in this case, which is to return a time that is DT
-	       away from the requested time, preferring a time whose
-	       tm_isdst differs from the requested value.  In practice,
-	       this is more useful than returning -1.  */
-	    break;
-	else if (--remaining_probes == 0)
-	    return -1;
-
-    /* If we have a match, check whether tm.tm_isdst has the requested
-       value, if any.  */
-    if (dt == 0 && isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst)
-    {
-	/* tm.tm_isdst has the wrong value.  Look for a neighboring
-	   time with the right value, and use its UTC offset.
-Heuristic: probe the previous three calendar quarters (approximately),
-looking for the desired isdst.  This isn't perfect,
-but it's good enough in practice.  */
-	int quarter = 7889238; /* seconds per average 1/4 Gregorian year */
-	int i;
-
-	/* If we're too close to the time_t limit, look in future quarters.  */
-	if (t < TIME_T_MIN + 3 * quarter)
-	    quarter = -quarter;
-
-	for (i = 1; i <= 3; i++)
-	{
-	    time_t ot = t - i * quarter;
-	    struct tm otm;
-	    __ranged_convert (convert, &ot, &otm);
-	    if (otm.tm_isdst == isdst)
-	    {
-		/* We found the desired tm_isdst.
-		   Extrapolate back to the desired time.  */
-		t = ot + __ydhms_tm_diff (year, yday, hour, min, sec, &otm);
-		__ranged_convert (convert, &t, &tm);
-		break;
-	    }
-	}
-    }
-
-    *offset = t - t0;
-
-#if LEAP_SECONDS_POSSIBLE
-    if (sec_requested != tm.tm_sec)
-    {
-	/* Adjust time to reflect the tm_sec requested, not the normalized value.
-	   Also, repair any damage from a false match due to a leap second.  */
-	t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
-	if (! (*convert) (&t, &tm))
-	    return -1;
-    }
-#endif
-
-    if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
-    {
-	/* time_t isn't large enough to rule out overflows in __ydhms_tm_diff,
-	   so check for major overflows.  A gross check suffices,
-	   since if t has overflowed, it is off by a multiple of
-	   TIME_T_MAX - TIME_T_MIN + 1.  So ignore any component of
-	   the difference that is bounded by a small value.  */
-
-	double dyear = (double) year_requested + mon_years - tm.tm_year;
-	double dday = 366 * dyear + mday;
-	double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
-
-	/* On Irix4.0.5 cc, dividing TIME_T_MIN by 3 does not produce
-	   correct results, ie., it erroneously gives a positive value
-	   of 715827882.  Setting a variable first then doing math on it
-	   seems to work.  (ghazi@caip.rutgers.edu) */
-
-	const time_t time_t_max = TIME_T_MAX;
-	const time_t time_t_min = TIME_T_MIN;
-
-	if (time_t_max / 3 - time_t_min / 3 < (dsec < 0 ? - dsec : dsec))
-	    return -1;
-    }
-
-    *tp = tm;
-    return t;
-}
-
-
-
-/* Convert *TP to a time_t value.  */
-time_t mktime (struct tm *tp)
-{
-    static time_t localtime_offset;
-    /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
-       time zone names contained in the external variable `tzname' shall
-       be set as if the tzset() function had been called.  */
-    tzset ();
-
-    return __mktime_internal (tp, localtime_r, &localtime_offset);
-}
-#else
-
-/* Convert *TP to a time_t value.  */
-time_t mktime (struct tm *tp)
-{
-    time_t m_secs=tp->tm_min*60;
-    time_t h_secs=tp->tm_hour*3600;
-    time_t d_secs=tp->tm_yday*86400;
-    time_t y_secs=(tp->tm_year-70)*31536000;
-    time_t l_secs1=((tp->tm_year-69)/4)*86400;
-    time_t l_secs2=((tp->tm_year-1)/100)*86400;
-    time_t l_secs3=((tp->tm_year+299)/400)*86400;
-    return m_secs+h_secs+d_secs+y_secs+l_secs1-l_secs2+l_secs3+tp->tm_gmtoff;
-}
-#endif
diff --git a/libc/misc/time/strftime.c b/libc/misc/time/strftime.c
deleted file mode 100644
index bde0d93d8..000000000
--- a/libc/misc/time/strftime.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/* Copyright (C) 1991, 92, 93, 94, 95, 96 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>		/* Some systems define `time_t' here.  */
-#include <sys/time.h>
-#include <time.h>
-#include <ctype.h>
-#include <limits.h>
-
-static unsigned int week (const struct tm *const, int, int);
-
-#define	add(n, f)							      \
-  do									      \
-    {									      \
-      i += (n);								      \
-      if (i >= maxsize)							      \
-	return 0;							      \
-      else								      \
-	if (p)								      \
-	  {								      \
-	    f;								      \
-	    p += (n);							      \
-	  }								      \
-    } while (0)
-#define	cpy(n, s)	add((n), memcpy((void *) p, (void *) (s), (n)))
-
-#ifdef _LIBC
-#define	fmt(n, args)	add((n), if (sprintf args != (n)) return 0)
-#else
-#define	fmt(n, args)	add((n), sprintf args; if (strlen (p) != (n)) return 0)
-#endif
-
-
-
-/* Return the week in the year specified by TP,
-   with weeks starting on STARTING_DAY.  */
-static unsigned int week(const struct tm *const tp , int starting_day , int max_preceding )
-{
-  int wday, dl, base;
-
-  wday = tp->tm_wday - starting_day;
-  if (wday < 0)
-    wday += 7;
-
-  /* Set DL to the day in the year of the first day of the week
-     containing the day specified in TP.  */
-  dl = tp->tm_yday - wday;
-
-  /* For the computation following ISO 8601:1988 we set the number of
-     the week containing January 1st to 1 if this week has more than
-     MAX_PRECEDING days in the new year.  For ISO 8601 this number is
-     3, for the other representation it is 7 (i.e., not to be
-     fulfilled).  */
-  base = ((dl + 7) % 7) > max_preceding ? 1 : 0;
-
-  /* If DL is negative we compute the result as 0 unless we have to
-     compute it according ISO 8601.  In this case we have to return 53
-     or 1 if the week containing January 1st has less than 4 days in
-     the new year or not.  If DL is not negative we calculate the
-     number of complete weeks for our week (DL / 7) plus 1 (because
-     only for DL < 0 we are in week 0/53 and plus the number of the
-     first week computed in the last step.  */
-  return dl < 0 ? (dl < -max_preceding ? 53 : base)
-		: base + 1 + dl / 7;
-}
-
-#ifndef __UCLIBC_HAS_LOCALE__
-extern char const __weekday_name[][10];
-extern char const __month_name[][10];
-#endif
-
-/* Write information from TP into S according to the format
-   string FORMAT, writing no more that MAXSIZE characters
-   (including the terminating '\0') and returning number of
-   characters written.  If S is NULL, nothing will be written
-   anywhere, so to determine how many characters would be
-   written, use NULL for S and (size_t) UINT_MAX for MAXSIZE.  */
-size_t strftime( char *s , size_t maxsize , const char *format , register const struct tm *tp)
-{
-  int hour12 = tp->tm_hour;
-#ifdef __UCLIBC_HAS_LOCALE__
-  const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
-  const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
-  const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
-  const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
-  const char *const ampm = _NL_CURRENT (LC_TIME,
-					hour12 > 11 ? PM_STR : AM_STR);
-  size_t aw_len = strlen(a_wkday);
-  size_t am_len = strlen(a_month);
-  size_t ap_len = strlen (ampm);
-#else
-  const char *const f_wkday = __weekday_name[tp->tm_wday];
-  const char *const f_month = __month_name[tp->tm_mon];
-  const char *const a_wkday = f_wkday;
-  const char *const a_month = f_month;
-  const char *const ampm = "AMPM" + 2 * (hour12 > 11);
-  size_t aw_len = 3;
-  size_t am_len = 3;
-  size_t ap_len = 2;
-#endif
-  size_t wkday_len = strlen(f_wkday);
-  size_t month_len = strlen(f_month);
-  const unsigned int y_week0 = week (tp, 0, 7);
-  const unsigned int y_week1 = week (tp, 1, 7);
-  const unsigned int y_week2 = week (tp, 1, 3);
-  const char *zone;
-  size_t zonelen;
-  register size_t i = 0;
-  register char *p = s;
-  register const char *f;
-  char number_fmt[5];
-
-  /* Initialize the buffer we will use for the sprintf format for numbers.  */
-  number_fmt[0] = '%';
-
-  /* The POSIX test suite assumes that setting
-     the environment variable TZ to a new value before calling strftime()
-     will influence the result (the %Z format) even if the information in
-     TP is computed with a totally different time zone.
-     This is bogus: though POSIX allows bad behavior like this,
-     POSIX does not require it.  Do the right thing instead.  */
-  zone = (const char *) tp->tm_zone;
-  /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
-     time zone names contained in the external variable `tzname' shall
-     be set as if the tzset() function had been called.  */
-  tzset ();
-  zonelen = strlen (zone);
-
-  if (hour12 > 12)
-    hour12 -= 12;
-  else
-    if (hour12 == 0) hour12 = 12;
-
-  for (f = format; *f != '\0'; ++f)
-    {
-      enum { pad_zero, pad_space, pad_none } pad; /* Padding for number.  */
-      unsigned int maxdigits;	/* Max digits for numeric format.  */
-      unsigned int number_value; /* Numeric value to be printed.  */
-      const char *subfmt;
-
-#if HAVE_MBLEN
-      if (!isascii(*f))
-	{
-	  /* Non-ASCII, may be a multibyte.  */
-	  int len = mblen(f, strlen(f));
-	  if (len > 0)
-	    {
-	      cpy(len, f);
-	      continue;
-	    }
-	}
-#endif
-
-      if (*f != '%')
-	{
-	  add(1, *p = *f);
-	  continue;
-	}
-
-      /* Check for flags that can modify a number format.  */
-      ++f;
-      switch (*f)
-	{
-	case '_':
-	  pad = pad_space;
-	  ++f;
-	  break;
-	case '-':
-	  pad = pad_none;
-	  ++f;
-	  break;
-	default:
-	  pad = pad_zero;
-	  break;
-	}
-
-      /* Now do the specified format.  */
-      switch (*f)
-	{
-	case '\0':
-	case '%':
-	  add(1, *p = *f);
-	  break;
-
-	case 'a':
-	  cpy(aw_len, a_wkday);
-	  break;
-
-	case 'A':
-	  cpy(wkday_len, f_wkday);
-	  break;
-
-	case 'b':
-	case 'h':		/* GNU extension.  */
-	  cpy(am_len, a_month);
-	  break;
-
-	case 'B':
-	  cpy(month_len, f_month);
-	  break;
-
-	case 'c':
-#ifdef __UCLIBC_HAS_LOCALE__
-	  subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
-#else
-	  subfmt = "%a %b %d %H:%M:%S %Z %Y";
-#endif
-	subformat:
-	  {
-	    size_t len = strftime (p, maxsize - i, subfmt, tp);
-	    if (len == 0 && *subfmt)
-	      return 0;
-	    add(len, );
-	  }
-	  break;
-
-#define DO_NUMBER(digits, value) \
-	  maxdigits = digits; number_value = value; goto do_number
-#define DO_NUMBER_NOPAD(digits, value) \
-	  maxdigits = digits; number_value = value; goto do_number_nopad
-
-	case 'C':
-	  DO_NUMBER (2, (1900 + tp->tm_year) / 100);
-
-	case 'x':
-#ifdef __UCLIBC_HAS_LOCALE__
-	  subfmt = _NL_CURRENT (LC_TIME, D_FMT);
-	  goto subformat;
-#endif
-	  /* Fall through.  */
-	case 'D':		/* GNU extension.  */
-	  subfmt = "%m/%d/%y";
-	  goto subformat;
-
-	case 'd':
-	  DO_NUMBER (2, tp->tm_mday);
-
-	case 'e':		/* GNU extension: %d, but blank-padded.  */
-#if 0
-	  DO_NUMBER_NOPAD (2, tp->tm_mday);
-#else
-	  DO_NUMBER (2, tp->tm_mday);
-#endif
-
-	  /* All numeric formats set MAXDIGITS and NUMBER_VALUE and then
-	     jump to one of these two labels.  */
-
-	do_number_nopad:
-	  /* Force `-' flag.  */
-	  pad = pad_none;
-
-	do_number:
-	  {
-	    /* Format the number according to the PAD flag.  */
-
-	    register char *nf = &number_fmt[1];
-	    int printed;
-
-	    switch (pad)
-	      {
-	      case pad_zero:
-		*nf++ = '0';
-	      case pad_space:
-		*nf++ = '0' + maxdigits;
-	      case pad_none:
-		*nf++ = 'u';
-		*nf = '\0';
-	      }
-
-#ifdef _LIBC
-	    if (i + maxdigits >= maxsize)
-		return 0;
-	    printed = sprintf (p, number_fmt, number_value);
-	    i += printed;
-	    p += printed;
-#else
-	    add (maxdigits, sprintf (p, number_fmt, number_value);
-		 printed = strlen (p));
-#endif
-
-	    break;
-	  }
-
-
-	case 'H':
-	  DO_NUMBER (2, tp->tm_hour);
-
-	case 'I':
-	  DO_NUMBER (2, hour12);
-
-	case 'k':		/* GNU extension.  */
-	  DO_NUMBER_NOPAD (2, tp->tm_hour);
-
-	case 'l':		/* GNU extension.  */
-	  DO_NUMBER_NOPAD (2, hour12);
-
-	case 'j':
-	  DO_NUMBER (3, 1 + tp->tm_yday);
-
-	case 'M':
-	  DO_NUMBER (2, tp->tm_min);
-
-	case 'm':
-	  DO_NUMBER (2, tp->tm_mon + 1);
-
-	case 'n':		/* GNU extension.  */
-	  add (1, *p = '\n');
-	  break;
-
-	case 'p':
-	  cpy(ap_len, ampm);
-	  break;
-
-	case 'R':		/* GNU extension.  */
-	  subfmt = "%H:%M";
-	  goto subformat;
-
-	case 'r':		/* GNU extension.  */
-	  subfmt = "%I:%M:%S %p";
-	  goto subformat;
-
-	case 'S':
-	  DO_NUMBER (2, tp->tm_sec);
-
-	case 'X':
-#ifdef __UCLIBC_HAS_LOCALE__
-	  subfmt = _NL_CURRENT (LC_TIME, T_FMT);
-	  goto subformat;
-#endif
-	  /* Fall through.  */
-	case 'T':		/* GNU extenstion.  */
-	  subfmt = "%H:%M:%S";
-	  goto subformat;
-
-	case 't':		/* GNU extenstion.  */
-	  add (1, *p = '\t');
-	  break;
-
-	case 'U':
-	  DO_NUMBER (2, y_week0);
-
-	case 'V':
-	  DO_NUMBER (2, y_week2);
-
-	case 'W':
-	  DO_NUMBER (2, y_week1);
-
-	case 'w':
-	  DO_NUMBER (1, tp->tm_wday);
-
-	case 'Y':
-	  DO_NUMBER (4, 1900 + tp->tm_year);
-
-	case 'y':
-	  DO_NUMBER (2, tp->tm_year % 100);
-
-	case 'Z':
-	  /* The tzset() call might have changed the value.  */
-	  if (!(zone && *zone) && tp->tm_isdst >= 0)
-	    zone = tzname[tp->tm_isdst];
-	  if (! zone)
-	    zone = "";		/* POSIX.2 requires the empty string here.  */
-	  cpy(zonelen, zone);
-	  break;
-
-	default:
-	  /* Bad format.  */
-	  break;
-	}
-    }
-
-  if (p)
-    *p = '\0';
-  return i;
-}
diff --git a/libc/misc/time/strptime.c b/libc/misc/time/strptime.c
deleted file mode 100644
index 749eb797d..000000000
--- a/libc/misc/time/strptime.c
+++ /dev/null
@@ -1,983 +0,0 @@
-/* Convert a string representation of time to a time value.
-   Copyright (C) 1996-2000, 2001 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
-
-   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.  */
-
-/* XXX This version of the implementation is not really complete.
-   Some of the fields cannot add information alone.  But if seeing
-   some of them in the same format (such as year, week and weekday)
-   this is enough information for determining the date.  */
-
-#include <features.h>
-#include <ctype.h>
-#include <langinfo.h>
-#include <limits.h>
-#include <string.h>
-#include <time.h>
-
-#undef ENABLE_ERA_JUNK
-
-
-#define match_char(ch1, ch2) if (ch1 != ch2) return NULL
-#if defined __GNUC__ && __GNUC__ >= 2
-# define match_string(cs1, s2) \
-  ({ size_t len = strlen (cs1);						      \
-     int result = strncasecmp ((cs1), (s2), len) == 0;			      \
-     if (result) (s2) += len;						      \
-     result; })
-#else
-/* Oh come on.  Get a reasonable compiler.  */
-# define match_string(cs1, s2) \
-  (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
-#endif
-/* We intentionally do not use isdigit() for testing because this will
-   lead to problems with the wide character version.  */
-#define get_number(from, to, n) \
-  do {									      \
-    int __n = n;							      \
-    val = 0;								      \
-    while (*rp == ' ')							      \
-      ++rp;								      \
-    if (*rp < '0' || *rp > '9')						      \
-      return NULL;							      \
-    do {								      \
-      val *= 10;							      \
-      val += *rp++ - '0';						      \
-    } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9');	      \
-    if (val < from || val > to)						      \
-      return NULL;							      \
-  } while (0)
-#ifdef __UCLIBC_HAS_LOCALE__
-# define get_alt_number(from, to, n) \
-  ({									      \
-     __label__ do_normal;						      \
-									      \
-     if (*decided != raw)						      \
-       {								      \
-	 val = _nl_parse_alt_digit (&rp);				      \
-	 if (val == -1 && *decided != loc)				      \
-	   {								      \
-	     *decided = loc;						      \
-	     goto do_normal;						      \
-	   }								      \
-	if (val < from || val > to)					      \
-	  return NULL;							      \
-       }								      \
-     else								      \
-       {								      \
-       do_normal:							      \
-	 get_number (from, to, n);					      \
-       }								      \
-    0;									      \
-  })
-#else
-# define get_alt_number(from, to, n) \
-  /* We don't have the alternate representation.  */			      \
-  get_number(from, to, n)
-#endif
-#define recursive(new_fmt) \
-  (*(new_fmt) != '\0'							      \
-   && (rp = __strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL)
-
-
-#ifdef __UCLIBC_HAS_LOCALE__
-/* This is defined in locale/C-time.c in the GNU libc.  */
-extern const struct locale_data _nl_C_LC_TIME;
-extern const unsigned short int __mon_yday[2][13];
-
-# define __weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
-# define __ab_weekday_name \
-  (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
-# define __month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
-# define __ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
-# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
-# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
-# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
-# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
-# define HERE_T_FMT_AMPM \
-  (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
-# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
-
-# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
-#else
-extern char const __weekday_name[][10];
-extern char const __ab_weekday_name[][4];
-extern char const __month_name[][10];
-extern char const __ab_month_name[][4];
-extern const unsigned short int __mon_yday[2][13];
-# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
-# define HERE_D_FMT "%m/%d/%y"
-# define HERE_AM_STR "AM"
-# define HERE_PM_STR "PM"
-# define HERE_T_FMT_AMPM "%I:%M:%S %p"
-# define HERE_T_FMT "%H:%M:%S"
-#endif
-
-/* Status of lookup: do we use the locale data or the raw data?  */
-enum locale_status { not, loc, raw };
-
-
-#ifndef __isleap
-/* Nonzero if YEAR is a leap year (every 4 years,
-   except every 100th isn't, and every 400th is).  */
-# define __isleap(year)	\
-  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
-#endif
-
-/* Compute the day of the week.  */
-static void
-day_of_the_week (struct tm *tm)
-{
-    /* We know that January 1st 1970 was a Thursday (= 4).  Compute the
-       the difference between this data in the one on TM and so determine
-       the weekday.  */
-    int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
-    int wday = (-473
-	    + (365 * (tm->tm_year - 70))
-	    + (corr_year / 4)
-	    - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
-	    + (((corr_year / 4) / 25) / 4)
-	    + __mon_yday[0][tm->tm_mon]
-	    + tm->tm_mday - 1);
-    tm->tm_wday = ((wday % 7) + 7) % 7;
-}
-
-/* Compute the day of the year.  */
-static void
-day_of_the_year (struct tm *tm)
-{
-    tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
-	    + (tm->tm_mday - 1));
-}
-
-
-static char * __strptime_internal (rp, fmt, tm, decided, era_cnt)
-     const char *rp;
-     const char *fmt;
-     struct tm *tm;
-     enum locale_status *decided;
-     int era_cnt;
-{
-    const char *rp_backup;
-    int cnt;
-    size_t val;
-    int have_I, is_pm;
-    int century, want_century;
-    int want_era;
-    int have_wday, want_xday;
-    int have_yday;
-    int have_mon, have_mday;
-    int have_uweek, have_wweek;
-    int week_no;
-#ifdef ENABLE_ERA_JUNK
-    size_t num_eras;
-    struct era_entry *era;
-
-    era = NULL;
-#endif
-    have_I = is_pm = 0;
-    century = -1;
-    want_century = 0;
-    want_era = 0;
-    week_no = 0;
-
-    have_wday = want_xday = have_yday = have_mon = have_mday = have_uweek = 0;
-    have_wweek = 0;
-
-    while (*fmt != '\0')
-    {
-	/* A white space in the format string matches 0 more or white
-	   space in the input string.  */
-	if (isspace (*fmt))
-	{
-	    while (isspace (*rp))
-		++rp;
-	    ++fmt;
-	    continue;
-	}
-
-	/* Any character but `%' must be matched by the same character
-	   in the iput string.  */
-	if (*fmt != '%')
-	{
-	    match_char (*fmt++, *rp++);
-	    continue;
-	}
-
-	++fmt;
-#ifndef __UCLIBC_HAS_LOCALE__
-	/* We need this for handling the `E' modifier.  */
-start_over:
-#endif
-
-	/* Make back up of current processing pointer.  */
-	rp_backup = rp;
-
-	switch (*fmt++)
-	{
-	    case '%':
-		/* Match the `%' character itself.  */
-		match_char ('%', *rp++);
-		break;
-	    case 'a':
-	    case 'A':
-		/* Match day of week.  */
-		for (cnt = 0; cnt < 7; ++cnt)
-		{
-#ifdef __UCLIBC_HAS_LOCALE__
-		    if (*decided !=raw)
-		    {
-			if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
-			{
-			    if (*decided == not
-				    && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
-					__weekday_name[cnt]))
-				*decided = loc;
-			    break;
-			}
-			if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
-			{
-			    if (*decided == not
-				    && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
-					__ab_weekday_name[cnt]))
-				*decided = loc;
-			    break;
-			}
-		    }
-#endif
-		    if (*decided != loc
-			    && (match_string (__weekday_name[cnt], rp)
-				|| match_string (__ab_weekday_name[cnt], rp)))
-		    {
-			*decided = raw;
-			break;
-		    }
-		}
-		if (cnt == 7)
-		    /* Does not match a weekday name.  */
-		    return NULL;
-		tm->tm_wday = cnt;
-		have_wday = 1;
-		break;
-	    case 'b':
-	    case 'B':
-	    case 'h':
-		/* Match month name.  */
-		for (cnt = 0; cnt < 12; ++cnt)
-		{
-#ifdef __UCLIBC_HAS_LOCALE__
-		    if (*decided !=raw)
-		    {
-			if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
-			{
-			    if (*decided == not
-				    && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
-					__month_name[cnt]))
-				*decided = loc;
-			    break;
-			}
-			if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
-			{
-			    if (*decided == not
-				    && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
-					__ab_month_name[cnt]))
-				*decided = loc;
-			    break;
-			}
-		    }
-#endif
-		    if (match_string (__month_name[cnt], rp)
-			    || match_string (__ab_month_name[cnt], rp))
-		    {
-			*decided = raw;
-			break;
-		    }
-		}
-		if (cnt == 12)
-		    /* Does not match a month name.  */
-		    return NULL;
-		tm->tm_mon = cnt;
-		want_xday = 1;
-		break;
-	    case 'c':
-		/* Match locale's date and time format.  */
-#ifdef __UCLIBC_HAS_LOCALE__
-		if (*decided != raw)
-		{
-		    if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
-		    {
-			if (*decided == loc)
-			    return NULL;
-			else
-			    rp = rp_backup;
-		    }
-		    else
-		    {
-			if (*decided == not &&
-				strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
-			    *decided = loc;
-			want_xday = 1;
-			break;
-		    }
-		    *decided = raw;
-		}
-#endif
-		if (!recursive (HERE_D_T_FMT))
-		    return NULL;
-		want_xday = 1;
-		break;
-	    case 'C':
-		/* Match century number.  */
-#ifdef __UCLIBC_HAS_LOCALE__
-match_century:
-#endif
-		get_number (0, 99, 2);
-		century = val;
-		want_xday = 1;
-		break;
-	    case 'd':
-	    case 'e':
-		/* Match day of month.  */
-		get_number (1, 31, 2);
-		tm->tm_mday = val;
-		have_mday = 1;
-		want_xday = 1;
-		break;
-	    case 'F':
-		if (!recursive ("%Y-%m-%d"))
-		    return NULL;
-		want_xday = 1;
-		break;
-	    case 'x':
-#ifdef __UCLIBC_HAS_LOCALE__
-		if (*decided != raw)
-		{
-		    if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
-		    {
-			if (*decided == loc)
-			    return NULL;
-			else
-			    rp = rp_backup;
-		    }
-		    else
-		    {
-			if (*decided == not
-				&& strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
-			    *decided = loc;
-			want_xday = 1;
-			break;
-		    }
-		    *decided = raw;
-		}
-#endif
-		/* Fall through.  */
-	    case 'D':
-		/* Match standard day format.  */
-		if (!recursive (HERE_D_FMT))
-		    return NULL;
-		want_xday = 1;
-		break;
-	    case 'k':
-	    case 'H':
-		/* Match hour in 24-hour clock.  */
-		get_number (0, 23, 2);
-		tm->tm_hour = val;
-		have_I = 0;
-		break;
-	    case 'l':
-		/* Match hour in 12-hour clock.  GNU extension.  */
-	    case 'I':
-		/* Match hour in 12-hour clock.  */
-		get_number (1, 12, 2);
-		tm->tm_hour = val % 12;
-		have_I = 1;
-		break;
-	    case 'j':
-		/* Match day number of year.  */
-		get_number (1, 366, 3);
-		tm->tm_yday = val - 1;
-		have_yday = 1;
-		break;
-	    case 'm':
-		/* Match number of month.  */
-		get_number (1, 12, 2);
-		tm->tm_mon = val - 1;
-		have_mon = 1;
-		want_xday = 1;
-		break;
-	    case 'M':
-		/* Match minute.  */
-		get_number (0, 59, 2);
-		tm->tm_min = val;
-		break;
-	    case 'n':
-	    case 't':
-		/* Match any white space.  */
-		while (isspace (*rp))
-		    ++rp;
-		break;
-	    case 'p':
-		/* Match locale's equivalent of AM/PM.  */
-#ifdef __UCLIBC_HAS_LOCALE__
-		if (*decided != raw)
-		{
-		    if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
-		    {
-			if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
-			    *decided = loc;
-			break;
-		    }
-		    if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
-		    {
-			if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
-			    *decided = loc;
-			is_pm = 1;
-			break;
-		    }
-		    *decided = raw;
-		}
-#endif
-		if (!match_string (HERE_AM_STR, rp))
-		    if (match_string (HERE_PM_STR, rp))
-			is_pm = 1;
-		    else
-			return NULL;
-		break;
-	    case 'r':
-#ifdef __UCLIBC_HAS_LOCALE__
-		if (*decided != raw)
-		{
-		    if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
-		    {
-			if (*decided == loc)
-			    return NULL;
-			else
-			    rp = rp_backup;
-		    }
-		    else
-		    {
-			if (*decided == not &&
-				strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
-				    HERE_T_FMT_AMPM))
-			    *decided = loc;
-			break;
-		    }
-		    *decided = raw;
-		}
-#endif
-		if (!recursive (HERE_T_FMT_AMPM))
-		    return NULL;
-		break;
-	    case 'R':
-		if (!recursive ("%H:%M"))
-		    return NULL;
-		break;
-	    case 's':
-		{
-		    /* The number of seconds may be very high so we cannot use
-		       the `get_number' macro.  Instead read the number
-		       character for character and construct the result while
-		       doing this.  */
-		    time_t secs = 0;
-		    if (*rp < '0' || *rp > '9')
-			/* We need at least one digit.  */
-			return NULL;
-
-		    do
-		    {
-			secs *= 10;
-			secs += *rp++ - '0';
-		    }
-		    while (*rp >= '0' && *rp <= '9');
-
-		    if (localtime_r (&secs, tm) == NULL)
-			/* Error in function.  */
-			return NULL;
-		}
-		break;
-	    case 'S':
-		get_number (0, 61, 2);
-		tm->tm_sec = val;
-		break;
-	    case 'X':
-#ifdef __UCLIBC_HAS_LOCALE__
-		if (*decided != raw)
-		{
-		    if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
-		    {
-			if (*decided == loc)
-			    return NULL;
-			else
-			    rp = rp_backup;
-		    }
-		    else
-		    {
-			if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
-			    *decided = loc;
-			break;
-		    }
-		    *decided = raw;
-		}
-#endif
-		/* Fall through.  */
-	    case 'T':
-		if (!recursive (HERE_T_FMT))
-		    return NULL;
-		break;
-	    case 'u':
-		get_number (1, 7, 1);
-		tm->tm_wday = val % 7;
-		have_wday = 1;
-		break;
-	    case 'g':
-		get_number (0, 99, 2);
-		/* XXX This cannot determine any field in TM.  */
-		break;
-	    case 'G':
-		if (*rp < '0' || *rp > '9')
-		    return NULL;
-		/* XXX Ignore the number since we would need some more
-		   information to compute a real date.  */
-		do
-		    ++rp;
-		while (*rp >= '0' && *rp <= '9');
-		break;
-	    case 'U':
-		get_number (0, 53, 2);
-		week_no = val;
-		have_uweek = 1;
-		break;
-	    case 'W':
-		get_number (0, 53, 2);
-		week_no = val;
-		have_wweek = 1;
-		break;
-	    case 'V':
-		get_number (0, 53, 2);
-		/* XXX This cannot determine any field in TM without some
-		   information.  */
-		break;
-	    case 'w':
-		/* Match number of weekday.  */
-		get_number (0, 6, 1);
-		tm->tm_wday = val;
-		have_wday = 1;
-		break;
-	    case 'y':
-#ifdef __UCLIBC_HAS_LOCALE__
-match_year_in_century:
-#endif
-		/* Match year within century.  */
-		get_number (0, 99, 2);
-		/* The "Year 2000: The Millennium Rollover" paper suggests that
-		   values in the range 69-99 refer to the twentieth century.  */
-		tm->tm_year = val >= 69 ? val : val + 100;
-		/* Indicate that we want to use the century, if specified.  */
-		want_century = 1;
-		want_xday = 1;
-		break;
-	    case 'Y':
-		/* Match year including century number.  */
-		get_number (0, 9999, 4);
-		tm->tm_year = val - 1900;
-		want_century = 0;
-		want_xday = 1;
-		break;
-	    case 'Z':
-		/* XXX How to handle this?  */
-		break;
-	    case 'E':
-#ifdef __UCLIBC_HAS_LOCALE__
-		switch (*fmt++)
-		{
-		    case 'c':
-			/* Match locale's alternate date and time format.  */
-			if (*decided != raw)
-			{
-			    const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
-
-			    if (*fmt == '\0')
-				fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
-
-			    if (!recursive (fmt))
-			    {
-				if (*decided == loc)
-				    return NULL;
-				else
-				    rp = rp_backup;
-			    }
-			    else
-			    {
-				if (strcmp (fmt, HERE_D_T_FMT))
-				    *decided = loc;
-				want_xday = 1;
-				break;
-			    }
-			    *decided = raw;
-			}
-			/* The C locale has no era information, so use the
-			   normal representation.  */
-			if (!recursive (HERE_D_T_FMT))
-			    return NULL;
-			want_xday = 1;
-			break;
-		    case 'C':
-#ifdef ENABLE_ERA_JUNK
-			if (*decided != raw)
-			{
-			    if (era_cnt >= 0)
-			    {
-				era = _nl_select_era_entry (era_cnt);
-				if (match_string (era->era_name, rp))
-				{
-				    *decided = loc;
-				    break;
-				}
-				else
-				    return NULL;
-			    }
-			    else
-			    {
-				num_eras = _NL_CURRENT_WORD (LC_TIME,
-					_NL_TIME_ERA_NUM_ENTRIES);
-				for (era_cnt = 0; era_cnt < (int) num_eras;
-					++era_cnt, rp = rp_backup)
-				{
-				    era = _nl_select_era_entry (era_cnt);
-				    if (match_string (era->era_name, rp))
-				    {
-					*decided = loc;
-					break;
-				    }
-				}
-				if (era_cnt == (int) num_eras)
-				{
-				    era_cnt = -1;
-				    if (*decided == loc)
-					return NULL;
-				}
-				else
-				    break;
-			    }
-
-			    *decided = raw;
-			}
-#endif
-			/* The C locale has no era information, so use the
-			   normal representation.  */
-			goto match_century;
-		    case 'y':
-			if (*decided == raw)
-			    goto match_year_in_century;
-
-			get_number(0, 9999, 4);
-			tm->tm_year = val;
-			want_era = 1;
-			want_xday = 1;
-			want_century = 1;
-			break;
-		    case 'Y':
-#ifdef ENABLE_ERA_JUNK
-			if (*decided != raw)
-			{
-			    num_eras = _NL_CURRENT_WORD (LC_TIME,
-				    _NL_TIME_ERA_NUM_ENTRIES);
-			    for (era_cnt = 0; era_cnt < (int) num_eras;
-				    ++era_cnt, rp = rp_backup)
-			    {
-				era = _nl_select_era_entry (era_cnt);
-				if (recursive (era->era_format))
-				    break;
-			    }
-			    if (era_cnt == (int) num_eras)
-			    {
-				era_cnt = -1;
-				if (*decided == loc)
-				    return NULL;
-				else
-				    rp = rp_backup;
-			    }
-			    else
-			    {
-				*decided = loc;
-				era_cnt = -1;
-				break;
-			    }
-
-			    *decided = raw;
-			}
-#endif
-			get_number (0, 9999, 4);
-			tm->tm_year = val - 1900;
-			want_century = 0;
-			want_xday = 1;
-			break;
-		    case 'x':
-			if (*decided != raw)
-			{
-			    const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
-
-			    if (*fmt == '\0')
-				fmt = _NL_CURRENT (LC_TIME, D_FMT);
-
-			    if (!recursive (fmt))
-			    {
-				if (*decided == loc)
-				    return NULL;
-				else
-				    rp = rp_backup;
-			    }
-			    else
-			    {
-				if (strcmp (fmt, HERE_D_FMT))
-				    *decided = loc;
-				break;
-			    }
-			    *decided = raw;
-			}
-			if (!recursive (HERE_D_FMT))
-			    return NULL;
-			break;
-		    case 'X':
-			if (*decided != raw)
-			{
-			    const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
-
-			    if (*fmt == '\0')
-				fmt = _NL_CURRENT (LC_TIME, T_FMT);
-
-			    if (!recursive (fmt))
-			    {
-				if (*decided == loc)
-				    return NULL;
-				else
-				    rp = rp_backup;
-			    }
-			    else
-			    {
-				if (strcmp (fmt, HERE_T_FMT))
-				    *decided = loc;
-				break;
-			    }
-			    *decided = raw;
-			}
-			if (!recursive (HERE_T_FMT))
-			    return NULL;
-			break;
-		    default:
-			return NULL;
-		}
-		break;
-#else
-		/* We have no information about the era format.  Just use
-		   the normal format.  */
-		if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
-			&& *fmt != 'x' && *fmt != 'X')
-		    /* This is an illegal format.  */
-		    return NULL;
-
-		goto start_over;
-#endif
-	    case 'O':
-		switch (*fmt++)
-		{
-		    case 'd':
-		    case 'e':
-			/* Match day of month using alternate numeric symbols.  */
-			get_alt_number (1, 31, 2);
-			tm->tm_mday = val;
-			have_mday = 1;
-			want_xday = 1;
-			break;
-		    case 'H':
-			/* Match hour in 24-hour clock using alternate numeric
-			   symbols.  */
-			get_alt_number (0, 23, 2);
-			tm->tm_hour = val;
-			have_I = 0;
-			break;
-		    case 'I':
-			/* Match hour in 12-hour clock using alternate numeric
-			   symbols.  */
-			get_alt_number (1, 12, 2);
-			tm->tm_hour = val % 12;
-			have_I = 1;
-			break;
-		    case 'm':
-			/* Match month using alternate numeric symbols.  */
-			get_alt_number (1, 12, 2);
-			tm->tm_mon = val - 1;
-			have_mon = 1;
-			want_xday = 1;
-			break;
-		    case 'M':
-			/* Match minutes using alternate numeric symbols.  */
-			get_alt_number (0, 59, 2);
-			tm->tm_min = val;
-			break;
-		    case 'S':
-			/* Match seconds using alternate numeric symbols.  */
-			get_alt_number (0, 61, 2);
-			tm->tm_sec = val;
-			break;
-		    case 'U':
-			get_alt_number (0, 53, 2);
-			week_no = val;
-			have_uweek = 1;
-			break;
-		    case 'W':
-			get_alt_number (0, 53, 2);
-			week_no = val;
-			have_wweek = 1;
-			break;
-		    case 'V':
-			get_alt_number (0, 53, 2);
-			/* XXX This cannot determine any field in TM without
-			   further information.  */
-			break;
-		    case 'w':
-			/* Match number of weekday using alternate numeric symbols.  */
-			get_alt_number (0, 6, 1);
-			tm->tm_wday = val;
-			have_wday = 1;
-			break;
-		    case 'y':
-			/* Match year within century using alternate numeric symbols.  */
-			get_alt_number (0, 99, 2);
-			tm->tm_year = val >= 69 ? val : val + 100;
-			want_xday = 1;
-			break;
-		    default:
-			return NULL;
-		}
-		break;
-	    default:
-		return NULL;
-	}
-    }
-
-    if (have_I && is_pm)
-	tm->tm_hour += 12;
-
-    if (century != -1)
-    {
-	if (want_century)
-	    tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
-	else
-	    /* Only the century, but not the year.  Strange, but so be it.  */
-	    tm->tm_year = (century - 19) * 100;
-    }
-
-#ifdef ENABLE_ERA_JUNK
-    if (era_cnt != -1)
-    {
-	era = _nl_select_era_entry (era_cnt);
-	if (want_era)
-	    tm->tm_year = (era->start_date[0]
-		    + ((tm->tm_year - era->offset)
-			* era->absolute_direction));
-	else
-	    /* Era start year assumed.  */
-	    tm->tm_year = era->start_date[0];
-    }
-    else
-#endif
-	if (want_era)
-	{
-	    /* No era found but we have seen an E modifier.  Rectify some
-	       values.  */
-	    if (want_century && century == -1 && tm->tm_year < 69)
-		tm->tm_year += 100;
-	}
-
-    if (want_xday && !have_wday)
-    {
-	if ( !(have_mon && have_mday) && have_yday)
-	{
-	    /* We don't have tm_mon and/or tm_mday, compute them.  */
-	    int t_mon = 0;
-	    while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
-		t_mon++;
-	    if (!have_mon)
-		tm->tm_mon = t_mon - 1;
-	    if (!have_mday)
-		tm->tm_mday =
-		    (tm->tm_yday
-		     - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1);
-	}
-	day_of_the_week (tm);
-    }
-
-    if (want_xday && !have_yday)
-	day_of_the_year (tm);
-
-    if ((have_uweek || have_wweek) && have_wday)
-    {
-	int save_wday = tm->tm_wday;
-	int save_mday = tm->tm_mday;
-	int save_mon = tm->tm_mon;
-	int w_offset = have_uweek ? 0 : 1;
-
-	tm->tm_mday = 1;
-	tm->tm_mon = 0;
-	day_of_the_week (tm);
-	if (have_mday)
-	    tm->tm_mday = save_mday;
-	if (have_mon)
-	    tm->tm_mon = save_mon;
-
-	if (!have_yday)
-	    tm->tm_yday = ((7 - (tm->tm_wday - w_offset)) % 7
-		    + (week_no - 1) *7
-		    + save_wday - w_offset);
-
-	if (!have_mday || !have_mon)
-	{
-	    int t_mon = 0;
-	    while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon]
-		    <= tm->tm_yday)
-		t_mon++;
-	    if (!have_mon)
-		tm->tm_mon = t_mon - 1;
-	    if (!have_mday)
-		tm->tm_mday =
-		    (tm->tm_yday
-		     - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1);
-	}
-
-	tm->tm_wday = save_wday;
-    }
-
-    return (char *) rp;
-}
-
-
-char * strptime (buf, format, tm)
-     const char *buf;
-     const char *format;
-     struct tm *tm;
-{
-    enum locale_status decided;
-
-#ifdef __UCLIBC_HAS_LOCALE__
-    decided = not;
-#else
-    decided = raw;
-#endif
-    return __strptime_internal (buf, format, tm, &decided, -1);
-}
diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c
new file mode 100644
index 000000000..4371a9cfd
--- /dev/null
+++ b/libc/misc/time/time.c
@@ -0,0 +1,1864 @@
+/*  Copyright (C) 2002     Manuel Novoa III
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
+ *
+ *  Besides uClibc, I'm using this code in my libc for elks, which is
+ *  a 16-bit environment with a fairly limited compiler.  It would make
+ *  things much easier for me if this file isn't modified unnecessarily.
+ *  In particular, please put any new or replacement functions somewhere
+ *  else, and modify the makefile to use your version instead.
+ *  Thanks.  Manuel
+ *
+ *  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION! */
+
+/* June 15, 2002     Initial Notes:
+ *
+ * Note: It is assumed throught that time_t is either long or unsigned long.
+ *       Similarly, clock_t is assumed to be long int.
+ *
+ * Warning: Assumptions are made about the layout of struct tm!  It is
+ *    assumed that the initial fields of struct tm are (in order):
+ *    tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday, tm_yday
+ *
+ * Reached the inital goal of supporting the ANSI/ISO C99 time functions
+ * as well as SUSv3's strptime.  All timezone info is obtained from the
+ * TZ env variable.
+ *
+ * Dif