mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-06-10 03:29:29 +00:00
initial checkin
This commit is contained in:
parent
ffae6366ab
commit
997c35962d
25
lib/libc/stdtime/Makefile
Normal file
25
lib/libc/stdtime/Makefile
Normal 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
|
71
lib/libc/stdtime/asctime.c
Normal file
71
lib/libc/stdtime/asctime.c
Normal 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;
|
||||
}
|
93
lib/libc/stdtime/difftime.c
Normal file
93
lib/libc/stdtime/difftime.c
Normal 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
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
222
lib/libc/stdtime/private.h
Normal 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
612
lib/libc/stdtime/strftime.c
Normal 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
182
lib/libc/stdtime/tzfile.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user