replace library time handling functions
mktime, tzset, asctime, ctime, gmtime, localtime, strftime with zoneinfo implementations in src/commands/zoneinfo, referenced from src/lib/stdtime/Makefile.in.
This commit is contained in:
parent
6ccd37a982
commit
056ac0a0d3
13 changed files with 28 additions and 627 deletions
|
@ -14,6 +14,11 @@ struct timeval
|
||||||
long /*useconds_t*/ tv_usec;
|
long /*useconds_t*/ tv_usec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct timezone {
|
||||||
|
int tz_minuteswest; /* minutes west of Greenwich */
|
||||||
|
int tz_dsttime; /* type of dst correction */
|
||||||
|
};
|
||||||
|
|
||||||
int gettimeofday(struct timeval *_RESTRICT tp, void *_RESTRICT tzp);
|
int gettimeofday(struct timeval *_RESTRICT tp, void *_RESTRICT tzp);
|
||||||
|
|
||||||
/* Compatibility with other Unix systems */
|
/* Compatibility with other Unix systems */
|
||||||
|
|
|
@ -39,6 +39,8 @@ all-ack: makefiles
|
||||||
cd regex && $(MAKE) $@
|
cd regex && $(MAKE) $@
|
||||||
mkdir -p obj-ack//./stdio
|
mkdir -p obj-ack//./stdio
|
||||||
cd stdio && $(MAKE) $@
|
cd stdio && $(MAKE) $@
|
||||||
|
mkdir -p obj-ack//./stdtime
|
||||||
|
cd stdtime && $(MAKE) $@
|
||||||
mkdir -p obj-ack//./syscall
|
mkdir -p obj-ack//./syscall
|
||||||
cd syscall && $(MAKE) $@
|
cd syscall && $(MAKE) $@
|
||||||
mkdir -p obj-ack//./syslib
|
mkdir -p obj-ack//./syslib
|
||||||
|
@ -79,6 +81,8 @@ all-gnu: makefiles
|
||||||
cd regex && $(MAKE) $@
|
cd regex && $(MAKE) $@
|
||||||
mkdir -p obj-gnu/./stdio
|
mkdir -p obj-gnu/./stdio
|
||||||
cd stdio && $(MAKE) $@
|
cd stdio && $(MAKE) $@
|
||||||
|
mkdir -p obj-gnu/./stdtime
|
||||||
|
cd stdtime && $(MAKE) $@
|
||||||
mkdir -p obj-gnu/./syscall
|
mkdir -p obj-gnu/./syscall
|
||||||
cd syscall && $(MAKE) $@
|
cd syscall && $(MAKE) $@
|
||||||
mkdir -p obj-gnu/./syslib
|
mkdir -p obj-gnu/./syslib
|
||||||
|
@ -108,6 +112,7 @@ clean depend depend-ack depend-gnu:: makefiles
|
||||||
cd posix && $(MAKE) $@
|
cd posix && $(MAKE) $@
|
||||||
cd regex && $(MAKE) $@
|
cd regex && $(MAKE) $@
|
||||||
cd stdio && $(MAKE) $@
|
cd stdio && $(MAKE) $@
|
||||||
|
cd stdtime && $(MAKE) $@
|
||||||
cd syscall && $(MAKE) $@
|
cd syscall && $(MAKE) $@
|
||||||
cd syslib && $(MAKE) $@
|
cd syslib && $(MAKE) $@
|
||||||
cd util && $(MAKE) $@
|
cd util && $(MAKE) $@
|
||||||
|
@ -128,6 +133,7 @@ makefiles: other/Makefile
|
||||||
makefiles: posix/Makefile
|
makefiles: posix/Makefile
|
||||||
makefiles: regex/Makefile
|
makefiles: regex/Makefile
|
||||||
makefiles: stdio/Makefile
|
makefiles: stdio/Makefile
|
||||||
|
makefiles: stdtime/Makefile
|
||||||
makefiles: syscall/Makefile
|
makefiles: syscall/Makefile
|
||||||
makefiles: syslib/Makefile
|
makefiles: syslib/Makefile
|
||||||
makefiles: util/Makefile
|
makefiles: util/Makefile
|
||||||
|
@ -159,6 +165,8 @@ regex/Makefile: regex/Makefile.in
|
||||||
cd regex && sh ../generate.sh ./regex ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
|
cd regex && sh ../generate.sh ./regex ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
|
||||||
stdio/Makefile: stdio/Makefile.in
|
stdio/Makefile: stdio/Makefile.in
|
||||||
cd stdio && sh ../generate.sh ./stdio ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
|
cd stdio && sh ../generate.sh ./stdio ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
|
||||||
|
stdtime/Makefile: stdtime/Makefile.in
|
||||||
|
cd stdtime && sh ../generate.sh ./stdtime ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
|
||||||
syscall/Makefile: syscall/Makefile.in
|
syscall/Makefile: syscall/Makefile.in
|
||||||
cd syscall && sh ../generate.sh ./syscall ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
|
cd syscall && sh ../generate.sh ./syscall ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
|
||||||
syslib/Makefile: syslib/Makefile.in
|
syslib/Makefile: syslib/Makefile.in
|
||||||
|
|
|
@ -17,6 +17,7 @@ SUBDIRS="ansi \
|
||||||
posix \
|
posix \
|
||||||
regex \
|
regex \
|
||||||
stdio \
|
stdio \
|
||||||
|
stdtime \
|
||||||
syscall \
|
syscall \
|
||||||
syslib \
|
syslib \
|
||||||
util \
|
util \
|
||||||
|
|
|
@ -25,7 +25,6 @@ LIBRARIES=libc
|
||||||
libc_FILES=" \
|
libc_FILES=" \
|
||||||
abort.c \
|
abort.c \
|
||||||
abs.c \
|
abs.c \
|
||||||
asctime.c \
|
|
||||||
assert.c \
|
assert.c \
|
||||||
atexit.c \
|
atexit.c \
|
||||||
atof.c \
|
atof.c \
|
||||||
|
@ -35,14 +34,12 @@ libc_FILES=" \
|
||||||
calloc.c \
|
calloc.c \
|
||||||
chartab.c \
|
chartab.c \
|
||||||
clock.c \
|
clock.c \
|
||||||
ctime.c \
|
|
||||||
difftime.c \
|
difftime.c \
|
||||||
div.c \
|
div.c \
|
||||||
errlist.c \
|
errlist.c \
|
||||||
exit.c \
|
exit.c \
|
||||||
ext_comp.c \
|
ext_comp.c \
|
||||||
getenv.c \
|
getenv.c \
|
||||||
gmtime.c \
|
|
||||||
isalnum.c \
|
isalnum.c \
|
||||||
isalpha.c \
|
isalpha.c \
|
||||||
isascii.c \
|
isascii.c \
|
||||||
|
@ -58,13 +55,11 @@ libc_FILES=" \
|
||||||
labs.c \
|
labs.c \
|
||||||
ldiv.c \
|
ldiv.c \
|
||||||
localeconv.c \
|
localeconv.c \
|
||||||
localtime.c \
|
|
||||||
malloc.c \
|
malloc.c \
|
||||||
mblen.c \
|
mblen.c \
|
||||||
mbstowcs.c \
|
mbstowcs.c \
|
||||||
mbtowc.c \
|
mbtowc.c \
|
||||||
misc.c \
|
misc.c \
|
||||||
mktime.c \
|
|
||||||
qsort.c \
|
qsort.c \
|
||||||
raise.c \
|
raise.c \
|
||||||
rand.c \
|
rand.c \
|
||||||
|
@ -74,7 +69,6 @@ libc_FILES=" \
|
||||||
strcoll.c \
|
strcoll.c \
|
||||||
strcspn.c \
|
strcspn.c \
|
||||||
strerror.c \
|
strerror.c \
|
||||||
strftime.c \
|
|
||||||
strpbrk.c \
|
strpbrk.c \
|
||||||
strspn.c \
|
strspn.c \
|
||||||
strstr.c \
|
strstr.c \
|
||||||
|
@ -84,7 +78,6 @@ libc_FILES=" \
|
||||||
system.c \
|
system.c \
|
||||||
tolower.c \
|
tolower.c \
|
||||||
toupper.c \
|
toupper.c \
|
||||||
tzset.c \
|
|
||||||
wcstombs.c \
|
wcstombs.c \
|
||||||
wctomb.c"
|
wctomb.c"
|
||||||
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* asctime - print a date
|
|
||||||
*/
|
|
||||||
/* $Header$ */
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "loc_time.h"
|
|
||||||
|
|
||||||
#define DATE_STR "??? ??? ?? ??:??:?? ????\n"
|
|
||||||
|
|
||||||
static char *
|
|
||||||
two_digits(register char *pb, int i, int nospace)
|
|
||||||
{
|
|
||||||
*pb = (i / 10) % 10 + '0';
|
|
||||||
if (!nospace && *pb == '0') *pb = ' ';
|
|
||||||
pb++;
|
|
||||||
*pb++ = (i % 10) + '0';
|
|
||||||
return ++pb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
four_digits(register char *pb, int i)
|
|
||||||
{
|
|
||||||
i %= 10000;
|
|
||||||
*pb++ = (i / 1000) + '0';
|
|
||||||
i %= 1000;
|
|
||||||
*pb++ = (i / 100) + '0';
|
|
||||||
i %= 100;
|
|
||||||
*pb++ = (i / 10) + '0';
|
|
||||||
*pb++ = (i % 10) + '0';
|
|
||||||
return ++pb;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *asctime(const struct tm *timeptr)
|
|
||||||
{
|
|
||||||
static char buf[26];
|
|
||||||
register char *pb = buf;
|
|
||||||
register const char *ps;
|
|
||||||
register int n;
|
|
||||||
|
|
||||||
strcpy(pb, DATE_STR);
|
|
||||||
ps = _days[timeptr->tm_wday];
|
|
||||||
n = ABB_LEN;
|
|
||||||
while(--n >= 0) *pb++ = *ps++;
|
|
||||||
pb++;
|
|
||||||
ps = _months[timeptr->tm_mon];
|
|
||||||
n = ABB_LEN;
|
|
||||||
while(--n >= 0) *pb++ = *ps++;
|
|
||||||
pb++;
|
|
||||||
pb = two_digits(
|
|
||||||
two_digits(
|
|
||||||
two_digits(two_digits(pb, timeptr->tm_mday, 0)
|
|
||||||
, timeptr->tm_hour, 1)
|
|
||||||
, timeptr->tm_min, 1)
|
|
||||||
, timeptr->tm_sec, 1);
|
|
||||||
|
|
||||||
four_digits(pb, timeptr->tm_year + 1900);
|
|
||||||
return buf;
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
/*
|
|
||||||
* ctime - convers the calendar time to a string
|
|
||||||
*/
|
|
||||||
/* $Header$ */
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
char *
|
|
||||||
ctime(const time_t *timer)
|
|
||||||
{
|
|
||||||
return asctime(localtime(timer));
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* gmtime - convert the calendar time into broken down time
|
|
||||||
*/
|
|
||||||
/* $Header$ */
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include "loc_time.h"
|
|
||||||
|
|
||||||
struct tm *
|
|
||||||
gmtime(register const time_t *timer)
|
|
||||||
{
|
|
||||||
static struct tm br_time;
|
|
||||||
register struct tm *timep = &br_time;
|
|
||||||
time_t time = *timer;
|
|
||||||
register unsigned long dayclock, dayno;
|
|
||||||
int year = EPOCH_YR;
|
|
||||||
|
|
||||||
dayclock = (unsigned long)time % SECS_DAY;
|
|
||||||
dayno = (unsigned long)time / SECS_DAY;
|
|
||||||
|
|
||||||
timep->tm_sec = dayclock % 60;
|
|
||||||
timep->tm_min = (dayclock % 3600) / 60;
|
|
||||||
timep->tm_hour = dayclock / 3600;
|
|
||||||
timep->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */
|
|
||||||
while (dayno >= YEARSIZE(year)) {
|
|
||||||
dayno -= YEARSIZE(year);
|
|
||||||
year++;
|
|
||||||
}
|
|
||||||
timep->tm_year = year - YEAR0;
|
|
||||||
timep->tm_yday = dayno;
|
|
||||||
timep->tm_mon = 0;
|
|
||||||
while (dayno >= _ytab[LEAPYEAR(year)][timep->tm_mon]) {
|
|
||||||
dayno -= _ytab[LEAPYEAR(year)][timep->tm_mon];
|
|
||||||
timep->tm_mon++;
|
|
||||||
}
|
|
||||||
timep->tm_mday = dayno + 1;
|
|
||||||
timep->tm_isdst = 0;
|
|
||||||
|
|
||||||
return timep;
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* localtime - convert a calendar time into broken down time
|
|
||||||
*/
|
|
||||||
/* $Header$ */
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include "loc_time.h"
|
|
||||||
|
|
||||||
/* We must be careful, since an int can't represent all the seconds in a day.
|
|
||||||
* Hence the adjustment of minutes when adding timezone and dst information.
|
|
||||||
* This assumes that both must be expressable in multiples of a minute.
|
|
||||||
* Furthermore, it is assumed that both fit into an integer when expressed as
|
|
||||||
* minutes (this is about 22 days, so this should not cause any problems).
|
|
||||||
*/
|
|
||||||
struct tm *
|
|
||||||
localtime(const time_t *timer)
|
|
||||||
{
|
|
||||||
struct tm *timep;
|
|
||||||
unsigned dst;
|
|
||||||
|
|
||||||
_tzset();
|
|
||||||
timep = gmtime(timer); /* tm->tm_isdst == 0 */
|
|
||||||
timep->tm_min -= _timezone / 60;
|
|
||||||
timep->tm_sec -= _timezone % 60;
|
|
||||||
mktime(timep);
|
|
||||||
|
|
||||||
dst = _dstget(timep);
|
|
||||||
if (dst) {
|
|
||||||
timep->tm_min += dst / 60;
|
|
||||||
timep->tm_sec += dst % 60;
|
|
||||||
mktime(timep);
|
|
||||||
}
|
|
||||||
return timep;
|
|
||||||
}
|
|
154
lib/ansi/misc.c
154
lib/ansi/misc.c
|
@ -49,10 +49,8 @@ static char dststr[TZ_LEN + 1] = "GDT"; /* string for daylight saving */
|
||||||
long _timezone = 0;
|
long _timezone = 0;
|
||||||
long _dst_off = 60 * 60;
|
long _dst_off = 60 * 60;
|
||||||
int _daylight = 0;
|
int _daylight = 0;
|
||||||
char *_tzname[2] = {ntstr, dststr};
|
|
||||||
|
|
||||||
#if defined(__USG) || defined(_POSIX_SOURCE)
|
#if defined(__USG) || defined(_POSIX_SOURCE)
|
||||||
char *tzname[2] = {ntstr, dststr};
|
|
||||||
|
|
||||||
#if defined(__USG)
|
#if defined(__USG)
|
||||||
long timezone = 0;
|
long timezone = 0;
|
||||||
|
@ -219,106 +217,6 @@ parseRule(register char *buf, register const char *p)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following routine parses timezone information in POSIX-format. For
|
|
||||||
* the requirements, see IEEE Std 1003.1-1988 section 8.1.1.
|
|
||||||
* The function returns as soon as it spots an error.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
parseTZ(const char *p)
|
|
||||||
{
|
|
||||||
long tz, dst = 60 * 60, sign = 1;
|
|
||||||
static char lastTZ[2 * RULE_LEN];
|
|
||||||
static char buffer[RULE_LEN];
|
|
||||||
|
|
||||||
if (!p) return;
|
|
||||||
|
|
||||||
if (*p == ':') {
|
|
||||||
/*
|
|
||||||
* According to POSIX, this is implementation defined.
|
|
||||||
* Since it depends on the particular operating system, we
|
|
||||||
* can do nothing.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(lastTZ, p)) return; /* nothing changed */
|
|
||||||
|
|
||||||
*_tzname[0] = '\0';
|
|
||||||
*_tzname[1] = '\0';
|
|
||||||
dststart.ds_type = 'U';
|
|
||||||
dststart.ds_sec = 2 * 60 * 60;
|
|
||||||
dstend.ds_type = 'U';
|
|
||||||
dstend.ds_sec = 2 * 60 * 60;
|
|
||||||
|
|
||||||
if (strlen(p) > 2 * RULE_LEN) return;
|
|
||||||
strcpy(lastTZ, p);
|
|
||||||
|
|
||||||
if (!(p = parseZoneName(buffer, p))) return;
|
|
||||||
|
|
||||||
if (*p == '-') {
|
|
||||||
sign = -1;
|
|
||||||
p++;
|
|
||||||
} else if (*p == '+') p++;
|
|
||||||
|
|
||||||
if (!(p = parseTime(&tz, p, NULL))) return;
|
|
||||||
tz *= sign;
|
|
||||||
_timezone = tz;
|
|
||||||
strncpy(_tzname[0], buffer, TZ_LEN);
|
|
||||||
|
|
||||||
if (!(_daylight = (*p != '\0'))) return;
|
|
||||||
|
|
||||||
buffer[0] = '\0';
|
|
||||||
if (!(p = parseZoneName(buffer, p))) return;
|
|
||||||
strncpy(_tzname[1], buffer, TZ_LEN);
|
|
||||||
|
|
||||||
buffer[0] = '\0';
|
|
||||||
if (*p && (*p != ','))
|
|
||||||
if (!(p = parseTime(&dst, p, NULL))) return;
|
|
||||||
_dst_off = dst; /* dst was initialized to 1 hour */
|
|
||||||
if (*p) {
|
|
||||||
if (*p != ',') return;
|
|
||||||
p++;
|
|
||||||
if (strlen(p) > RULE_LEN) return;
|
|
||||||
if (!(p = parseRule(buffer, p))) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_tzset(void)
|
|
||||||
{
|
|
||||||
#if defined(__BSD4_2)
|
|
||||||
|
|
||||||
struct timeval tv;
|
|
||||||
struct timezone tz;
|
|
||||||
|
|
||||||
_gettimeofday(&tv, &tz);
|
|
||||||
_daylight = tz.tz_dsttime;
|
|
||||||
_timezone = tz.tz_minuteswest * 60L;
|
|
||||||
|
|
||||||
#elif !defined(_POSIX_SOURCE) && !defined(__USG)
|
|
||||||
|
|
||||||
#if !defined(_MINIX) /* MINIX has no ftime() */
|
|
||||||
struct timeb time;
|
|
||||||
|
|
||||||
_ftime(&time);
|
|
||||||
_timezone = time.timezone * 60L;
|
|
||||||
_daylight = time.dstflag;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !_POSIX_SOURCE && !__USG */
|
|
||||||
|
|
||||||
parseTZ(getenv("TZ")); /* should go inside #if */
|
|
||||||
|
|
||||||
#if defined(__USG) || defined(_POSIX_SOURCE)
|
|
||||||
tzname[0] = _tzname[0];
|
|
||||||
tzname[1] = _tzname[1];
|
|
||||||
#if defined(__USG)
|
|
||||||
timezone = _timezone;
|
|
||||||
daylight = _daylight;
|
|
||||||
#endif
|
|
||||||
#endif /* __USG || _POSIX_SOURCE */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
last_sunday(register int day, register struct tm *timep)
|
last_sunday(register int day, register struct tm *timep)
|
||||||
{
|
{
|
||||||
|
@ -356,55 +254,3 @@ date_of(register struct dsttype *dst, struct tm *timep)
|
||||||
return day;
|
return day;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The default dst transitions are those for Western Europe (except Great
|
|
||||||
* Britain).
|
|
||||||
*/
|
|
||||||
unsigned
|
|
||||||
_dstget(register struct tm *timep)
|
|
||||||
{
|
|
||||||
int begindst, enddst;
|
|
||||||
register struct dsttype *dsts = &dststart, *dste = &dstend;
|
|
||||||
int do_dst = 0;
|
|
||||||
|
|
||||||
if (_daylight == -1)
|
|
||||||
_tzset();
|
|
||||||
|
|
||||||
timep->tm_isdst = _daylight;
|
|
||||||
if (!_daylight) return 0;
|
|
||||||
|
|
||||||
if (dsts->ds_type != 'U')
|
|
||||||
begindst = date_of(dsts, timep);
|
|
||||||
else begindst = last_sunday(89, timep); /* last Sun before Apr */
|
|
||||||
if (dste->ds_type != 'U')
|
|
||||||
enddst = date_of(dste, timep);
|
|
||||||
else enddst = last_sunday(272, timep); /* last Sun in Sep */
|
|
||||||
|
|
||||||
/* assume begindst != enddst (otherwise it would be no use) */
|
|
||||||
if (begindst < enddst) { /* northern hemisphere */
|
|
||||||
if (timep->tm_yday > begindst && timep->tm_yday < enddst)
|
|
||||||
do_dst = 1;
|
|
||||||
} else { /* southern hemisphere */
|
|
||||||
if (timep->tm_yday > begindst || timep->tm_yday < enddst)
|
|
||||||
do_dst = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!do_dst
|
|
||||||
&& (timep->tm_yday == begindst || timep->tm_yday == enddst)) {
|
|
||||||
long dsttranssec; /* transition when day is this old */
|
|
||||||
long cursec;
|
|
||||||
|
|
||||||
if (timep->tm_yday == begindst)
|
|
||||||
dsttranssec = dsts->ds_sec;
|
|
||||||
else dsttranssec = dste->ds_sec;
|
|
||||||
cursec = ((timep->tm_hour * 60) + timep->tm_min) * 60L
|
|
||||||
+ timep->tm_sec;
|
|
||||||
|
|
||||||
if ((timep->tm_yday == begindst && cursec >= dsttranssec)
|
|
||||||
|| (timep->tm_yday == enddst && cursec < dsttranssec))
|
|
||||||
do_dst = 1;
|
|
||||||
}
|
|
||||||
if (do_dst) return _dst_off;
|
|
||||||
timep->tm_isdst = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,132 +0,0 @@
|
||||||
/*
|
|
||||||
* mktime - convert local time into calendar time
|
|
||||||
*/
|
|
||||||
/* $Header$ */
|
|
||||||
|
|
||||||
/* Michael A. Temari <temari@ix.netcom.com> 03/01/96 */
|
|
||||||
/* - fixed bug is structure fixup code */
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include "loc_time.h"
|
|
||||||
|
|
||||||
/* The code assumes that unsigned long can be converted to time_t.
|
|
||||||
* A time_t should not be wider than unsigned long, since this would mean
|
|
||||||
* that the check for overflow at the end could fail.
|
|
||||||
*/
|
|
||||||
time_t
|
|
||||||
mktime(register struct tm *timep)
|
|
||||||
{
|
|
||||||
register long day, year;
|
|
||||||
register int tm_year;
|
|
||||||
int yday, month;
|
|
||||||
register unsigned long seconds;
|
|
||||||
int overflow;
|
|
||||||
unsigned dst;
|
|
||||||
|
|
||||||
timep->tm_min += timep->tm_sec / 60;
|
|
||||||
timep->tm_sec %= 60;
|
|
||||||
if (timep->tm_sec < 0) {
|
|
||||||
timep->tm_sec += 60;
|
|
||||||
timep->tm_min--;
|
|
||||||
}
|
|
||||||
timep->tm_hour += timep->tm_min / 60;
|
|
||||||
timep->tm_min = timep->tm_min % 60;
|
|
||||||
if (timep->tm_min < 0) {
|
|
||||||
timep->tm_min += 60;
|
|
||||||
timep->tm_hour--;
|
|
||||||
}
|
|
||||||
day = timep->tm_hour / 24;
|
|
||||||
timep->tm_hour= timep->tm_hour % 24;
|
|
||||||
if (timep->tm_hour < 0) {
|
|
||||||
timep->tm_hour += 24;
|
|
||||||
day--;
|
|
||||||
}
|
|
||||||
timep->tm_year += timep->tm_mon / 12;
|
|
||||||
timep->tm_mon %= 12;
|
|
||||||
if (timep->tm_mon < 0) {
|
|
||||||
timep->tm_mon += 12;
|
|
||||||
timep->tm_year--;
|
|
||||||
}
|
|
||||||
day += (timep->tm_mday - 1);
|
|
||||||
while (day < 0) {
|
|
||||||
if(--timep->tm_mon < 0) {
|
|
||||||
timep->tm_year--;
|
|
||||||
timep->tm_mon = 11;
|
|
||||||
}
|
|
||||||
day += _ytab[LEAPYEAR(YEAR0 + timep->tm_year)][timep->tm_mon];
|
|
||||||
}
|
|
||||||
while (day >= _ytab[LEAPYEAR(YEAR0 + timep->tm_year)][timep->tm_mon]) {
|
|
||||||
day -= _ytab[LEAPYEAR(YEAR0 + timep->tm_year)][timep->tm_mon];
|
|
||||||
if (++(timep->tm_mon) == 12) {
|
|
||||||
timep->tm_mon = 0;
|
|
||||||
timep->tm_year++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timep->tm_mday = day + 1;
|
|
||||||
_tzset(); /* set timezone and dst info */
|
|
||||||
year = EPOCH_YR;
|
|
||||||
if (timep->tm_year < year - YEAR0) return (time_t)-1;
|
|
||||||
seconds = 0;
|
|
||||||
day = 0; /* means days since day 0 now */
|
|
||||||
overflow = 0;
|
|
||||||
|
|
||||||
/* Assume that when day becomes negative, there will certainly
|
|
||||||
* be overflow on seconds.
|
|
||||||
* The check for overflow needs not to be done for leapyears
|
|
||||||
* divisible by 400.
|
|
||||||
* The code only works when year (1970) is not a leapyear.
|
|
||||||
*/
|
|
||||||
#if EPOCH_YR != 1970
|
|
||||||
#error EPOCH_YR != 1970
|
|
||||||
#endif
|
|
||||||
tm_year = timep->tm_year + YEAR0;
|
|
||||||
|
|
||||||
if (LONG_MAX / 365 < tm_year - year) overflow++;
|
|
||||||
day = (tm_year - year) * 365;
|
|
||||||
if (LONG_MAX - day < (tm_year - year) / 4 + 1) overflow++;
|
|
||||||
day += (tm_year - year) / 4
|
|
||||||
+ ((tm_year % 4) && tm_year % 4 < year % 4);
|
|
||||||
day -= (tm_year - year) / 100
|
|
||||||
+ ((tm_year % 100) && tm_year % 100 < year % 100);
|
|
||||||
day += (tm_year - year) / 400
|
|
||||||
+ ((tm_year % 400) && tm_year % 400 < year % 400);
|
|
||||||
|
|
||||||
yday = month = 0;
|
|
||||||
while (month < timep->tm_mon) {
|
|
||||||
yday += _ytab[LEAPYEAR(tm_year)][month];
|
|
||||||
month++;
|
|
||||||
}
|
|
||||||
yday += (timep->tm_mday - 1);
|
|
||||||
if (day + yday < 0) overflow++;
|
|
||||||
day += yday;
|
|
||||||
|
|
||||||
timep->tm_yday = yday;
|
|
||||||
timep->tm_wday = (day + 4) % 7; /* day 0 was thursday (4) */
|
|
||||||
|
|
||||||
seconds = ((timep->tm_hour * 60L) + timep->tm_min) * 60L + timep->tm_sec;
|
|
||||||
|
|
||||||
if ((TIME_MAX - seconds) / SECS_DAY < day) overflow++;
|
|
||||||
seconds += day * SECS_DAY;
|
|
||||||
|
|
||||||
/* Now adjust according to timezone and daylight saving time */
|
|
||||||
|
|
||||||
if (((_timezone > 0) && (TIME_MAX - _timezone < seconds))
|
|
||||||
|| ((_timezone < 0) && (seconds < -_timezone)))
|
|
||||||
overflow++;
|
|
||||||
seconds += _timezone;
|
|
||||||
|
|
||||||
if (timep->tm_isdst < 0)
|
|
||||||
dst = _dstget(timep);
|
|
||||||
else if (timep->tm_isdst)
|
|
||||||
dst = _dst_off;
|
|
||||||
else dst = 0;
|
|
||||||
|
|
||||||
if (dst > seconds) overflow++; /* dst is always non-negative */
|
|
||||||
seconds -= dst;
|
|
||||||
|
|
||||||
if (overflow) return (time_t)-1;
|
|
||||||
|
|
||||||
if ((time_t)seconds != seconds) return (time_t)-1;
|
|
||||||
return (time_t)seconds;
|
|
||||||
}
|
|
|
@ -1,172 +0,0 @@
|
||||||
/*
|
|
||||||
* strftime - convert a structure to a string, controlled by an argument
|
|
||||||
*/
|
|
||||||
/* $Header$ */
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include "loc_time.h"
|
|
||||||
|
|
||||||
/* The width can be -1 in both s_prnt() as in u_prnt(). This
|
|
||||||
* indicates that as many characters as needed should be printed.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
s_prnt(char *s, size_t maxsize, const char *str, int width)
|
|
||||||
{
|
|
||||||
while (width > 0 || (width < 0 && *str)) {
|
|
||||||
if (!maxsize) break;
|
|
||||||
*s++ = *str++;
|
|
||||||
maxsize--;
|
|
||||||
width--;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
u_prnt(char *s, size_t maxsize, unsigned val, int width)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
|
|
||||||
c = val % 10;
|
|
||||||
val = val / 10;
|
|
||||||
if (--width > 0 || (width < 0 && val != 0))
|
|
||||||
s = u_prnt(s, (maxsize ? maxsize - 1 : 0), val, width);
|
|
||||||
if (maxsize) *s++ = c + '0';
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
strftime(char *s, size_t maxsize,
|
|
||||||
const char *format, const struct tm *timeptr)
|
|
||||||
{
|
|
||||||
size_t n;
|
|
||||||
char *firsts, *olds;
|
|
||||||
|
|
||||||
if (!format) return 0;
|
|
||||||
|
|
||||||
_tzset(); /* for %Z conversion */
|
|
||||||
firsts = s;
|
|
||||||
while (maxsize && *format) {
|
|
||||||
while (maxsize && *format && *format != '%') {
|
|
||||||
*s++ = *format++;
|
|
||||||
maxsize--;
|
|
||||||
}
|
|
||||||
if (!maxsize || !*format) break;
|
|
||||||
format++;
|
|
||||||
|
|
||||||
olds = s;
|
|
||||||
switch (*format++) {
|
|
||||||
case 'a':
|
|
||||||
s = s_prnt(s, maxsize,
|
|
||||||
_days[timeptr->tm_wday], ABB_LEN);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'A':
|
|
||||||
s = s_prnt(s, maxsize, _days[timeptr->tm_wday], -1);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
s = s_prnt(s, maxsize,
|
|
||||||
_months[timeptr->tm_mon], ABB_LEN);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'B':
|
|
||||||
s = s_prnt(s, maxsize, _months[timeptr->tm_mon], -1);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
n = strftime(s, maxsize,
|
|
||||||
"%a %b %d %H:%M:%S %Y", timeptr);
|
|
||||||
if (n) maxsize -= n;
|
|
||||||
else maxsize = 0;
|
|
||||||
s += n;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
s = u_prnt(s, maxsize, timeptr->tm_mday, 2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'H':
|
|
||||||
s = u_prnt(s, maxsize, timeptr->tm_hour, 2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'I':
|
|
||||||
s = u_prnt(s, maxsize,
|
|
||||||
(timeptr->tm_hour + 11) % 12 + 1, 2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'j':
|
|
||||||
s = u_prnt(s, maxsize, timeptr->tm_yday + 1, 3);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
s = u_prnt(s, maxsize, timeptr->tm_mon + 1, 2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'M':
|
|
||||||
s = u_prnt(s, maxsize, timeptr->tm_min, 2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
s = s_prnt(s, maxsize,
|
|
||||||
(timeptr->tm_hour < 12) ? "AM" : "PM", 2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
s = u_prnt(s, maxsize, timeptr->tm_sec, 2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
s = u_prnt(s, maxsize, /* ??? */
|
|
||||||
(timeptr->tm_yday + 7 - timeptr->tm_wday) / 7, 2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
s = u_prnt(s, maxsize, timeptr->tm_wday, 1);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'W':
|
|
||||||
s = u_prnt(s, maxsize, /* ??? */
|
|
||||||
(timeptr->tm_yday+7-(timeptr->tm_wday+6)%7)/7,2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
n = strftime(s, maxsize, "%a %b %d %Y", timeptr);
|
|
||||||
if (n) maxsize -= n;
|
|
||||||
else maxsize = 0;
|
|
||||||
s += n;
|
|
||||||
break;
|
|
||||||
case 'X':
|
|
||||||
n = strftime(s, maxsize, "%H:%M:%S", timeptr);
|
|
||||||
if (n) maxsize -= n;
|
|
||||||
else maxsize = 0;
|
|
||||||
s += n;
|
|
||||||
break;
|
|
||||||
case 'y':
|
|
||||||
s = u_prnt(s, maxsize, timeptr->tm_year % 100, 2);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'Y':
|
|
||||||
s = u_prnt(s, maxsize, timeptr->tm_year + YEAR0, -1);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case 'Z':
|
|
||||||
s = s_prnt(s, maxsize,
|
|
||||||
_tzname[(timeptr->tm_isdst > 0)], -1);
|
|
||||||
maxsize -= s - olds;
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
*s++ = '%';
|
|
||||||
maxsize--;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* A conversion error. Leave the loop. */
|
|
||||||
while (*format) format++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (maxsize) {
|
|
||||||
*s = '\0';
|
|
||||||
return s - firsts;
|
|
||||||
}
|
|
||||||
return 0; /* The buffer is full */
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
/*
|
|
||||||
* tzset - set timezone information
|
|
||||||
*/
|
|
||||||
/* $Header$ */
|
|
||||||
|
|
||||||
/* This function is present for System V && POSIX */
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include "loc_time.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
tzset(void)
|
|
||||||
{
|
|
||||||
_tzset(); /* does the job */
|
|
||||||
}
|
|
14
lib/stdtime/Makefile.in
Normal file
14
lib/stdtime/Makefile.in
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Makefile for lib/stdtime.
|
||||||
|
|
||||||
|
Z=../../commands/zoneinfo
|
||||||
|
|
||||||
|
CFLAGS="-O -D_MINIX -D_POSIX_SOURCE -D__USG -I$Z"
|
||||||
|
|
||||||
|
LIBRARIES=libc
|
||||||
|
libc_FILES="
|
||||||
|
$Z/asctime.c
|
||||||
|
$Z/localtime.c
|
||||||
|
$Z/strftime.c
|
||||||
|
"
|
||||||
|
|
||||||
|
TYPE=both
|
Loading…
Reference in a new issue