am f41fe717
: Merge "Sync with upstream tzcode (2015g)."
* commit 'f41fe717655f01affc1d8244ff9efccc04d86620': Sync with upstream tzcode (2015g).
This commit is contained in:
commit
c1d7d92201
7 changed files with 2087 additions and 1799 deletions
|
@ -688,11 +688,13 @@ LOCAL_SRC_FILES += upstream-openbsd/lib/libc/time/wcsftime.c
|
|||
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) \
|
||||
-fvisibility=hidden \
|
||||
-Wno-unused-parameter \
|
||||
|
||||
# Don't use ridiculous amounts of stack.
|
||||
LOCAL_CFLAGS += -DALL_STATE
|
||||
# Include tzsetwall, timelocal, timegm, time2posix, and posix2time.
|
||||
LOCAL_CFLAGS += -DSTD_INSPIRED
|
||||
LOCAL_CFLAGS += -DTHREAD_SAFE
|
||||
# The name of the tm_gmtoff field in our struct tm.
|
||||
LOCAL_CFLAGS += -DTM_GMTOFF=tm_gmtoff
|
||||
# Where we store our tzdata.
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
** ??? ???-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).
|
||||
** and a trailing NUL byte).
|
||||
** 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.
|
||||
|
@ -99,11 +99,11 @@ asctime_r(register const struct tm *timeptr, char *buf)
|
|||
** 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);
|
||||
strftime(year, sizeof year, "%Y", timeptr);
|
||||
/*
|
||||
** We avoid using snprintf since it's not available on all systems.
|
||||
*/
|
||||
(void) snprintf(result, sizeof(result), /* Android change: use snprintf. */
|
||||
snprintf(result, sizeof(result), /* Android change: use snprintf. */
|
||||
((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
|
||||
wn, mn,
|
||||
timeptr->tm_mday, timeptr->tm_hour,
|
||||
|
@ -112,11 +112,7 @@ asctime_r(register const struct tm *timeptr, char *buf)
|
|||
if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime)
|
||||
return strcpy(buf, result);
|
||||
else {
|
||||
#ifdef EOVERFLOW
|
||||
errno = EOVERFLOW;
|
||||
#else /* !defined EOVERFLOW */
|
||||
errno = EINVAL;
|
||||
#endif /* !defined EOVERFLOW */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,42 +7,52 @@
|
|||
|
||||
#include "private.h" /* for time_t and TYPE_SIGNED */
|
||||
|
||||
/* Return -X as a double. Using this avoids casting to 'double'. */
|
||||
static double
|
||||
dminus(double x)
|
||||
{
|
||||
return -x;
|
||||
}
|
||||
|
||||
double ATTRIBUTE_CONST
|
||||
difftime(const time_t time1, const time_t time0)
|
||||
difftime(time_t time1, time_t time0)
|
||||
{
|
||||
/*
|
||||
** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
|
||||
** If double is large enough, simply convert and subtract
|
||||
** (assuming that the larger type has more precision).
|
||||
*/
|
||||
if (sizeof (double) > sizeof (time_t))
|
||||
return (double) time1 - (double) time0;
|
||||
if (!TYPE_SIGNED(time_t)) {
|
||||
/*
|
||||
** 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);
|
||||
if (sizeof (time_t) < sizeof (double)) {
|
||||
double t1 = time1, t0 = time0;
|
||||
return t1 - t0;
|
||||
}
|
||||
|
||||
/*
|
||||
** The difference of two unsigned values can't overflow
|
||||
** if the minuend is greater than or equal to the subtrahend.
|
||||
*/
|
||||
if (!TYPE_SIGNED(time_t))
|
||||
return time0 <= time1 ? time1 - time0 : dminus(time0 - time1);
|
||||
|
||||
/* Use uintmax_t if wide enough. */
|
||||
if (sizeof (time_t) <= sizeof (uintmax_t)) {
|
||||
uintmax_t t1 = time1, t0 = time0;
|
||||
return time0 <= time1 ? t1 - t0 : dminus(t0 - t1);
|
||||
}
|
||||
|
||||
/*
|
||||
** 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;
|
||||
return time1 - time0;
|
||||
|
||||
/*
|
||||
** time1 and time0 have opposite signs.
|
||||
** Punt if uintmax_t is too narrow.
|
||||
** The values have opposite signs and uintmax_t is too narrow.
|
||||
** This suffers from double rounding; attempt to lessen that
|
||||
** by using long double temporaries.
|
||||
*/
|
||||
if (sizeof (uintmax_t) < sizeof (time_t))
|
||||
return (long double) time1 - (long double) time0;
|
||||
/*
|
||||
** Stay calm...decent optimizers will eliminate the complexity below.
|
||||
*/
|
||||
if (time1 >= 0 /* && time0 < 0 */)
|
||||
return (uintmax_t) time1 + (uintmax_t) (-1 - time0) + 1;
|
||||
return -(double) ((uintmax_t) time0 + (uintmax_t) (-1 - time1) + 1);
|
||||
{
|
||||
long double t1 = time1, t0 = time0;
|
||||
return t1 - t0;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,13 +19,9 @@
|
|||
|
||||
/*
|
||||
** Defaults for preprocessor symbols.
|
||||
** You can override these in your C compiler options, e.g. '-DHAVE_ADJTIME=0'.
|
||||
** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_ADJTIME
|
||||
#define HAVE_ADJTIME 1
|
||||
#endif /* !defined HAVE_ADJTIME */
|
||||
|
||||
#ifndef HAVE_GETTEXT
|
||||
#define HAVE_GETTEXT 0
|
||||
#endif /* !defined HAVE_GETTEXT */
|
||||
|
@ -38,9 +34,9 @@
|
|||
#define HAVE_LINK 1
|
||||
#endif /* !defined HAVE_LINK */
|
||||
|
||||
#ifndef HAVE_SETTIMEOFDAY
|
||||
#define HAVE_SETTIMEOFDAY 3
|
||||
#endif /* !defined HAVE_SETTIMEOFDAY */
|
||||
#ifndef HAVE_STRDUP
|
||||
#define HAVE_STRDUP 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SYMLINK
|
||||
#define HAVE_SYMLINK 1
|
||||
|
@ -59,32 +55,61 @@
|
|||
#endif /* !defined HAVE_UNISTD_H */
|
||||
|
||||
#ifndef HAVE_UTMPX_H
|
||||
#define HAVE_UTMPX_H 0
|
||||
#define HAVE_UTMPX_H 1
|
||||
#endif /* !defined HAVE_UTMPX_H */
|
||||
|
||||
#if !defined(__ANDROID__)
|
||||
#ifndef LOCALE_HOME
|
||||
#define LOCALE_HOME "/usr/lib/locale"
|
||||
#endif /* !defined LOCALE_HOME */
|
||||
#endif // __ANDROID__
|
||||
#ifndef NETBSD_INSPIRED
|
||||
# define NETBSD_INSPIRED 1
|
||||
#endif
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#define asctime_r _incompatible_asctime_r
|
||||
#define ctime_r _incompatible_ctime_r
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
/* Enable tm_gmtoff and tm_zone on GNUish systems. */
|
||||
#define _GNU_SOURCE 1
|
||||
/* Fix asctime_r on Solaris 10. */
|
||||
#define _POSIX_PTHREAD_SEMANTICS 1
|
||||
/* Enable strtoimax on Solaris 10. */
|
||||
#define __EXTENSIONS__ 1
|
||||
|
||||
/*
|
||||
** Nested includes
|
||||
*/
|
||||
|
||||
/* Avoid clashes with NetBSD by renaming NetBSD's declarations. */
|
||||
#define localtime_rz sys_localtime_rz
|
||||
#define mktime_z sys_mktime_z
|
||||
#define posix2time_z sys_posix2time_z
|
||||
#define time2posix_z sys_time2posix_z
|
||||
#define timezone_t sys_timezone_t
|
||||
#define tzalloc sys_tzalloc
|
||||
#define tzfree sys_tzfree
|
||||
#include <time.h>
|
||||
#undef localtime_rz
|
||||
#undef mktime_z
|
||||
#undef posix2time_z
|
||||
#undef time2posix_z
|
||||
#undef timezone_t
|
||||
#undef tzalloc
|
||||
#undef tzfree
|
||||
|
||||
#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"
|
||||
|
||||
#include "errno.h"
|
||||
|
||||
#ifndef ENAMETOOLONG
|
||||
# define ENAMETOOLONG EINVAL
|
||||
#endif
|
||||
#ifndef EOVERFLOW
|
||||
# define EOVERFLOW EINVAL
|
||||
#endif
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
#include "libintl.h"
|
||||
#endif /* HAVE_GETTEXT */
|
||||
|
@ -104,6 +129,14 @@
|
|||
#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#ifndef HAVE_STRFTIME_L
|
||||
# if _POSIX_VERSION < 200809
|
||||
# define HAVE_STRFTIME_L 0
|
||||
# else
|
||||
# define HAVE_STRFTIME_L 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef F_OK
|
||||
#define F_OK 0
|
||||
#endif /* !defined F_OK */
|
||||
|
@ -138,65 +171,98 @@
|
|||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#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;
|
||||
#ifdef __LONG_LONG_MAX__
|
||||
# ifndef LLONG_MAX
|
||||
# define LLONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifndef LLONG_MIN
|
||||
# define LLONG_MIN (-1 - LLONG_MAX)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INT_FAST64_MAX
|
||||
# ifdef LLONG_MAX
|
||||
typedef long long int_fast64_t;
|
||||
# define INT_FAST64_MIN LLONG_MIN
|
||||
# define INT_FAST64_MAX LLONG_MAX
|
||||
# else
|
||||
# define INT_FAST64_MIN __LONG_LONG_MIN__
|
||||
# define INT_FAST64_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# define SCNdFAST64 "lld"
|
||||
#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
|
||||
#if (LONG_MAX >> 31) < 0xffffffff
|
||||
# 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 */
|
||||
# endif
|
||||
typedef long int_fast64_t;
|
||||
# define INT_FAST64_MIN LONG_MIN
|
||||
# define INT_FAST64_MAX LONG_MAX
|
||||
# define SCNdFAST64 "ld"
|
||||
#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
|
||||
#endif /* !defined INT_FAST64_MAX */
|
||||
# define INT_FAST64_MIN LONG_MIN
|
||||
# define INT_FAST64_MAX LONG_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SCNdFAST64
|
||||
# if INT_FAST64_MAX == LLONG_MAX
|
||||
# define SCNdFAST64 "lld"
|
||||
# else
|
||||
# define SCNdFAST64 "ld"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INT_FAST32_MAX
|
||||
# if INT_MAX >> 31 == 0
|
||||
typedef long int_fast32_t;
|
||||
# define INT_FAST32_MAX LONG_MAX
|
||||
# define INT_FAST32_MIN LONG_MIN
|
||||
# else
|
||||
typedef int int_fast32_t;
|
||||
# define INT_FAST32_MAX INT_MAX
|
||||
# define INT_FAST32_MIN INT_MIN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INTMAX_MAX
|
||||
# if defined LLONG_MAX || defined __LONG_LONG_MAX__
|
||||
# ifdef LLONG_MAX
|
||||
typedef long long intmax_t;
|
||||
# define strtoimax strtoll
|
||||
# define PRIdMAX "lld"
|
||||
# ifdef LLONG_MAX
|
||||
# define INTMAX_MAX LLONG_MAX
|
||||
# define INTMAX_MIN LLONG_MIN
|
||||
# else
|
||||
# define INTMAX_MAX __LONG_LONG_MAX__
|
||||
# define INTMAX_MIN __LONG_LONG_MIN__
|
||||
# endif
|
||||
# define INTMAX_MAX LLONG_MAX
|
||||
# define INTMAX_MIN LLONG_MIN
|
||||
# else
|
||||
typedef long intmax_t;
|
||||
# define strtoimax strtol
|
||||
# define PRIdMAX "ld"
|
||||
# define INTMAX_MAX LONG_MAX
|
||||
# define INTMAX_MIN LONG_MIN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PRIdMAX
|
||||
# if INTMAX_MAX == LLONG_MAX
|
||||
# define PRIdMAX "lld"
|
||||
# else
|
||||
# define PRIdMAX "ld"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef UINT_FAST64_MAX
|
||||
# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
|
||||
typedef unsigned long long uint_fast64_t;
|
||||
# else
|
||||
# if ULONG_MAX >> 31 >> 1 < 0xffffffff
|
||||
Please use a compiler that supports a 64-bit integer type (or wider);
|
||||
you may need to compile with "-DHAVE_STDINT_H".
|
||||
# endif
|
||||
typedef unsigned long uint_fast64_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef UINTMAX_MAX
|
||||
# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
|
||||
typedef unsigned long long uintmax_t;
|
||||
# define PRIuMAX "llu"
|
||||
# else
|
||||
typedef unsigned long uintmax_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PRIuMAX
|
||||
# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
|
||||
# define PRIuMAX "llu"
|
||||
# else
|
||||
# define PRIuMAX "lu"
|
||||
# endif
|
||||
#endif
|
||||
|
@ -238,16 +304,6 @@ typedef unsigned long uintmax_t;
|
|||
** 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
|
||||
|
||||
/*
|
||||
** Compile with -Dtime_tz=T to build the tz package with a private
|
||||
** time_t type equivalent to T rather than the system-supplied time_t.
|
||||
|
@ -256,7 +312,11 @@ extern char * asctime_r(struct tm const *, char *);
|
|||
** typical platforms.
|
||||
*/
|
||||
#ifdef time_tz
|
||||
# ifdef LOCALTIME_IMPLEMENTATION
|
||||
static time_t sys_time(time_t *x) { return time(x); }
|
||||
# endif
|
||||
|
||||
typedef time_tz tz_time_t;
|
||||
|
||||
# undef ctime
|
||||
# define ctime tz_ctime
|
||||
|
@ -272,14 +332,40 @@ static time_t sys_time(time_t *x) { return time(x); }
|
|||
# define localtime tz_localtime
|
||||
# undef localtime_r
|
||||
# define localtime_r tz_localtime_r
|
||||
# undef localtime_rz
|
||||
# define localtime_rz tz_localtime_rz
|
||||
# undef mktime
|
||||
# define mktime tz_mktime
|
||||
# undef mktime_z
|
||||
# define mktime_z tz_mktime_z
|
||||
# undef offtime
|
||||
# define offtime tz_offtime
|
||||
# undef posix2time
|
||||
# define posix2time tz_posix2time
|
||||
# undef posix2time_z
|
||||
# define posix2time_z tz_posix2time_z
|
||||
# undef time
|
||||
# define time tz_time
|
||||
# undef time2posix
|
||||
# define time2posix tz_time2posix
|
||||
# undef time2posix_z
|
||||
# define time2posix_z tz_time2posix_z
|
||||
# undef time_t
|
||||
# define time_t tz_time_t
|
||||
|
||||
typedef time_tz time_t;
|
||||
# undef timegm
|
||||
# define timegm tz_timegm
|
||||
# undef timelocal
|
||||
# define timelocal tz_timelocal
|
||||
# undef timeoff
|
||||
# define timeoff tz_timeoff
|
||||
# undef tzalloc
|
||||
# define tzalloc tz_tzalloc
|
||||
# undef tzfree
|
||||
# define tzfree tz_tzfree
|
||||
# undef tzset
|
||||
# define tzset tz_tzset
|
||||
# undef tzsetwall
|
||||
# define tzsetwall tz_tzsetwall
|
||||
|
||||
char *ctime(time_t const *);
|
||||
char *ctime_r(time_t const *, char *);
|
||||
|
@ -289,36 +375,111 @@ struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
|
|||
struct tm *localtime(time_t const *);
|
||||
struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
|
||||
time_t mktime(struct tm *);
|
||||
|
||||
static time_t
|
||||
time(time_t *p)
|
||||
{
|
||||
time_t r = sys_time(0);
|
||||
if (p)
|
||||
*p = r;
|
||||
return r;
|
||||
}
|
||||
time_t time(time_t *);
|
||||
void tzset(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Private function declarations.
|
||||
** Some time.h implementations don't declare asctime_r.
|
||||
** Others might define it as a macro.
|
||||
** Fix the former without affecting the latter.
|
||||
** Similarly for timezone, daylight, and altzone.
|
||||
*/
|
||||
|
||||
char * icatalloc(char * old, const char * new);
|
||||
char * icpyalloc(const char * string);
|
||||
const char * scheck(const char * string, const char * format);
|
||||
#ifndef asctime_r
|
||||
extern char * asctime_r(struct tm const *restrict, char *restrict);
|
||||
#endif
|
||||
|
||||
#ifdef USG_COMPAT
|
||||
# ifndef timezone
|
||||
extern long timezone;
|
||||
# endif
|
||||
# ifndef daylight
|
||||
extern int daylight;
|
||||
# endif
|
||||
#endif
|
||||
#if defined ALTZONE && !defined altzone
|
||||
extern long altzone;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The STD_INSPIRED functions are similar, but most also need
|
||||
** declarations if time_tz is defined.
|
||||
*/
|
||||
|
||||
#ifdef STD_INSPIRED
|
||||
# if !defined tzsetwall || defined time_tz
|
||||
void tzsetwall(void);
|
||||
# endif
|
||||
# if !defined offtime || defined time_tz
|
||||
struct tm *offtime(time_t const *, long);
|
||||
# endif
|
||||
# if !defined timegm || defined time_tz
|
||||
time_t timegm(struct tm *);
|
||||
# endif
|
||||
# if !defined timelocal || defined time_tz
|
||||
time_t timelocal(struct tm *);
|
||||
# endif
|
||||
# if !defined timeoff || defined time_tz
|
||||
time_t timeoff(struct tm *, long);
|
||||
# endif
|
||||
# if !defined time2posix || defined time_tz
|
||||
time_t time2posix(time_t);
|
||||
# endif
|
||||
# if !defined posix2time || defined time_tz
|
||||
time_t posix2time(time_t);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Infer TM_ZONE on systems where this information is known, but suppress
|
||||
guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
|
||||
#if (defined __GLIBC__ \
|
||||
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|
||||
|| (defined __APPLE__ && defined __MACH__))
|
||||
# if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
|
||||
# define TM_GMTOFF tm_gmtoff
|
||||
# endif
|
||||
# if !defined TM_ZONE && !defined NO_TM_ZONE
|
||||
# define TM_ZONE tm_zone
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Define functions that are ABI compatible with NetBSD but have
|
||||
** better prototypes. NetBSD 6.1.4 defines a pointer type timezone_t
|
||||
** and labors under the misconception that 'const timezone_t' is a
|
||||
** pointer to a constant. This use of 'const' is ineffective, so it
|
||||
** is not done here. What we call 'struct state' NetBSD calls
|
||||
** 'struct __state', but this is a private name so it doesn't matter.
|
||||
*/
|
||||
#if NETBSD_INSPIRED
|
||||
typedef struct state *timezone_t;
|
||||
struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
|
||||
struct tm *restrict);
|
||||
time_t mktime_z(timezone_t restrict, struct tm *restrict);
|
||||
timezone_t tzalloc(char const *);
|
||||
void tzfree(timezone_t);
|
||||
# ifdef STD_INSPIRED
|
||||
# if !defined posix2time_z || defined time_tz
|
||||
time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_PURE;
|
||||
# endif
|
||||
# if !defined time2posix_z || defined time_tz
|
||||
time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Finally, some convenience items.
|
||||
*/
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* !defined TRUE */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* !defined FALSE */
|
||||
#if __STDC_VERSION__ < 199901
|
||||
# define true 1
|
||||
# define false 0
|
||||
# define bool int
|
||||
#else
|
||||
# include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_BIT
|
||||
#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
|
||||
|
@ -330,14 +491,14 @@ const char * scheck(const char * string, const char * format);
|
|||
|
||||
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
|
||||
|
||||
/* Max and min values of the integer type T, of which only the bottom
|
||||
* B bits are used, and where the highest-order used bit is considered
|
||||
* to be a sign bit if T is signed. */
|
||||
#define MAXVAL(t, b) \
|
||||
((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
|
||||
- 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
|
||||
#define MINVAL(t, b) \
|
||||
((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
|
||||
/* Max and min values of the integer type T, of which only the bottom
|
||||
B bits are used, and where the highest-order used bit is considered
|
||||
to be a sign bit if T is signed. */
|
||||
#define MAXVAL(t, b) \
|
||||
((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
|
||||
- 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
|
||||
#define MINVAL(t, b) \
|
||||
((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
|
||||
|
||||
/* The minimum and maximum finite time values. This assumes no padding. */
|
||||
static time_t const time_t_min = MINVAL(time_t, TYPE_BIT(time_t));
|
||||
|
@ -365,6 +526,10 @@ static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
|
|||
# define INITIALIZE(x)
|
||||
#endif
|
||||
|
||||
#ifndef UNINIT_TRAP
|
||||
# define UNINIT_TRAP 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** For the benefit of GNU folk...
|
||||
** '_(MSGID)' uses the current locale's message library string for MSGID.
|
||||
|
@ -379,7 +544,7 @@ static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
|
|||
#endif /* !HAVE_GETTEXT */
|
||||
#endif /* !defined _ */
|
||||
|
||||
#if !defined TZ_DOMAIN && defined TZ_DOMAINDIR
|
||||
#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
|
||||
# define TZ_DOMAIN "tz"
|
||||
#endif
|
||||
|
||||
|
@ -410,8 +575,4 @@ char *ctime_r(time_t const *, char *);
|
|||
#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 */
|
||||
|
|
|
@ -55,15 +55,7 @@ struct lc_time_T {
|
|||
const char * date_fmt;
|
||||
};
|
||||
|
||||
#ifdef LOCALE_HOME
|
||||
#include "sys/stat.h"
|
||||
static struct lc_time_T localebuf;
|
||||
static struct lc_time_T * _loc(void);
|
||||
#define Locale _loc()
|
||||
#endif /* defined LOCALE_HOME */
|
||||
#ifndef LOCALE_HOME
|
||||
#define Locale (&C_time_locale)
|
||||
#endif /* !defined LOCALE_HOME */
|
||||
|
||||
static const struct lc_time_T C_time_locale = {
|
||||
{
|
||||
|
@ -115,7 +107,7 @@ static char * _add(const char *, char *, const char *, int);
|
|||
static char * _conv(int, const char *, char *, const char *);
|
||||
static char * _fmt(const char *, const struct tm *, char *, const char *,
|
||||
int *);
|
||||
static char * _yconv(int, int, int, int, char *, const char *, int);
|
||||
static char * _yconv(int, int, bool, bool, char *, const char *, int);
|
||||
static char * getformat(int, char *, char *, char *, char *);
|
||||
|
||||
extern char * tzname[];
|
||||
|
@ -132,32 +124,28 @@ extern char * tzname[];
|
|||
#define FORCE_LOWER_CASE 0x100
|
||||
|
||||
size_t
|
||||
strftime(char * const s, const size_t maxsize, const char *const format,
|
||||
const struct tm *const t)
|
||||
strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
|
||||
{
|
||||
char * p;
|
||||
int warn;
|
||||
|
||||
tzset();
|
||||
#ifdef LOCALE_HOME
|
||||
localebuf.mon[0] = 0;
|
||||
#endif /* defined LOCALE_HOME */
|
||||
warn = IN_NONE;
|
||||
p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
|
||||
#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
|
||||
if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
|
||||
(void) fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\n");
|
||||
if (format == NULL)
|
||||
(void) fprintf(stderr, "NULL strftime format ");
|
||||
else (void) fprintf(stderr, "strftime format \"%s\" ",
|
||||
fprintf(stderr, "NULL strftime format ");
|
||||
else fprintf(stderr, "strftime format \"%s\" ",
|
||||
format);
|
||||
(void) fprintf(stderr, "yields only two digits of years in ");
|
||||
fprintf(stderr, "yields only two digits of years in ");
|
||||
if (warn == IN_SOME)
|
||||
(void) fprintf(stderr, "some locales");
|
||||
fprintf(stderr, "some locales");
|
||||
else if (warn == IN_THIS)
|
||||
(void) fprintf(stderr, "the current locale");
|
||||
else (void) fprintf(stderr, "all locales");
|
||||
(void) fprintf(stderr, "\n");
|
||||
fprintf(stderr, "the current locale");
|
||||
else fprintf(stderr, "all locales");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
|
||||
if (p == s + maxsize)
|
||||
|
@ -171,20 +159,17 @@ static char *getformat(int modifier, char *normal, char *underscore,
|
|||
switch (modifier) {
|
||||
case '_':
|
||||
return underscore;
|
||||
|
||||
case '-':
|
||||
return dash;
|
||||
|
||||
case '0':
|
||||
return zero;
|
||||
}
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
static char *
|
||||
_fmt(const char *format, const struct tm *const t, char * pt,
|
||||
const char *const ptlim, int *warnp)
|
||||
_fmt(const char *format, const struct tm *t, char *pt,
|
||||
const char *ptlim, int *warnp)
|
||||
{
|
||||
for ( ; *format; ++format) {
|
||||
if (*format == '%') {
|
||||
|
@ -227,8 +212,8 @@ label:
|
|||
** something completely different.
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0,
|
||||
pt, ptlim, modifier);
|
||||
pt = _yconv(t->tm_year, TM_YEAR_BASE,
|
||||
true, false, pt, ptlim, modifier);
|
||||
continue;
|
||||
case 'c':
|
||||
{
|
||||
|
@ -245,10 +230,7 @@ label:
|
|||
pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'd':
|
||||
pt = _conv(t->tm_mday,
|
||||
getformat(modifier, "%02d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
pt = _conv(t->tm_mday, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 'E':
|
||||
case 'O':
|
||||
|
@ -270,31 +252,21 @@ label:
|
|||
modifier = *format;
|
||||
goto label;
|
||||
case 'e':
|
||||
pt = _conv(t->tm_mday,
|
||||
getformat(modifier, "%2d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
pt = _conv(t->tm_mday, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 'F':
|
||||
pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'H':
|
||||
pt = _conv(t->tm_hour,
|
||||
getformat(modifier, "%02d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
pt = _conv(t->tm_hour, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 'I':
|
||||
pt = _conv((t->tm_hour % 12) ?
|
||||
(t->tm_hour % 12) : 12,
|
||||
getformat(modifier, "%02d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 'j':
|
||||
pt = _conv(t->tm_yday + 1,
|
||||
getformat(modifier, "%03d", "%3d", "%d", "%03d"),
|
||||
pt, ptlim);
|
||||
pt = _conv(t->tm_yday + 1, getformat(modifier, "%03d", "%3d", "%d", "%03d"), pt, ptlim);
|
||||
continue;
|
||||
case 'k':
|
||||
/*
|
||||
|
@ -307,10 +279,7 @@ label:
|
|||
** "%l" have been swapped.
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv(t->tm_hour,
|
||||
getformat(modifier, "%2d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
pt = _conv(t->tm_hour, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
#ifdef KITCHEN_SINK
|
||||
case 'K':
|
||||
|
@ -332,36 +301,23 @@ label:
|
|||
*/
|
||||
pt = _conv((t->tm_hour % 12) ?
|
||||
(t->tm_hour % 12) : 12,
|
||||
getformat(modifier, "%2d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 'M':
|
||||
pt = _conv(t->tm_min,
|
||||
getformat(modifier, "%02d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
pt = _conv(t->tm_min, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 'm':
|
||||
pt = _conv(t->tm_mon + 1,
|
||||
getformat(modifier, "%02d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
pt = _conv(t->tm_mon + 1, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 'n':
|
||||
pt = _add("\n", pt, ptlim, modifier);
|
||||
continue;
|
||||
case 'P':
|
||||
case 'p':
|
||||
pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
|
||||
Locale->pm :
|
||||
Locale->am,
|
||||
pt, ptlim, modifier);
|
||||
continue;
|
||||
case 'P':
|
||||
pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
|
||||
Locale->pm :
|
||||
Locale->am,
|
||||
pt, ptlim, FORCE_LOWER_CASE);
|
||||
pt, ptlim, (*format == 'P') ? FORCE_LOWER_CASE : modifier);
|
||||
continue;
|
||||
case 'R':
|
||||
pt = _fmt("%H:%M", t, pt, ptlim, warnp);
|
||||
|
@ -370,10 +326,7 @@ label:
|
|||
pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'S':
|
||||
pt = _conv(t->tm_sec,
|
||||
getformat(modifier, "%02d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
pt = _conv(t->tm_sec, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 's':
|
||||
{
|
||||
|
@ -385,10 +338,10 @@ label:
|
|||
tm = *t;
|
||||
mkt = mktime64(&tm);
|
||||
if (TYPE_SIGNED(time64_t))
|
||||
(void) snprintf(buf, sizeof(buf), "%lld",
|
||||
(long long) mkt);
|
||||
else (void) snprintf(buf, sizeof(buf), "%llu",
|
||||
(unsigned long long) mkt);
|
||||
snprintf(buf, sizeof(buf), "%"PRIdMAX,
|
||||
(intmax_t) mkt);
|
||||
else snprintf(buf, sizeof(buf), "%"PRIuMAX,
|
||||
(uintmax_t) mkt);
|
||||
pt = _add(buf, pt, ptlim, modifier);
|
||||
}
|
||||
continue;
|
||||
|
@ -401,9 +354,7 @@ label:
|
|||
case 'U':
|
||||
pt = _conv((t->tm_yday + DAYSPERWEEK -
|
||||
t->tm_wday) / DAYSPERWEEK,
|
||||
getformat(modifier, "%02d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 'u':
|
||||
/*
|
||||
|
@ -413,7 +364,8 @@ label:
|
|||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv((t->tm_wday == 0) ?
|
||||
DAYSPERWEEK : t->tm_wday, "%d", pt, ptlim);
|
||||
DAYSPERWEEK : t->tm_wday,
|
||||
"%d", pt, ptlim);
|
||||
continue;
|
||||
case 'V': /* ISO 8601 week number */
|
||||
case 'G': /* ISO 8601 year (four digits) */
|
||||
|
@ -493,14 +445,15 @@ label:
|
|||
w = 53;
|
||||
#endif /* defined XPG4_1994_04_09 */
|
||||
if (*format == 'V')
|
||||
pt = _conv(w,
|
||||
getformat(modifier, "%02d", "%2d", "%d", "%02d"),
|
||||
pt = _conv(w, getformat(modifier, "%02d", "%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
else if (*format == 'g') {
|
||||
*warnp = IN_ALL;
|
||||
pt = _yconv(year, base, 0, 1,
|
||||
pt = _yconv(year, base,
|
||||
false, true,
|
||||
pt, ptlim, modifier);
|
||||
} else pt = _yconv(year, base, 1, 1,
|
||||
} else pt = _yconv(year, base,
|
||||
true, true,
|
||||
pt, ptlim, modifier);
|
||||
}
|
||||
continue;
|
||||
|
@ -517,9 +470,7 @@ label:
|
|||
(t->tm_wday ?
|
||||
(t->tm_wday - 1) :
|
||||
(DAYSPERWEEK - 1))) / DAYSPERWEEK,
|
||||
getformat(modifier, "%02d",
|
||||
"%2d", "%d", "%02d"),
|
||||
pt, ptlim);
|
||||
getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
|
||||
continue;
|
||||
case 'w':
|
||||
pt = _conv(t->tm_wday, "%d", pt, ptlim);
|
||||
|
@ -540,23 +491,23 @@ label:
|
|||
continue;
|
||||
case 'y':
|
||||
*warnp = IN_ALL;
|
||||
pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1,
|
||||
pt = _yconv(t->tm_year, TM_YEAR_BASE,
|
||||
false, true,
|
||||
pt, ptlim, modifier);
|
||||
continue;
|
||||
case 'Y':
|
||||
pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1,
|
||||
pt = _yconv(t->tm_year, TM_YEAR_BASE,
|
||||
true, true,
|
||||
pt, ptlim, modifier);
|
||||
continue;
|
||||
case 'Z':
|
||||
#ifdef TM_ZONE
|
||||
if (t->TM_ZONE != NULL)
|
||||
pt = _add(t->TM_ZONE, pt, ptlim,
|
||||
modifier);
|
||||
else
|
||||
#endif /* defined TM_ZONE */
|
||||
pt = _add(t->TM_ZONE, pt, ptlim, modifier);
|
||||
#else
|
||||
if (t->tm_isdst >= 0)
|
||||
pt = _add(tzname[t->tm_isdst != 0],
|
||||
pt, ptlim, modifier);
|
||||
pt, ptlim);
|
||||
#endif
|
||||
/*
|
||||
** C99 says that %Z must be replaced by the
|
||||
** empty string if the time zone is not
|
||||
|
@ -613,10 +564,7 @@ label:
|
|||
diff /= SECSPERMIN;
|
||||
diff = (diff / MINSPERHOUR) * 100 +
|
||||
(diff % MINSPERHOUR);
|
||||
pt = _conv(diff,
|
||||
getformat(modifier, "%04d",
|
||||
"%4d", "%d", "%04d"),
|
||||
pt, ptlim);
|
||||
pt = _conv(diff, getformat(modifier, "%04d", "%4d", "%d", "%04d"), pt, ptlim);
|
||||
}
|
||||
continue;
|
||||
case '+':
|
||||
|
@ -641,13 +589,12 @@ label:
|
|||
}
|
||||
|
||||
static char *
|
||||
_conv(const int n, const char *const format, char *const pt,
|
||||
const char *const ptlim)
|
||||
_conv(int n, const char *format, char *pt, const char *ptlim)
|
||||
{
|
||||
char buf[INT_STRLEN_MAXIMUM(int) + 1];
|
||||
char buf[INT_STRLEN_MAXIMUM(int) + 1];
|
||||
|
||||
(void) snprintf(buf, sizeof(buf), format, n);
|
||||
return _add(buf, pt, ptlim, 0);
|
||||
snprintf(buf, sizeof(buf), format, n);
|
||||
return _add(buf, pt, ptlim, 0);
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -699,8 +646,8 @@ _add(const char *str, char *pt, const char *const ptlim, int modifier)
|
|||
*/
|
||||
|
||||
static char *
|
||||
_yconv(const int a, const int b, const int convert_top, const int convert_yy,
|
||||
char *pt, const char *const ptlim, int modifier)
|
||||
_yconv(int a, int b, bool convert_top, bool convert_yy,
|
||||
char *pt, const char *ptlim, int modifier)
|
||||
{
|
||||
register int lead;
|
||||
register int trail;
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
struct tzhead {
|
||||
char tzh_magic[4]; /* TZ_MAGIC */
|
||||
char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */
|
||||
char tzh_reserved[15]; /* reserved--must be zero */
|
||||
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 */
|
||||
|
@ -62,13 +62,13 @@ struct tzhead {
|
|||
** 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,
|
||||
** tzh_ttisstdcnt (char)s indexed by type; if 1, transition
|
||||
** time is standard time, if 0,
|
||||
** 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 UT, if FALSE,
|
||||
** tzh_ttisgmtcnt (char)s indexed by type; if 1, transition
|
||||
** time is UT, if 0,
|
||||
** transition time is local time
|
||||
** if absent, transition times are
|
||||
** assumed to be local time
|
||||
|
@ -97,7 +97,7 @@ struct tzhead {
|
|||
*/
|
||||
|
||||
#ifndef TZ_MAX_TIMES
|
||||
#define TZ_MAX_TIMES 1200
|
||||
#define TZ_MAX_TIMES 2000
|
||||
#endif /* !defined TZ_MAX_TIMES */
|
||||
|
||||
#ifndef TZ_MAX_TYPES
|
||||
|
|
Loading…
Reference in a new issue