Split the contributed code from libc/stdtime from lib/libc/stdtime

to contrib/tzcode/stdtime.
This commit is contained in:
Edwin Groothuis 2010-02-26 06:44:00 +00:00
parent e7dc8641d6
commit dcfeda6122
12 changed files with 7 additions and 3623 deletions

View File

@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include "../stdlib/atexit.h"
#include "../stdtime/tzfile.h"
#include "tzfile.h" /* from ../../../contrib/tzcode/stdtime */
#define _PATH_ZONEINFO TZDIR /* from tzfile.h */

View File

@ -1,13 +1,16 @@
# Makefile.inc,v 1.2 1994/09/13 21:26:01 wollman Exp
# $FreeBSD$
.PATH: ${.CURDIR}/stdtime ${.CURDIR}/../locale
.PATH: ${.CURDIR}/stdtime ${.CURDIR}/../locale \
${.CURDIR}/../../contrib/tzcode/stdtime
SRCS+= asctime.c difftime.c localtime.c strftime.c strptime.c timelocal.c \
time32.c
SYM_MAPS+= ${.CURDIR}/stdtime/Symbol.map
CFLAGS+= -I${.CURDIR}/../../contrib/tzcode/stdtime -I${.CURDIR}/stdtime
MAN+= ctime.3 strftime.3 strptime.3 time2posix.3
MAN+= tzfile.5

View File

@ -1,142 +0,0 @@
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson.
*/
/*
** Avoid the temptation to punt entirely to strftime;
** the output of strftime is supposed to be locale specific
** whereas the output of asctime is supposed to be constant.
*/
#include <sys/cdefs.h>
#ifndef lint
#ifndef NOID
static char elsieid[] __unused = "@(#)asctime.c 8.2";
#endif /* !defined NOID */
#endif /* !defined lint */
__FBSDID("$FreeBSD$");
/*LINTLIBRARY*/
#include "namespace.h"
#include "private.h"
#include "un-namespace.h"
#include "tzfile.h"
/*
** Some systems only handle "%.2d"; others only handle "%02d";
** "%02.2d" makes (most) everybody happy.
** At least some versions of gcc warn about the %02.2d;
** we conditionalize below to avoid the warning.
*/
/*
** All years associated with 32-bit time_t values are exactly four digits long;
** some years associated with 64-bit time_t values are not.
** Vintage programs are coded for years that are always four digits long
** and may assume that the newline always lands in the same place.
** For years that are less than four digits, we pad the output with
** leading zeroes to get the newline in the traditional place.
** The -4 ensures that we get four characters of output even if
** we call a strftime variant that produces fewer characters for some years.
** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year,
** but many implementations pad anyway; most likely the standards are buggy.
*/
#ifdef __GNUC__
#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n"
#else /* !defined __GNUC__ */
#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n"
#endif /* !defined __GNUC__ */
/*
** For years that are more than four digits we put extra spaces before the year
** so that code trying to overwrite the newline won't end up overwriting
** a digit within a year and truncating the year (operating on the assumption
** that no output is better than wrong output).
*/
#ifdef __GNUC__
#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n"
#else /* !defined __GNUC__ */
#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n"
#endif /* !defined __GNUC__ */
#define STD_ASCTIME_BUF_SIZE 26
/*
** Big enough for something such as
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
** (two three-character abbreviations, five strings denoting integers,
** seven explicit spaces, two explicit colons, a newline,
** and a trailing ASCII nul).
** The values above are for systems where an int is 32 bits and are provided
** as an example; the define below calculates the maximum for the system at
** hand.
*/
#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
static char buf_asctime[MAX_ASCTIME_BUF_SIZE];
/*
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
*/
char *
asctime_r(timeptr, buf)
const struct tm * timeptr;
char * buf;
{
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"
};
const char * wn;
const char * mn;
char year[INT_STRLEN_MAXIMUM(int) + 2];
char result[MAX_ASCTIME_BUF_SIZE];
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];
/*
** Use strftime's %Y to generate the year, to avoid overflow problems
** when computing timeptr->tm_year + TM_YEAR_BASE.
** Assume that strftime is unaffected by other out-of-range members
** (e.g., timeptr->tm_mday) when processing "%Y".
*/
(void) strftime(year, sizeof year, "%Y", timeptr);
/*
** We avoid using snprintf since it's not available on all systems.
*/
(void) sprintf(result,
((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
wn, mn,
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
year);
if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) {
(void) strcpy(buf, result);
return buf;
} else {
#ifdef EOVERFLOW
errno = EOVERFLOW;
#else /* !defined EOVERFLOW */
errno = EINVAL;
#endif /* !defined EOVERFLOW */
return NULL;
}
}
/*
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
*/
char *
asctime(timeptr)
const struct tm * timeptr;
{
return asctime_r(timeptr, buf_asctime);
}

