initial checkin

This commit is contained in:
gdr 1997-09-21 06:22:10 +00:00
parent ffae6366ab
commit 997c35962d
7 changed files with 2958 additions and 0 deletions

25
lib/libc/stdtime/Makefile Normal file
View File

@ -0,0 +1,25 @@
#
# Makefile for libc/stdtime.
#
# $Id: Makefile,v 1.1 1997/09/21 06:22:10 gdr Exp $
#
.INCLUDE: ../../../paths.mk
.INCLUDE: ../../const.mk
OBJS = asctime.o difftime.o localtime.o strftime.o
CFLAGS += -v
default:
@echo do not use this directory yet
build: ../libc
obj: $(OBJS)
.INCLUDE: ../rules.mk
asctime.o:: private.h
difftime.o:: private.h
localtime.o:: private.h
strftime.o:: private.h

View File

@ -0,0 +1,71 @@
/*
* $Id: asctime.c,v 1.1 1997/09/21 06:22:10 gdr Exp $
*
* This file is formatted for tab stops every 8 columns.
*/
#ifdef __ORCAC__
segment "libc_stdtm";
#define NOID
#endif
#ifndef lint
#ifndef NOID
static char elsieid[] = "@(#)asctime.c 7.5";
#endif /* !defined NOID */
#endif /* !defined lint */
/*LINTLIBRARY*/
#include "private.h"
#include "tzfile.h"
/*
** A la X3J11, with core dump avoidance.
*/
char *
#ifdef USE_PROTOS
asctime(register const struct tm *timeptr)
#else
asctime(timeptr)
register const struct tm *timeptr;
#endif
{
static const char wday_name[][3] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char mon_name[][3] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
/*
** Big enough for something such as
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
** (two three-character abbreviations, five strings denoting integers,
** three explicit spaces, two explicit colons, a newline,
** and a trailing ASCII nul).
*/
static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) +
3 + 2 + 1 + 1];
register const char * wn;
register const char * mn;
if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
wn = "???";
else wn = wday_name[timeptr->tm_wday];
if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
mn = "???";
else mn = mon_name[timeptr->tm_mon];
/*
** The X3J11-suggested format is
** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n"
** Since the .2 in 02.2d is ignored, we drop it.
*/
(void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
wn, mn,
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
TM_YEAR_BASE + timeptr->tm_year);
return result;
}

View File

@ -0,0 +1,93 @@
#line 1 ":src:gno:lib:libc:stdtime:difftime.c"
/*
* $Id: difftime.c,v 1.1 1997/09/21 06:22:10 gdr Exp $
*
* This file is formatted for tab stops every 8 columns.
*/
#ifdef __ORCAC__
segment "libc_stdtm";
#define NOID
#define CONST /* ORCA/C v2.1.1b2 chokes on the const as used here */
#else
#define CONST const
#endif
#ifndef lint
#ifndef NOID
static char elsieid[] = "@(#)difftime.c 7.4";
#endif /* !defined NOID */
#endif /* !defined lint */
/*LINTLIBRARY*/
#include "private.h"
/*
** Algorithm courtesy Paul Eggert (eggert@twinsun.com).
*/
#ifdef HAVE_LONG_DOUBLE
#define long_double long double
#endif /* defined HAVE_LONG_DOUBLE */
#ifndef HAVE_LONG_DOUBLE
#define long_double double
#endif /* !defined HAVE_LONG_DOUBLE */
double
#ifdef USE_PROTOS
difftime(CONST time_t time1, CONST time_t time0)
#else
difftime(time1, time0)
CONST time_t time1;
CONST time_t time0;
#endif
{
time_t delta;
time_t 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 = 1;
while ((hibit <<= 1) > 0)
continue;
/*
** 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;
}

1753
lib/libc/stdtime/localtime.c Normal file

File diff suppressed because it is too large Load Diff

222
lib/libc/stdtime/private.h Normal file
View File

@ -0,0 +1,222 @@
#ifndef PRIVATE_H
#define PRIVATE_H
/* Stuff moved from Makefile.inc to reduce clutter */
#ifdef __GNO__
#if 0
#define TM_GMTOFF tm_gmtoff
#define TM_ZONE tm_zone
#endif
#define STD_INSPIRED 1
#define PCTS 1
#define HAVE_LONG_DOUBLE 1
#define TZDIR "/usr/share/zoneinfo"
#else /* ! __GNO__ */
#ifndef TM_GMTOFF
#define TM_GMTOFF tm_gmtoff
#define TM_ZONE tm_zone
#define STD_INSPIRED 1
#define PCTS 1
#define HAVE_LONG_DOUBLE 1
#define TZDIR "/usr/share/zoneinfo"
#endif /* ndef TM_GMTOFF */
#endif /* ! __GNO__ */
/*
** This header is for use ONLY with the time conversion code.
** There is no guarantee that it will remain unchanged,
** or that it will remain at all.
** Do NOT copy it to any system include directory.
** Thank you!
*/
/*
** ID
*/
#ifndef lint
#ifndef NOID
/*static char privatehid[] = "@(#)private.h 7.33";*/
#endif /* !defined NOID */
#endif /* !defined lint */
/*
** Defaults for preprocessor symbols.
** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
*/
#ifndef HAVE_ADJTIME
#define HAVE_ADJTIME 1
#endif /* !defined HAVE_ADJTIME */
#ifndef HAVE_SETTIMEOFDAY
#define HAVE_SETTIMEOFDAY 3
#endif /* !defined HAVE_SETTIMEOFDAY */
#ifndef HAVE_UNISTD_H
#define HAVE_UNISTD_H 1
#endif /* !defined HAVE_UNISTD_H */
/*
** Nested includes
*/
#include "sys/types.h" /* for time_t */
#include "stdio.h"
#include "ctype.h"
#include "errno.h"
#include "string.h"
#include "limits.h" /* for CHAR_BIT */
#include "time.h"
#include "stdlib.h"
#if HAVE_UNISTD_H - 0
#include "unistd.h" /* for F_OK and R_OK */
#endif /* HAVE_UNISTD_H - 0 */
#if !(HAVE_UNISTD_H - 0)
#ifndef F_OK
#define F_OK 0
#endif /* !defined F_OK */
#ifndef R_OK
#define R_OK 4
#endif /* !defined R_OK */
#endif /* !(HAVE_UNISTD_H - 0) */
/*
** Workarounds for compilers/systems.
*/
/*
** SunOS 4.1.1 cc lacks const.
*/
#ifndef const
#ifndef __STDC__
#define const
#endif /* !defined __STDC__ */
#endif /* !defined const */
/*
** SunOS 4.1.1 cc lacks prototypes.
*/
#ifndef P
#ifdef __STDC__
#define P(x) x
#endif /* defined __STDC__ */
#ifndef __STDC__
#define P(x) ()
#endif /* !defined __STDC__ */
#endif /* !defined P */
#ifndef USE_PROTOS
# ifdef __STDC__
# define USE_PROTOS
# endif
#endif
/*
** SunOS 4.1.1 headers lack EXIT_SUCCESS.
*/
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif /* !defined EXIT_SUCCESS */
/*
** SunOS 4.1.1 headers lack EXIT_FAILURE.
*/
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif /* !defined EXIT_FAILURE */
/*
** SunOS 4.1.1 headers lack FILENAME_MAX.
*/
#ifndef FILENAME_MAX
#ifndef MAXPATHLEN
#ifdef unix
#include "sys/param.h"
#endif /* defined unix */
#endif /* !defined MAXPATHLEN */
#ifdef MAXPATHLEN
#define FILENAME_MAX MAXPATHLEN
#endif /* defined MAXPATHLEN */
#ifndef MAXPATHLEN
#define FILENAME_MAX 1024 /* Pure guesswork */
#endif /* !defined MAXPATHLEN */
#endif /* !defined FILENAME_MAX */
/*
** SunOS 4.1.1 libraries lack remove.
*/
#ifndef remove
extern int unlink P((const char * filename));
#define remove unlink
#endif /* !defined remove */
/*
** Finally, some convenience items.
*/
#ifndef TRUE
#define TRUE 1
#endif /* !defined TRUE */
#ifndef FALSE
#define FALSE 0
#endif /* !defined FALSE */
#ifndef INT_STRLEN_MAXIMUM
/*
** 302 / 1000 is log10(2.0) rounded up.
** Subtract one for the sign bit;
** add one for integer division truncation;
** add one more for a minus sign.
*/
#define INT_STRLEN_MAXIMUM(type) \
((sizeof(type) * CHAR_BIT - 1) * 302 / 1000 + 2)
#endif /* !defined INT_STRLEN_MAXIMUM */
/*
** INITIALIZE(x)
*/
#ifndef GNUC_or_lint
#ifdef lint
#define GNUC_or_lint
#endif /* defined lint */
#ifndef lint
#ifdef __GNUC__
#define GNUC_or_lint
#endif /* defined __GNUC__ */
#endif /* !defined lint */
#endif /* !defined GNUC_or_lint */
#ifndef INITIALIZE
#ifdef GNUC_or_lint
#define INITIALIZE(x) ((x) = 0)
#endif /* defined GNUC_or_lint */
#ifndef GNUC_or_lint
#define INITIALIZE(x)
#endif /* !defined GNUC_or_lint */
#endif /* !defined INITIALIZE */
/*
** UNIX was a registered trademark of UNIX System Laboratories in 1993.
*/
#endif /* !defined PRIVATE_H */

612
lib/libc/stdtime/strftime.c Normal file
View File

@ -0,0 +1,612 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: strftime.c,v 1.1 1997/09/21 06:22:10 gdr Exp $
*
* This file is formatted for tab stops every 8 columns.
*/
#ifdef __ORCAC__
segment "libc_stdtm";
#define NOID
#endif
#ifdef LIBC_RCS
static const char rcsid[] =
"$Id: strftime.c,v 1.1 1997/09/21 06:22:10 gdr Exp $";
#endif
#ifndef lint
#ifndef NOID
static const char elsieid[] = "@(#)strftime.c 7.38";
/*
** Based on the UCB version with the ID appearing below.
** This is ANSIish only when "multibyte character == plain character".
*/
#endif /* !defined NOID */
#endif /* !defined lint */
#include "private.h"
#ifndef LIBC_SCCS
#ifndef lint
static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89";
#endif /* !defined lint */
#endif /* !defined LIBC_SCCS */
#include "tzfile.h"
#include <fcntl.h>
#include <locale.h>
#include <rune.h> /* for _PATH_LOCALE */
#include <sys/stat.h>
#define LOCALE_HOME _PATH_LOCALE
struct lc_time_T {
const char * mon[12];
const char * month[12];
const char * wday[7];
const char * weekday[7];
const char * X_fmt;
const char * x_fmt;
const char * c_fmt;
const char * am;
const char * pm;
const char * date_fmt;
};
static struct lc_time_T localebuf;
static struct lc_time_T * _loc P((void));
static int using_locale;
#define Locale (using_locale ? &localebuf : &C_time_locale)
static const struct lc_time_T C_time_locale = {
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
}, {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
}, {
"Sun", "Mon", "Tue", "Wed",
"Thu", "Fri", "Sat"
}, {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
},
/* X_fmt */
"%H:%M:%S",
/*
** x_fmt
** Since the C language standard calls for
** "date, using locale's date format," anything goes.
** Using just numbers (as here) makes Quakers happier;
** it's also compatible with SVR4.
*/
"%m/%d/%y",
/*
** c_fmt (ctime-compatible)
** Note that
** "%a %b %d %H:%M:%S %Y"
** is used by Solaris 2.3.
*/
"%a %b %e %X %Y",
/* am */
"AM",
/* pm */
"PM",
/* date_fmt */
"%a %b %e %X %Z %Y"
};
static char * _add P((const char *, char *, const char *));
static char * _conv P((int, const char *, char *, const char *));
static char * _fmt P((const char *, const struct tm *, char *, const char *));
static char * _secs P((const struct tm *, char *, const char *));
size_t strftime P((char *, size_t, const char *, const struct tm *));
extern char * tzname[];
size_t
#ifdef USE_PROTOS
strftime(char *const s, const size_t maxsize, const char *const format,
const struct tm *const t)
#else
strftime(s, maxsize, format, t)
char *const s;
const size_t maxsize;
const char *const format;
const struct tm *const t;
#endif
{
char *p;
tzset();
p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize);
if (p == s + maxsize)
return 0;
*p = '\0';
return p - s;
}
static char *
#ifdef USE_PROTOS
_fmt(const char *format, const struct tm *const t, char *pt,
const char *const ptlim)
#else
_fmt(format, t, pt, ptlim)
const char *format;
const struct tm *const t;
char *pt;
const char *const ptlim;
#endif
{
for ( ; *format; ++format) {
if (*format == '%') {
label:
switch (*++format) {
case '\0':
--format;
break;
case 'A':
pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ?
"?" : Locale->weekday[t->tm_wday],
pt, ptlim);
continue;
case 'a':
pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ?
"?" : Locale->wday[t->tm_wday],
pt, ptlim);
continue;
case 'B':
pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ?
"?" : Locale->month[t->tm_mon],
pt, ptlim);
continue;
case 'b':
case 'h':
pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ?
"?" : Locale->mon[t->tm_mon],
pt, ptlim);
continue;
case 'C':
/*
** %C used to do a...
** _fmt("%a %b %e %X %Y", t);
** ...whereas now POSIX 1003.2 calls for
** something completely different.
** (ado, 5/24/93)
*/
pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
"%02d", pt, ptlim);
continue;
case 'c':
pt = _fmt(Locale->c_fmt, t, pt, ptlim);
continue;
case 'D':
pt = _fmt("%m/%d/%y", t, pt, ptlim);
continue;
case 'd':
pt = _conv(t->tm_mday, "%02d", pt, ptlim);
continue;
case 'E':
case 'O':
/*
** POSIX locale extensions, a la
** Arnold Robbins' strftime version 3.0.
** The sequences
** %Ec %EC %Ex %Ey %EY
** %Od %oe %OH %OI %Om %OM
** %OS %Ou %OU %OV %Ow %OW %Oy
** are supposed to provide alternate
** representations.
** (ado, 5/24/93)
*/
goto label;
case 'e':
pt = _conv(t->tm_mday, "%2d", pt, ptlim);
continue;
case 'H':
pt = _conv(t->tm_hour, "%02d", pt, ptlim);
continue;
case 'I':
pt = _conv((t->tm_hour % 12) ?
(t->tm_hour % 12) : 12,
"%02d", pt, ptlim);
continue;
case 'j':
pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);
continue;
case 'k':
/*
** This used to be...
** _conv(t->tm_hour % 12 ?
** t->tm_hour % 12 : 12, 2, ' ');
** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbins'
** strftime version 3.0. That is, "%k" and
** "%l" have been swapped.
** (ado, 5/24/93)
*/
pt = _conv(t->tm_hour, "%2d", pt, ptlim);
continue;
#ifdef KITCHEN_SINK
case 'K':
/*
** After all this time, still unclaimed!
*/
pt = _add("kitchen sink", pt, ptlim);
continue;
#endif /* defined KITCHEN_SINK */
case 'l':
/*
** This used to be...
** _conv(t->tm_hour, 2, ' ');
** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbin's
** strftime version 3.0. That is, "%k" and
** "%l" have been swapped.
** (ado, 5/24/93)
*/
pt = _conv((t->tm_hour % 12) ?
(t->tm_hour % 12) : 12,
"%2d", pt, ptlim);
continue;
case 'M':
pt = _conv(t->tm_min, "%02d", pt, ptlim);
continue;
case 'm':
pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);
continue;
case 'n':
pt = _add("\n", pt, ptlim);
continue;
case 'p':
pt = _add((t->tm_hour >= 12) ?
Locale->pm :
Locale->am,
pt, ptlim);
continue;
case 'R':
pt = _fmt("%H:%M", t, pt, ptlim);
continue;
case 'r':
pt = _fmt("%I:%M:%S %p", t, pt, ptlim);
continue;
case 'S':
pt = _conv(t->tm_sec, "%02d", pt, ptlim);
continue;
case 's':
pt = _secs(t, pt, ptlim);
continue;
case 'T':
pt = _fmt("%H:%M:%S", t, pt, ptlim);
continue;
case 't':
pt = _add("\t", pt, ptlim);
continue;
case 'U':
pt = _conv((t->tm_yday + 7 - t->tm_wday) / 7,
"%02d", pt, ptlim);
continue;
case 'u':
/*
** From Arnold Robbins' strftime version 3.0:
** "ISO 8601: Weekday as a decimal number
** [1 (Monday) - 7]"
** (ado, 5/24/93)
*/
pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday,
"%d", pt, ptlim);
continue;
case 'V':
/*
** From Arnold Robbins' strftime version 3.0:
** "the week number of the year (the first
** Monday as the first day of week 1) as a
** decimal number (01-53). The method for
** determining the week number is as specified
** by ISO 8601 (to wit: if the week containing
** January 1 has four or more days in the new
** year, then it is week 1, otherwise it is
** week 53 of the previous year and the next
** week is week 1)."
** (ado, 5/24/93)
*/
/*
** XXX--If January 1 falls on a Friday,
** January 1-3 are part of week 53 of the
** previous year. By analogy, if January
** 1 falls on a Thursday, are December 29-31
** of the PREVIOUS year part of week 1???
** (ado 5/24/93)
*/
/*
** You are understood not to expect this.
*/
{
int i;
i = (t->tm_yday + 10 - (t->tm_wday ?
(t->tm_wday - 1) : 6)) / 7;
if (i == 0) {
/*
** What day of the week does
** January 1 fall on?
*/
i = t->tm_wday -
(t->tm_yday - 1);
/*
** Fri Jan 1: 53
** Sun Jan 1: 52
** Sat Jan 1: 53 if previous
** year a leap
** year, else 52
*/
if (i == TM_FRIDAY)
i = 53;
else if (i == TM_SUNDAY)
i = 52;
else i = isleap(t->tm_year +
TM_YEAR_BASE) ?
53 : 52;
#ifdef XPG4_1994_04_09
/*
** As of 4/9/94, though,
** XPG4 calls for 53
** unconditionally.
*/
i = 53;
#endif /* defined XPG4_1994_04_09 */
}
pt = _conv(i, "%02d", pt, ptlim);
}
continue;
case 'v':
/*
** From Arnold Robbins' strftime version 3.0:
** "date as dd-bbb-YYYY"
** (ado, 5/24/93)
*/
pt = _fmt("%e-%b-%Y", t, pt, ptlim);
continue;
case 'W':
pt = _conv((t->tm_yday + 7 -
(t->tm_wday ?
(t->tm_wday - 1) : 6)) / 7,
"%02d", pt, ptlim);
continue;
case 'w':
pt = _conv(t->tm_wday, "%d", pt, ptlim);
continue;
case 'X':
pt = _fmt(Locale->X_fmt, t, pt, ptlim);
continue;
case 'x':
pt = _fmt(Locale->x_fmt, t, pt, ptlim);
continue;
case 'y':
pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
"%02d", pt, ptlim);
continue;
case 'Y':
pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d",
pt, ptlim);
continue;
case 'Z':
if (t->tm_zone != NULL)
pt = _add(t->tm_zone, pt, ptlim);
else
if (t->tm_isdst == 0 || t->tm_isdst == 1) {
pt = _add(tzname[t->tm_isdst],
pt, ptlim);
} else pt = _add("?", pt, ptlim);
continue;
case '+':
pt = _fmt(Locale->date_fmt, t, pt, ptlim);
continue;
case '%':
/*
* X311J/88-090 (4.12.3.5): if conversion char is
* undefined, behavior is undefined. Print out the
* character itself as printf(3) also does.
*/
default:
break;
}
}
if (pt == ptlim)
break;
*pt++ = *format;
}
return pt;
}
static char *
#ifdef USE_PROTOS
_conv(const int n, const char *const format, char *const pt,
const char *const ptlim)
#else
_conv(n, format, pt, ptlim)
const int n;
const char *const format;
char *const pt;
const char *const ptlim;
#endif
{
char buf[INT_STRLEN_MAXIMUM(int) + 1];
(void) sprintf(buf, format, n);
return _add(buf, pt, ptlim);
}
static char *
#ifdef USE_PROTOS
_secs(const struct tm *t, char *pt, const char *ptlim)
#else
_secs(t, pt, ptlim)
const struct tm *t;
char *pt;
const char *ptlim;
#endif
{
char buf[INT_STRLEN_MAXIMUM(int) + 1];
register time_t s;
struct tm tmp;
/* Make a copy, mktime(3) modifies the tm struct. */
tmp = *t;
s = mktime(&tmp);
(void) sprintf(buf, "%ld", s);
return _add(buf, pt, ptlim);
}
static char *
#ifdef USE_PROTOS
_add(const char *str, char *pt, const char *const ptlim)
#else
_add(str, pt, ptlim)
const char *str;
char *pt;
const char *const ptlim;
#endif
{
while (pt < ptlim && (*pt = *str++) != '\0')
++pt;
return pt;
}
extern char *_PathLocale;
int
#ifdef USE_PROTOS
__time_load_locale(const char *name)
#else
__time_load_locale(name)
const char *name;
#endif
{
static const char lc_time[] = "LC_TIME";
static char * locale_buf;
static char locale_buf_C[] = "C";
int fd;
char * lbuf;
char * p;
const char ** ap;
const char * plim;
#ifdef __ORCAC__
static
#endif
char filename[FILENAME_MAX];
struct stat st;
size_t namesize;
size_t bufsize;
using_locale = 0;
if (!strcmp(name, "C") || !strcmp(name, "POSIX"))
return 0;
if (name == NULL || *name == '\0') {
goto no_locale;
}
/*
** If the locale name is the same as our cache, use the cache.
*/
lbuf = locale_buf;
if (lbuf != NULL && strcmp(name, lbuf) == 0) {
p = lbuf;
for (ap = (const char **) &localebuf;
ap < (const char **) (&localebuf + 1);
++ap)
*ap = p += strlen(p) + 1;
using_locale = 1;
return 0;
}
/*
** Slurp the locale file into the cache.
*/
namesize = strlen(name) + 1;
snprintf(filename, sizeof filename,
"%s/%s/%s",
_PathLocale, name, lc_time);
fd = open(filename, O_RDONLY);
if (fd < 0) {
goto no_locale;
}
if (fstat(fd, &st) != 0)
goto bad_locale;
if (st.st_size <= 0)
goto bad_locale;
bufsize = namesize + st.st_size;
locale_buf = NULL;
lbuf = (lbuf == NULL || lbuf == locale_buf_C) ?
malloc(bufsize) : realloc(lbuf, bufsize);
if (lbuf == NULL)
goto bad_locale;
(void) strcpy(lbuf, name);
p = lbuf + namesize;
plim = p + st.st_size;
if (read(fd, p, (size_t) st.st_size) != st.st_size)
goto bad_lbuf;
if (close(fd) != 0)
goto bad_lbuf;
/*
** Parse the locale file into localebuf.
*/
if (plim[-1] != '\n')
goto bad_lbuf;
for (ap = (const char **) &localebuf;
ap < (const char **) (&localebuf + 1);
++ap) {
if (p == plim)
goto bad_lbuf;
*ap = p;
while (*p != '\n')
++p;
*p++ = '\0';
}
/*
** Record the successful parse in the cache.
*/
locale_buf = lbuf;
using_locale = 1;
return 0;
bad_lbuf:
free(lbuf);
bad_locale:
(void) close(fd);
no_locale:
/*
* XXX - This may not be the correct thing to do in this case.
* setlocale() assumes that we left the old locale alone.
*/
locale_buf = locale_buf_C;
localebuf = C_time_locale;
return -1;
}