View File

@ -1,374 +0,0 @@
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Arthur Olson.
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" From: @(#)ctime.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd January 2, 1999
.Dt CTIME 3
.Os
.Sh NAME
.Nm asctime ,
.Nm asctime_r ,
.Nm ctime ,
.Nm ctime_r ,
.Nm difftime ,
.Nm gmtime ,
.Nm gmtime_r ,
.Nm localtime ,
.Nm localtime_r ,
.Nm mktime ,
.Nm timegm
.Nd transform binary date and time values
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In time.h
.Vt extern char *tzname[2] ;
.Ft char *
.Fn ctime "const time_t *clock"
.Ft double
.Fn difftime "time_t time1" "time_t time0"
.Ft char *
.Fn asctime "const struct tm *tm"
.Ft struct tm *
.Fn localtime "const time_t *clock"
.Ft struct tm *
.Fn gmtime "const time_t *clock"
.Ft time_t
.Fn mktime "struct tm *tm"
.Ft time_t
.Fn timegm "struct tm *tm"
.Ft char *
.Fn ctime_r "const time_t *clock" "char *buf"
.Ft struct tm *
.Fn localtime_r "const time_t *clock" "struct tm *result"
.Ft struct tm *
.Fn gmtime_r "const time_t *clock" "struct tm *result"
.Ft char *
.Fn asctime_r "const struct tm *tm" "char *buf"
.Sh DESCRIPTION
The functions
.Fn ctime ,
.Fn gmtime
and
.Fn localtime
all take as an argument a time value representing the time in seconds since
the Epoch (00:00:00
.Tn UTC ,
January 1, 1970; see
.Xr time 3 ) .
.Pp
The function
.Fn localtime
converts the time value pointed at by
.Fa clock ,
and returns a pointer to a
.Dq Fa struct tm
(described below) which contains
the broken-out time information for the value after adjusting for the current
time zone (and any other factors such as Daylight Saving Time).
Time zone adjustments are performed as specified by the
.Ev TZ
environment variable (see
.Xr tzset 3 ) .
The function
.Fn localtime
uses
.Xr tzset 3
to initialize time conversion information if
.Xr tzset 3
has not already been called by the process.
.Pp
After filling in the tm structure,
.Fn localtime
sets the
.Fa tm_isdst Ns 'th
element of
.Fa tzname
to a pointer to an
.Tn ASCII
string that is the time zone abbreviation to be
used with
.Fn localtime Ns 's
return value.
.Pp
The function
.Fn gmtime
similarly converts the time value, but without any time zone adjustment,
and returns a pointer to a tm structure (described below).
.Pp
The
.Fn ctime
function
adjusts the time value for the current time zone in the same manner as
.Fn localtime ,
and returns a pointer to a 26-character string of the form:
.Bd -literal -offset indent
Thu Nov 24 18:22:48 1986\en\e0
.Ed
.Pp
All the fields have constant width.
.Pp
The
.Fn ctime_r
function
provides the same functionality as
.Fn ctime
except the caller must provide the output buffer
.Fa buf
to store the result, which must be at least 26 characters long.
The
.Fn localtime_r
and
.Fn gmtime_r
functions
provide the same functionality as
.Fn localtime
and
.Fn gmtime
respectively, except the caller must provide the output buffer
.Fa result .
.Pp
The
.Fn asctime
function
converts the broken down time in the structure
.Fa tm
pointed at by
.Fa *tm
to the form
shown in the example above.
.Pp
The
.Fn asctime_r
function
provides the same functionality as
.Fn asctime
except the caller provide the output buffer
.Fa buf
to store the result, which must be at least 26 characters long.
.Pp
The functions
.Fn mktime
and
.Fn timegm
convert the broken-down time in the structure
pointed to by tm into a time value with the same encoding as that of the
values returned by the
.Xr time 3
function (that is, seconds from the Epoch,
.Tn UTC ) .
The
.Fn mktime
function
interprets the input structure according to the current timezone setting
(see
.Xr tzset 3 ) .
The
.Fn timegm
function
interprets the input structure as representing Universal Coordinated Time
.Pq Tn UTC .
.Pp
The original values of the
.Fa tm_wday
and
.Fa tm_yday
components of the structure are ignored, and the original values of the
other components are not restricted to their normal ranges, and will be
normalized if needed.
For example,
October 40 is changed into November 9,
a
.Fa tm_hour
of \-1 means 1 hour before midnight,
.Fa tm_mday
of 0 means the day preceding the current month, and
.Fa tm_mon
of \-2 means 2 months before January of
.Fa tm_year .
(A positive or zero value for
.Fa tm_isdst
causes
.Fn mktime
to presume initially that summer time (for example, Daylight Saving Time)
is or is not in effect for the specified time, respectively.
A negative value for
.Fa tm_isdst
causes the
.Fn mktime
function to attempt to divine whether summer time is in effect for the
specified time.
The
.Fa tm_isdst
and
.Fa tm_gmtoff
members are forced to zero by
.Fn timegm . )
.Pp
On successful completion, the values of the
.Fa tm_wday
and
.Fa tm_yday
components of the structure are set appropriately, and the other components
are set to represent the specified calendar time, but with their values
forced to their normal ranges; the final value of
.Fa tm_mday
is not set until
.Fa tm_mon
and
.Fa tm_year
are determined.
The
.Fn mktime
function
returns the specified calendar time; if the calendar time cannot be
represented, it returns \-1;
.Pp
The
.Fn difftime
function
returns the difference between two calendar times,
.Pf ( Fa time1
-
.Fa time0 ) ,
expressed in seconds.
.Pp
External declarations as well as the tm structure definition are in the
.In time.h
include file.
The tm structure includes at least the following fields:
.Bd -literal -offset indent
int tm_sec; /\(** seconds (0 - 60) \(**/
int tm_min; /\(** minutes (0 - 59) \(**/
int tm_hour; /\(** hours (0 - 23) \(**/
int tm_mday; /\(** day of month (1 - 31) \(**/
int tm_mon; /\(** month of year (0 - 11) \(**/
int tm_year; /\(** year \- 1900 \(**/
int tm_wday; /\(** day of week (Sunday = 0) \(**/
int tm_yday; /\(** day of year (0 - 365) \(**/
int tm_isdst; /\(** is summer time in effect? \(**/
char \(**tm_zone; /\(** abbreviation of timezone name \(**/
long tm_gmtoff; /\(** offset from UTC in seconds \(**/
.Ed
.Pp
The
field
.Fa tm_isdst
is non-zero if summer time is in effect.
.Pp
The field
.Fa tm_gmtoff
is the offset (in seconds) of the time represented from
.Tn UTC ,
with positive
values indicating east of the Prime Meridian.
.Sh SEE ALSO
.Xr date 1 ,
.Xr gettimeofday 2 ,
.Xr getenv 3 ,
.Xr time 3 ,
.Xr tzset 3 ,
.Xr tzfile 5
.Sh STANDARDS
The
.Fn asctime ,
.Fn ctime ,
.Fn difftime ,
.Fn gmtime ,
.Fn localtime ,
and
.Fn mktime
functions conform to
.St -isoC ,
and conform to
.St -p1003.1-96
provided the selected local timezone does not contain a leap-second table
(see
.Xr zic 8 ) .
.Pp
The
.Fn asctime_r ,
.Fn ctime_r ,
.Fn gmtime_r ,
and
.Fn localtime_r
functions are expected to conform to
.St -p1003.1-96
(again provided the selected local timezone does not contain a leap-second
table).
.Pp
The
.Fn timegm
function is not specified by any standard; its function cannot be
completely emulated using the standard functions described above.
.Sh HISTORY
This manual page is derived from
the time package contributed to Berkeley by
.An Arthur Olson
and which appeared in
.Bx 4.3 .
.Sh BUGS
Except for
.Fn difftime ,
.Fn mktime ,
and the
.Fn \&_r
variants of the other functions,
these functions leaves their result in an internal static object and return
a pointer to that object.
Subsequent calls to these
function will modify the same object.
.Pp
The C Standard provides no mechanism for a program to modify its current
local timezone setting, and the
.Tn POSIX Ns No \&-standard
method is not reentrant.
(However, thread-safe implementations are provided
in the
.Tn POSIX
threaded environment.)
.Pp
The
.Va tm_zone
field of a returned
.Vt tm
structure points to a static array of characters,
which will also be overwritten by any subsequent calls (as well as by
subsequent calls to
.Xr tzset 3
and
.Xr tzsetwall 3 ) .
.Pp
Use of the external variable
.Fa tzname
is discouraged; the
.Fa tm_zone
entry in the tm structure is preferred.

View File

@ -1,69 +0,0 @@
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson.
*/
#include <sys/cdefs.h>
#ifndef lint
#ifndef NOID
static char elsieid[] __unused = "@(#)difftime.c 8.1";
#endif /* !defined NOID */
#endif /* !defined lint */
__FBSDID("$FreeBSD$");
/*LINTLIBRARY*/
#include "namespace.h"
#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
#include "un-namespace.h"
double
difftime(time1, time0)
const time_t time1;
const time_t time0;
{
/*
** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
** (assuming that the larger type has more precision).
** This is the common real-world case circa 2004.
*/
if (sizeof (double) > sizeof (time_t))
return (double) time1 - (double) time0;
if (!TYPE_INTEGRAL(time_t)) {
/*
** time_t is floating.
*/
return time1 - time0;
}
if (!TYPE_SIGNED(time_t)) {
/*
** time_t is integral and unsigned.
** The difference of two unsigned values can't overflow
** if the minuend is greater than or equal to the subtrahend.
*/
if (time1 >= time0)
return time1 - time0;
else return -((double) (time0 - time1));
}
/*
** time_t is integral and signed.
** Handle cases where both time1 and time0 have the same sign
** (meaning that their difference cannot overflow).
*/
if ((time1 < 0) == (time0 < 0))
return time1 - time0;
/*
** time1 and time0 have opposite signs.
** Punt if unsigned long is too narrow.
*/
if (sizeof (unsigned long) < sizeof (time_t))
return (double) time1 - (double) time0;
/*
** Stay calm...decent optimizers will eliminate the complexity below.
*/
if (time1 >= 0 /* && time0 < 0 */)
return (unsigned long) time1 +
(unsigned long) (-(time0 + 1)) + 1;
return -(double) ((unsigned long) time0 +
(unsigned long) (-(time1 + 1)) + 1);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,326 +0,0 @@
#ifndef PRIVATE_H
#define PRIVATE_H
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson.
**
** $FreeBSD$
*/
/* Stuff moved from Makefile.inc to reduce clutter */
#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 HAVE_STRERROR 1
#define HAVE_UNISTD_H 1
#define LOCALE_HOME _PATH_LOCALE
#define TZDIR "/usr/share/zoneinfo"
#endif /* ndef TM_GMTOFF */
/*
** 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 8.6";
*/
#endif /* !defined NOID */
#endif /* !defined lint */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
/*
** 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_GETTEXT
#define HAVE_GETTEXT 0
#endif /* !defined HAVE_GETTEXT */
#ifndef HAVE_INCOMPATIBLE_CTIME_R
#define HAVE_INCOMPATIBLE_CTIME_R 0
#endif /* !defined INCOMPATIBLE_CTIME_R */
#ifndef HAVE_SETTIMEOFDAY
#define HAVE_SETTIMEOFDAY 3
#endif /* !defined HAVE_SETTIMEOFDAY */
#ifndef HAVE_SYMLINK
#define HAVE_SYMLINK 1
#endif /* !defined HAVE_SYMLINK */
#ifndef HAVE_SYS_STAT_H
#define HAVE_SYS_STAT_H 1
#endif /* !defined HAVE_SYS_STAT_H */
#ifndef HAVE_SYS_WAIT_H
#define HAVE_SYS_WAIT_H 1
#endif /* !defined HAVE_SYS_WAIT_H */
#ifndef HAVE_UNISTD_H
#define HAVE_UNISTD_H 1
#endif /* !defined HAVE_UNISTD_H */
#ifndef HAVE_UTMPX_H
#define HAVE_UTMPX_H 0
#endif /* !defined HAVE_UTMPX_H */
#ifndef LOCALE_HOME
#define LOCALE_HOME "/usr/lib/locale"
#endif /* !defined LOCALE_HOME */
#if HAVE_INCOMPATIBLE_CTIME_R
#define asctime_r _incompatible_asctime_r
#define ctime_r _incompatible_ctime_r
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
/*
** Nested includes
*/
#include "sys/types.h" /* for time_t */
#include "stdio.h"
#include "errno.h"
#include "string.h"
#include "limits.h" /* for CHAR_BIT et al. */
#include "time.h"
#include "stdlib.h"
#if HAVE_GETTEXT
#include "libintl.h"
#endif /* HAVE_GETTEXT */
#if HAVE_SYS_WAIT_H
#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
#endif /* HAVE_SYS_WAIT_H */
#ifndef WIFEXITED
#define WIFEXITED(status) (((status) & 0xff) == 0)
#endif /* !defined WIFEXITED */
#ifndef WEXITSTATUS
#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
#endif /* !defined WEXITSTATUS */
#if HAVE_UNISTD_H
#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */
#endif /* HAVE_UNISTD_H */
#if !(HAVE_UNISTD_H)
#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) */
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
/*
** Define HAVE_STDINT_H's default value here, rather than at the
** start, since __GLIBC__'s value depends on previously-included
** files.
** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
*/
#ifndef HAVE_STDINT_H
#define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ || \
2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
#endif /* !defined HAVE_STDINT_H */
#if HAVE_STDINT_H
#include "stdint.h"
#endif /* !HAVE_STDINT_H */
#ifndef INT_FAST64_MAX
/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
#if defined LLONG_MAX || defined __LONG_LONG_MAX__
typedef long long int_fast64_t;
#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
#if (LONG_MAX >> 31) < 0xffffffff
Please use a compiler that supports a 64-bit integer type (or wider);
you may need to compile with "-DHAVE_STDINT_H".
#endif /* (LONG_MAX >> 31) < 0xffffffff */
typedef long int_fast64_t;
#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
#endif /* !defined INT_FAST64_MAX */
#ifndef INT32_MAX
#define INT32_MAX 0x7fffffff
#endif /* !defined INT32_MAX */
#ifndef INT32_MIN
#define INT32_MIN (-1 - INT32_MAX)
#endif /* !defined INT32_MIN */
/*
** Workarounds for compilers/systems.
*/
/*
** Some time.h implementations don't declare asctime_r.
** Others might define it as a macro.
** Fix the former without affecting the latter.
*/
#ifndef asctime_r
extern char * asctime_r(struct tm const *, char *);
#endif
/*
** Private function declarations.
*/
char * icalloc(int nelem, int elsize);
char * icatalloc(char * old, const char * new);
char * icpyalloc(const char * string);
char * imalloc(int n);
void * irealloc(void * pointer, int size);
void icfree(char * pointer);
void ifree(char * pointer);
const char * scheck(const char * string, const char * format);
/*
** Finally, some convenience items.
*/
#ifndef TRUE
#define TRUE 1
#endif /* !defined TRUE */
#ifndef FALSE
#define FALSE 0
#endif /* !defined FALSE */
#ifndef TYPE_BIT
#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
#endif /* !defined TYPE_BIT */
#ifndef TYPE_SIGNED
#define TYPE_SIGNED(type) (((type) -1) < 0)
#endif /* !defined TYPE_SIGNED */
/*
** Since the definition of TYPE_INTEGRAL contains floating point numbers,
** it cannot be used in preprocessor directives.
*/
#ifndef TYPE_INTEGRAL
#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
#endif /* !defined TYPE_INTEGRAL */
/*
** Since the definition of TYPE_INTEGRAL contains floating point numbers,
** it cannot be used in preprocessor directives.
*/
#ifndef TYPE_INTEGRAL
#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
#endif /* !defined TYPE_INTEGRAL */
#ifndef INT_STRLEN_MAXIMUM
/*
** 302 / 1000 is log10(2.0) rounded up.
** Subtract one for the sign bit if the type is signed;
** add one for integer division truncation;
** add one more for a minus sign if the type is signed.
*/
#define INT_STRLEN_MAXIMUM(type) \
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
1 + TYPE_SIGNED(type))
#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 */
/*
** For the benefit of GNU folk...
** `_(MSGID)' uses the current locale's message library string for MSGID.
** The default is to use gettext if available, and use MSGID otherwise.
*/
#ifndef _
#if HAVE_GETTEXT
#define _(msgid) gettext(msgid)
#else /* !HAVE_GETTEXT */
#define _(msgid) msgid
#endif /* !HAVE_GETTEXT */
#endif /* !defined _ */
#ifndef TZ_DOMAIN
#define TZ_DOMAIN "tz"
#endif /* !defined TZ_DOMAIN */
#if HAVE_INCOMPATIBLE_CTIME_R
#undef asctime_r
#undef ctime_r
char *asctime_r(struct tm const *, char *);
char *ctime_r(time_t const *, char *);
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
#ifndef YEARSPERREPEAT
#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
#endif /* !defined YEARSPERREPEAT */
/*
** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
*/
#ifndef AVGSECSPERYEAR
#define AVGSECSPERYEAR 31556952L
#endif /* !defined AVGSECSPERYEAR */
#ifndef SECSPERREPEAT
#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
#endif /* !defined SECSPERREPEAT */
#ifndef SECSPERREPEAT_BITS
#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
#endif /* !defined SECSPERREPEAT_BITS */
/*
** UNIX was a registered trademark of The Open Group in 2003.
*/
#endif /* !defined PRIVATE_H */

View File

@ -1,123 +0,0 @@
.\" $FreeBSD$
.\"
.Dd September 11, 2005
.Dt TIME2POSIX 3
.Os
.Sh NAME
.Nm time2posix ,
.Nm posix2time
.Nd convert seconds since the Epoch
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In time.h
.Ft time_t
.Fn time2posix "time_t t"
.Ft time_t
.Fn posix2time "time_t t"
.Sh DESCRIPTION
.St -p1003.1-88
legislates that a time_t value of
536457599 shall correspond to "Wed Dec 31 23:59:59 GMT 1986."
This effectively implies that POSIX time_t's cannot include leap
seconds and,
therefore,
that the system time must be adjusted as each leap occurs.
.Pp
If the time package is configured with leap-second support
enabled,
however,
no such adjustment is needed and
time_t values continue to increase over leap events
(as a true `seconds since...' value).
This means that these values will differ from those required by POSIX
by the net number of leap seconds inserted since the Epoch.
.Pp
Typically this is not a problem as the type time_t is intended
to be
(mostly)
opaque\(emtime_t values should only be obtained-from and
passed-to functions such as
.Xr time 3 ,
.Xr localtime 3 ,
.Xr mktime 3
and
.Xr difftime 3 .
However,
.St -p1003.1-88
gives an arithmetic
expression for directly computing a time_t value from a given date/time,
and the same relationship is assumed by some
(usually older)
applications.
Any programs creating/dissecting time_t's
using such a relationship will typically not handle intervals
over leap seconds correctly.
.Pp
The
.Fn time2posix
and
.Fn posix2time
functions are provided to address this time_t mismatch by converting
between local time_t values and their POSIX equivalents.
This is done by accounting for the number of time-base changes that
would have taken place on a POSIX system as leap seconds were inserted
or deleted.
These converted values can then be used in lieu of correcting the older
applications,
or when communicating with POSIX-compliant systems.
.Pp
The
.Fn time2posix
function is single-valued.
That is,
every local time_t
corresponds to a single POSIX time_t.
The
.Fn posix2time
function is less well-behaved:
for a positive leap second hit the result is not unique,
and for a negative leap second hit the corresponding
POSIX time_t does not exist so an adjacent value is returned.
Both of these are good indicators of the inferiority of the
POSIX representation.
.Pp
The following table summarizes the relationship between time_t
and its conversion to,
and back from,
the POSIX representation over the leap second inserted at the end of June,
1993.
.Bl -column "93/06/30" "23:59:59" "A+0" "X=time2posix(T)"
.It Sy "DATE TIME T X=time2posix(T) posix2time(X)"
.It "93/06/30 23:59:59 A+0 B+0 A+0"
.It "93/06/30 23:59:60 A+1 B+1 A+1 or A+2"
.It "93/07/01 00:00:00 A+2 B+1 A+1 or A+2"
.It "93/07/01 00:00:01 A+3 B+2 A+3"
.El
.Pp
A leap second deletion would look like...
.Bl -column "??/06/30" "23:59:58" "A+0" "X=time2posix(T)"
.It Sy "DATE TIME T X=time2posix(T) posix2time(X)"
.It "??/06/30 23:59:58 A+0 B+0 A+0"
.It "??/07/01 00:00:00 A+1 B+2 A+1"
.It "??/07/01 00:00:01 A+2 B+3 A+2"
.El
.Pp
.D1 No "[Note: posix2time(B+1) => A+0 or A+1]"
.Pp
If leap-second support is not enabled,
local time_t's and
POSIX time_t's are equivalent,
and both
.Fn time2posix
and
.Fn posix2time
degenerate to the identity function.
.Sh "SEE ALSO"
.Xr difftime 3 ,
.Xr localtime 3 ,
.Xr mktime 3 ,
.Xr time 3
.\" @(#)time2posix.3 8.2
.\" This file is in the public domain, so clarified as of
.\" 1996-06-05 by Arthur David Olson.

View File

@ -1,152 +0,0 @@
.\" $FreeBSD$
.Dd September 13, 1994
.Dt TZFILE 5
.Os
.Sh NAME
.Nm tzfile
.Nd timezone information
.Sh SYNOPSIS
.Fd #include \&"/usr/src/lib/libc/stdtime/tzfile.h\&"
.Sh DESCRIPTION
The time zone information files used by
.Xr tzset 3
begin with the magic characters
.Dq Li TZif
to identify them as
time zone information files,
followed by a character identifying the version of the file's format
(as of 2005, either an ASCII NUL or a '2')
followed by fifteen bytes containing zeroes reserved for future use,
followed by four four-byte values
written in a ``standard'' byte order
(the high-order byte of the value is written first).
These values are,
in order:
.Pp
.Bl -tag -compact -width tzh_ttisstdcnt
.It Va tzh_ttisgmtcnt
The number of UTC/local indicators stored in the file.
.It Va tzh_ttisstdcnt
The number of standard/wall indicators stored in the file.
.It Va tzh_leapcnt
The number of leap seconds for which data is stored in the file.
.It Va tzh_timecnt
The number of ``transition times'' for which data is stored
in the file.
.It Va tzh_typecnt
The number of ``local time types'' for which data is stored
in the file (must not be zero).
.It Va tzh_charcnt
The number of characters of ``time zone abbreviation strings''
stored in the file.
.El
.Pp
The above header is followed by
.Va tzh_timecnt
four-byte values of type
.Fa long ,
sorted in ascending order.
These values are written in ``standard'' byte order.
Each is used as a transition time (as returned by
.Xr time 3 )
at which the rules for computing local time change.
Next come
.Va tzh_timecnt
one-byte values of type
.Fa "unsigned char" ;
each one tells which of the different types of ``local time'' types
described in the file is associated with the same-indexed transition time.
These values serve as indices into an array of
.Fa ttinfo
structures (with
.Fa tzh_typecnt
entries) that appears next in the file;
these structures are defined as follows:
.Pp
.Bd -literal -offset indent
struct ttinfo {
long tt_gmtoff;
int tt_isdst;
unsigned int tt_abbrind;
};
.Ed
.Pp
Each structure is written as a four-byte value for
.Va tt_gmtoff
of type
.Fa long ,
in a standard byte order, followed by a one-byte value for
.Va tt_isdst
and a one-byte value for
.Va tt_abbrind .
In each structure,
.Va tt_gmtoff
gives the number of seconds to be added to UTC,
.Li tt_isdst
tells whether
.Li tm_isdst
should be set by
.Xr localtime 3
and
.Va tt_abbrind
serves as an index into the array of time zone abbreviation characters
that follow the
.Li ttinfo
structure(s) in the file.
.Pp
Then there are
.Va tzh_leapcnt
pairs of four-byte values, written in standard byte order;
the first value of each pair gives the time
(as returned by
.Xr time 3 )
at which a leap second occurs;
the second gives the
.Em total
number of leap seconds to be applied after the given time.
The pairs of values are sorted in ascending order by time.
.Pp
Then there are
.Va tzh_ttisstdcnt
standard/wall indicators, each stored as a one-byte value;
they tell whether the transition times associated with local time types
were specified as standard time or wall clock time,
and are used when a time zone file is used in handling POSIX-style
time zone environment variables.
.Pp
Finally there are
.Va tzh_ttisgmtcnt
UTC/local indicators, each stored as a one-byte value;
they tell whether the transition times associated with local time types
were specified as UTC or local time,
and are used when a time zone file is used in handling POSIX-style
time zone environment variables.
.Pp
.Nm localtime
uses the first standard-time
.Li ttinfo
structure in the file
(or simply the first
.Li ttinfo
structure in the absence of a standard-time structure)
if either
.Li tzh_timecnt
is zero or the time argument is less than the first transition time recorded
in the file.
.Pp
For version-2-format time zone files,
the above header and data is followed by a second header and data,
identical in format except that eight bytes are used for each
transition time or leap second time.
After the second header and data comes a newline-enclosed,
POSIX-TZ-environment-variable-style string for use in handling instants
after the last transition time stored in the file
(with nothing between the newlines if there is no POSIX representation for
such instants).
.Sh SEE ALSO
.Xr ctime 3 ,
.Xr time2posix 3 ,
.Xr zic 8
.\" @(#)tzfile.5 8.3
.\" This file is in the public domain, so clarified as of
.\" 1996-06-05 by Arthur David Olson.

View File

@ -1,184 +0,0 @@
#ifndef TZFILE_H
#define TZFILE_H
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson.
**
** $FreeBSD$
*/
/*
** 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 8.1";
*/
#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. . .
*/
#define TZ_MAGIC "TZif"
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
char tzh_version[1]; /* '\0' or '2' as of 2005 */
char tzh_reserved[15]; /* reserved--must be zero */
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 UTC 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 UTC, if FALSE,
** transition time is local time
** if absent, transition times are
** assumed to be local time
*/
/*
** If tzh_version is '2' or greater, the above is followed by a second instance
** of tzhead and a second instance of the data in which each coded transition
** time uses 8 rather than 4 chars,
** then a POSIX-TZ-environment-variable-style string for use in handling
** instants after the last transition time stored in the file
** (with nothing between the newlines if there is no POSIX representation for
** such instants).
*/
/*
** In the current implementation, "tzset()" refuses to deal with files that
** exceed any of the limits below.
*/
#ifndef TZ_MAX_TIMES
#define TZ_MAX_TIMES 1200
#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.
*/
#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
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
/*
** Since everything in isleap is modulo 400 (or a factor of 400), we know that
** isleap(y) == isleap(y % 400)
** and so
** isleap(a + b) == isleap((a + b) % 400)
** or
** isleap(a + b) == isleap(a % 400 + b % 400)
** This is true even if % means modulo rather than Fortran remainder
** (which is allowed by C89 but not C99).
** We use this to avoid addition overflow problems.
*/
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
#endif /* !defined TZFILE_H */

View File

@ -8,7 +8,7 @@ SRCS= zdump.c ialloc.c scheck.c
CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS
CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"/usr/share/zoneinfo\" -Demkdir=mkdir
CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../lib/libc/stdtime
CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../contrib/tzcode/stdtime
WARNS?= 2

View File

@ -9,7 +9,7 @@ SRCS= zic.c ialloc.c scheck.c
CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS
CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"/usr/share/zoneinfo\" -Demkdir=mkdir
CFLAGS+= -DHAVE_STRERROR -DHAVE_UNISTD_H
CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../lib/libc/stdtime
CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../contrib/tzcode/stdtime
WARNS?= 2