182
lib/libc/stdtime/tzfile.h Normal file
View File

@ -0,0 +1,182 @@
#ifndef TZFILE_H
#define TZFILE_H
/*
** This header is for use ONLY with the time conversion code.
** There is no guarantee that it will remain unchanged,
** or that it will remain at all.
** Do NOT copy it to any system include directory.
** Thank you!
*/
/*
** ID
*/
#ifndef lint
#ifndef NOID
/*static char tzfilehid[] = "@(#)tzfile.h 7.6";*/
#endif /* !defined NOID */
#endif /* !defined lint */
/*
** Information about time zone files.
*/
#ifndef TZDIR
#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
#endif /* !defined TZDIR */
#ifndef TZDEFAULT
#define TZDEFAULT "/etc/localtime"
#endif /* !defined TZDEFAULT */
#ifndef TZDEFRULES
#define TZDEFRULES "posixrules"
#endif /* !defined TZDEFRULES */
/*
** Each file begins with. . .
*/
struct tzhead {
char tzh_reserved[20]; /* reserved for future use */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
char tzh_timecnt[4]; /* coded number of transition times */
char tzh_typecnt[4]; /* coded number of local time types */
char tzh_charcnt[4]; /* coded number of abbr. chars */
};
/*
** . . .followed by. . .
**
** tzh_timecnt (char [4])s coded transition times a la time(2)
** tzh_timecnt (unsigned char)s types of local time starting at above
** tzh_typecnt repetitions of
** one (char [4]) coded GMT offset in seconds
** one (unsigned char) used to set tm_isdst
** one (unsigned char) that's an abbreviation list index
** tzh_charcnt (char)s '\0'-terminated zone abbreviations
** tzh_leapcnt repetitions of
** one (char [4]) coded leap second transition times
** one (char [4]) total correction after above
** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
** time is standard time, if FALSE,
** transition time is wall clock time
** if absent, transition times are
** assumed to be wall clock time
** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition
** time is GMT, if FALSE,
** transition time is local time
** if absent, transition times are
** assumed to be local time
*/
/*
** In the current implementation, "tzset()" refuses to deal with files that
** exceed any of the limits below.
*/
#ifndef TZ_MAX_TIMES
/*
** The TZ_MAX_TIMES value below is enough to handle a bit more than a
** year's worth of solar time (corrected daily to the nearest second) or
** 138 years of Pacific Presidential Election time
** (where there are three time zone transitions every fourth year).
*/
#define TZ_MAX_TIMES 370
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
#ifndef NOSOLAR
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
#endif /* !defined NOSOLAR */
#ifdef NOSOLAR
/*
** Must be at least 14 for Europe/Riga as of Jan 12 1995,
** as noted by Earl Chew <earl@hpato.aus.hp.com>.
*/
#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
#endif /* !defined NOSOLAR */
#endif /* !defined TZ_MAX_TYPES */
#ifndef TZ_MAX_CHARS
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
/* (limited by what unsigned chars can hold) */
#endif /* !defined TZ_MAX_CHARS */
#ifndef TZ_MAX_LEAPS
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
#endif /* !defined TZ_MAX_LEAPS */
#define SECSPERMIN 60
#define MINSPERHOUR 60
#define HOURSPERDAY 24
#define DAYSPERWEEK 7
#define DAYSPERNYEAR 365
#define DAYSPERLYEAR 366
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR 12
#define TM_SUNDAY 0
#define TM_MONDAY 1
#define TM_TUESDAY 2
#define TM_WEDNESDAY 3
#define TM_THURSDAY 4
#define TM_FRIDAY 5
#define TM_SATURDAY 6
#define TM_JANUARY 0
#define TM_FEBRUARY 1
#define TM_MARCH 2
#define TM_APRIL 3
#define TM_MAY 4
#define TM_JUNE 5
#define TM_JULY 6
#define TM_AUGUST 7
#define TM_SEPTEMBER 8
#define TM_OCTOBER 9
#define TM_NOVEMBER 10
#define TM_DECEMBER 11
#define TM_YEAR_BASE 1900
#define EPOCH_YEAR 1970
#define EPOCH_WDAY TM_THURSDAY
/*
** Accurate only for the past couple of centuries;
** that will probably do.
*/
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
#ifndef USG
/*
** Use of the underscored variants may cause problems if you move your code to
** certain System-V-based systems; for maximum portability, use the
** underscore-free variants. The underscored variants are provided for
** backward compatibility only; they may disappear from future versions of
** this file.
*/
#define SECS_PER_MIN SECSPERMIN
#define MINS_PER_HOUR MINSPERHOUR
#define HOURS_PER_DAY HOURSPERDAY
#define DAYS_PER_WEEK DAYSPERWEEK
#define DAYS_PER_NYEAR DAYSPERNYEAR
#define DAYS_PER_LYEAR DAYSPERLYEAR
#define SECS_PER_HOUR SECSPERHOUR
#define SECS_PER_DAY SECSPERDAY
#define MONS_PER_YEAR MONSPERYEAR
#endif /* !defined USG */
#endif /* !defined TZFILE_H */