mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-28 11:57:28 +00:00
Import tzcode2004a.
Obtained from: ftp://elsie.nci.nih.gov/pub/tzcode2004a.tar.gz
This commit is contained in:
parent
7765d84cde
commit
dcd1bc204f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/tzcode/dist/; revision=130459
@ -1,11 +1,11 @@
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)asctime.c 7.7";
|
||||
static char elsieid[] = "@(#)asctime.c 7.9";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
@ -15,12 +15,13 @@ static char elsieid[] = "@(#)asctime.c 7.7";
|
||||
#include "tzfile.h"
|
||||
|
||||
/*
|
||||
** A la X3J11, with core dump avoidance.
|
||||
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12.
|
||||
*/
|
||||
|
||||
char *
|
||||
asctime(timeptr)
|
||||
asctime_r(timeptr, buf)
|
||||
register const struct tm * timeptr;
|
||||
char * buf;
|
||||
{
|
||||
static const char wday_name[][3] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
@ -29,15 +30,6 @@ register const struct tm * timeptr;
|
||||
"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;
|
||||
|
||||
@ -52,10 +44,31 @@ register const struct tm * timeptr;
|
||||
** "%.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",
|
||||
(void) sprintf(buf, "%.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;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
** A la X3J11, with core dump avoidance.
|
||||
*/
|
||||
|
||||
char *
|
||||
asctime(timeptr)
|
||||
register const struct tm * timeptr;
|
||||
{
|
||||
/*
|
||||
** 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];
|
||||
|
||||
return asctime_r(timeptr, result);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)difftime.c 7.7";
|
||||
static char elsieid[] = "@(#)difftime.c 7.9";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
@ -32,10 +32,16 @@ const time_t time0;
|
||||
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;
|
||||
{
|
||||
time_t tt;
|
||||
double d;
|
||||
long_double ld;
|
||||
|
||||
if (sizeof tt < sizeof d)
|
||||
return (double) time1 - (double) time0;
|
||||
if (sizeof tt < sizeof ld)
|
||||
return (long_double) time1 - (long_double) time0;
|
||||
}
|
||||
if (time1 < time0)
|
||||
return -difftime(time0, time1);
|
||||
/*
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)localtime.c 7.57";
|
||||
static char elsieid[] = "@(#)localtime.c 7.78";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
@ -59,12 +59,23 @@ static char wildabbr[] = "WILDABBR";
|
||||
|
||||
static const char gmt[] = "GMT";
|
||||
|
||||
/*
|
||||
** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
|
||||
** We default to US rules as of 1999-08-17.
|
||||
** POSIX 1003.1 section 8.1.1 says that the default DST rules are
|
||||
** implementation dependent; for historical reasons, US rules are a
|
||||
** common default.
|
||||
*/
|
||||
#ifndef TZDEFRULESTRING
|
||||
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
|
||||
#endif /* !defined TZDEFDST */
|
||||
|
||||
struct ttinfo { /* time type information */
|
||||
long tt_gmtoff; /* GMT offset in seconds */
|
||||
long tt_gmtoff; /* UTC offset in seconds */
|
||||
int tt_isdst; /* used to set tm_isdst */
|
||||
int tt_abbrind; /* abbreviation list index */
|
||||
int tt_ttisstd; /* TRUE if transition is std time */
|
||||
int tt_ttisgmt; /* TRUE if transition is GMT */
|
||||
int tt_ttisgmt; /* TRUE if transition is UTC */
|
||||
};
|
||||
|
||||
struct lsinfo { /* leap second information */
|
||||
@ -134,6 +145,10 @@ static time_t time2 P((struct tm *tmp,
|
||||
void(*funcp) P((const time_t *,
|
||||
long, struct tm*)),
|
||||
long offset, int * okayp));
|
||||
static time_t time2sub P((struct tm *tmp,
|
||||
void(*funcp) P((const time_t *,
|
||||
long, struct tm*)),
|
||||
long offset, int * okayp, int do_norm_secs));
|
||||
static void timesub P((const time_t * timep, long offset,
|
||||
const struct state * sp, struct tm * tmp));
|
||||
static int tmcomp P((const struct tm * atmp,
|
||||
@ -267,7 +282,7 @@ register struct state * const sp;
|
||||
/*
|
||||
** Section 4.9.1 of the C standard says that
|
||||
** "FILENAME_MAX expands to an integral constant expression
|
||||
** that is the sie needed for an array of char large enough
|
||||
** that is the size needed for an array of char large enough
|
||||
** to hold the longest file name string that the implementation
|
||||
** guarantees can be opened."
|
||||
*/
|
||||
@ -298,27 +313,23 @@ register struct state * const sp;
|
||||
}
|
||||
{
|
||||
struct tzhead * tzhp;
|
||||
char buf[sizeof *sp + sizeof *tzhp];
|
||||
union {
|
||||
struct tzhead tzhead;
|
||||
char buf[sizeof *sp + sizeof *tzhp];
|
||||
} u;
|
||||
int ttisstdcnt;
|
||||
int ttisgmtcnt;
|
||||
|
||||
i = read(fid, buf, sizeof buf);
|
||||
i = read(fid, u.buf, sizeof u.buf);
|
||||
if (close(fid) != 0)
|
||||
return -1;
|
||||
p = buf;
|
||||
p += sizeof tzhp->tzh_reserved;
|
||||
ttisstdcnt = (int) detzcode(p);
|
||||
p += 4;
|
||||
ttisgmtcnt = (int) detzcode(p);
|
||||
p += 4;
|
||||
sp->leapcnt = (int) detzcode(p);
|
||||
p += 4;
|
||||
sp->timecnt = (int) detzcode(p);
|
||||
p += 4;
|
||||
sp->typecnt = (int) detzcode(p);
|
||||
p += 4;
|
||||
sp->charcnt = (int) detzcode(p);
|
||||
p += 4;
|
||||
ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
|
||||
ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
|
||||
sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
|
||||
sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
|
||||
sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
|
||||
sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
|
||||
p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
|
||||
if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
|
||||
sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
|
||||
sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
|
||||
@ -326,7 +337,7 @@ register struct state * const sp;
|
||||
(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
|
||||
(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
|
||||
return -1;
|
||||
if (i - (p - buf) < sp->timecnt * 4 + /* ats */
|
||||
if (i - (p - u.buf) < sp->timecnt * 4 + /* ats */
|
||||
sp->timecnt + /* types */
|
||||
sp->typecnt * (4 + 2) + /* ttinfos */
|
||||
sp->charcnt + /* chars */
|
||||
@ -584,8 +595,8 @@ register struct rule * const rulep;
|
||||
}
|
||||
|
||||
/*
|
||||
** Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the
|
||||
** year, a rule, and the offset from GMT at the time that rule takes effect,
|
||||
** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
|
||||
** year, a rule, and the offset from UTC at the time that rule takes effect,
|
||||
** calculate the Epoch-relative time that rule takes effect.
|
||||
*/
|
||||
|
||||
@ -671,10 +682,10 @@ const long offset;
|
||||
}
|
||||
|
||||
/*
|
||||
** "value" is the Epoch-relative time of 00:00:00 GMT on the day in
|
||||
** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
|
||||
** question. To get the Epoch-relative time of the specified local
|
||||
** time on that day, add the transition time and the current offset
|
||||
** from GMT.
|
||||
** from UTC.
|
||||
*/
|
||||
return value + rulep->r_time + offset;
|
||||
}
|
||||
@ -708,15 +719,14 @@ const int lastditch;
|
||||
name += stdlen;
|
||||
if (stdlen >= sizeof sp->chars)
|
||||
stdlen = (sizeof sp->chars) - 1;
|
||||
stdoffset = 0;
|
||||
} else {
|
||||
name = getzname(name);
|
||||
stdlen = name - stdname;
|
||||
if (stdlen < 3)
|
||||
return -1;
|
||||
}
|
||||
if (*name == '\0')
|
||||
return -1; /* was "stdoffset = 0;" */
|
||||
else {
|
||||
if (*name == '\0')
|
||||
return -1;
|
||||
name = getoffset(name, &stdoffset);
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
@ -735,6 +745,8 @@ const int lastditch;
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
} else dstoffset = stdoffset - SECSPERHOUR;
|
||||
if (*name == '\0' && load_result != 0)
|
||||
name = TZDEFRULESTRING;
|
||||
if (*name == ',' || *name == ';') {
|
||||
struct rule start;
|
||||
struct rule end;
|
||||
@ -797,8 +809,6 @@ const int lastditch;
|
||||
|
||||
if (*name != '\0')
|
||||
return -1;
|
||||
if (load_result != 0)
|
||||
return -1;
|
||||
/*
|
||||
** Initial values of theirstdoffset and theirdstoffset.
|
||||
*/
|
||||
@ -872,6 +882,7 @@ const int lastditch;
|
||||
sp->ttis[1].tt_gmtoff = -dstoffset;
|
||||
sp->ttis[1].tt_isdst = TRUE;
|
||||
sp->ttis[1].tt_abbrind = stdlen + 1;
|
||||
sp->typecnt = 2;
|
||||
}
|
||||
} else {
|
||||
dstlen = 0;
|
||||
@ -884,7 +895,7 @@ const int lastditch;
|
||||
sp->charcnt = stdlen + 1;
|
||||
if (dstlen != 0)
|
||||
sp->charcnt += dstlen + 1;
|
||||
if (sp->charcnt > sizeof sp->chars)
|
||||
if ((size_t) sp->charcnt > sizeof sp->chars)
|
||||
return -1;
|
||||
cp = sp->chars;
|
||||
(void) strncpy(cp, stdname, stdlen);
|
||||
@ -944,9 +955,9 @@ tzset P((void))
|
||||
return;
|
||||
}
|
||||
|
||||
if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
|
||||
if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
|
||||
return;
|
||||
lcl_is_set = (strlen(name) < sizeof(lcl_TZname));
|
||||
lcl_is_set = strlen(name) < sizeof lcl_TZname;
|
||||
if (lcl_is_set)
|
||||
(void) strcpy(lcl_TZname, name);
|
||||
|
||||
@ -965,6 +976,8 @@ tzset P((void))
|
||||
*/
|
||||
lclptr->leapcnt = 0; /* so, we're off a little */
|
||||
lclptr->timecnt = 0;
|
||||
lclptr->typecnt = 0;
|
||||
lclptr->ttis[0].tt_isdst = 0;
|
||||
lclptr->ttis[0].tt_gmtoff = 0;
|
||||
lclptr->ttis[0].tt_abbrind = 0;
|
||||
(void) strcpy(lclptr->chars, gmt);
|
||||
@ -1039,6 +1052,19 @@ const time_t * const timep;
|
||||
return &tm;
|
||||
}
|
||||
|
||||
/*
|
||||
** Re-entrant version of localtime.
|
||||
*/
|
||||
|
||||
struct tm *
|
||||
localtime_r(timep, tm)
|
||||
const time_t * const timep;
|
||||
struct tm * tm;
|
||||
{
|
||||
localsub(timep, 0L, tm);
|
||||
return tm;
|
||||
}
|
||||
|
||||
/*
|
||||
** gmtsub is to gmtime as localsub is to localtime.
|
||||
*/
|
||||
@ -1061,7 +1087,7 @@ struct tm * const tmp;
|
||||
#ifdef TM_ZONE
|
||||
/*
|
||||
** Could get fancy here and deliver something such as
|
||||
** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero,
|
||||
** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
|
||||
** but this is no time for a treasure hunt.
|
||||
*/
|
||||
if (offset != 0)
|
||||
@ -1087,6 +1113,19 @@ const time_t * const timep;
|
||||
return &tm;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-entrant version of gmtime.
|
||||
*/
|
||||
|
||||
struct tm *
|
||||
gmtime_r(timep, tm)
|
||||
const time_t * const timep;
|
||||
struct tm * tm;
|
||||
{
|
||||
gmtsub(timep, 0L, tm);
|
||||
return tm;
|
||||
}
|
||||
|
||||
#ifdef STD_INSPIRED
|
||||
|
||||
struct tm *
|
||||
@ -1207,13 +1246,23 @@ const time_t * const timep;
|
||||
{
|
||||
/*
|
||||
** Section 4.12.3.2 of X3.159-1989 requires that
|
||||
** The ctime funciton converts the calendar time pointed to by timer
|
||||
** The ctime function converts the calendar time pointed to by timer
|
||||
** to local time in the form of a string. It is equivalent to
|
||||
** asctime(localtime(timer))
|
||||
*/
|
||||
return asctime(localtime(timep));
|
||||
}
|
||||
|
||||
char *
|
||||
ctime_r(timep, buf)
|
||||
const time_t * const timep;
|
||||
char * buf;
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
return asctime_r(localtime_r(timep, &tm), buf);
|
||||
}
|
||||
|
||||
/*
|
||||
** Adapted from code provided by Robert Elz, who writes:
|
||||
** The "best" way to do mktime I think is based on an idea of Bob
|
||||
@ -1276,11 +1325,12 @@ register const struct tm * const btmp;
|
||||
}
|
||||
|
||||
static time_t
|
||||
time2(tmp, funcp, offset, okayp)
|
||||
time2sub(tmp, funcp, offset, okayp, do_norm_secs)
|
||||
struct tm * const tmp;
|
||||
void (* const funcp) P((const time_t*, long, struct tm*));
|
||||
const long offset;
|
||||
int * const okayp;
|
||||
const int do_norm_secs;
|
||||
{
|
||||
register const struct state * sp;
|
||||
register int dir;
|
||||
@ -1293,6 +1343,11 @@ int * const okayp;
|
||||
|
||||
*okayp = FALSE;
|
||||
yourtm = *tmp;
|
||||
if (do_norm_secs) {
|
||||
if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
|
||||
SECSPERMIN))
|
||||
return WRONG;
|
||||
}
|
||||
if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
|
||||
return WRONG;
|
||||
if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
|
||||
@ -1330,7 +1385,9 @@ int * const okayp;
|
||||
}
|
||||
if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))
|
||||
return WRONG;
|
||||
if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
|
||||
if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
|
||||
saved_seconds = 0;
|
||||
else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
|
||||
/*
|
||||
** We can't set tm_sec to 0, because that might push the
|
||||
** time below the minimum representable time.
|
||||
@ -1421,6 +1478,24 @@ int * const okayp;
|
||||
return t;
|
||||
}
|
||||
|
||||
static time_t
|
||||
time2(tmp, funcp, offset, okayp)
|
||||
struct tm * const tmp;
|
||||
void (* const funcp) P((const time_t*, long, struct tm*));
|
||||
const long offset;
|
||||
int * const okayp;
|
||||
{
|
||||
time_t t;
|
||||
|
||||
/*
|
||||
** First try without normalization of seconds
|
||||
** (in case tm_sec contains a value associated with a leap second).
|
||||
** If that fails, try with normalization of seconds.
|
||||
*/
|
||||
t = time2sub(tmp, funcp, offset, okayp, FALSE);
|
||||
return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
|
||||
}
|
||||
|
||||
static time_t
|
||||
time1(tmp, funcp, offset)
|
||||
struct tm * const tmp;
|
||||
@ -1430,6 +1505,11 @@ const long offset;
|
||||
register time_t t;
|
||||
register const struct state * sp;
|
||||
register int samei, otheri;
|
||||
register int sameind, otherind;
|
||||
register int i;
|
||||
register int nseen;
|
||||
int seen[TZ_MAX_TYPES];
|
||||
int types[TZ_MAX_TYPES];
|
||||
int okay;
|
||||
|
||||
if (tmp->tm_isdst > 1)
|
||||
@ -1463,10 +1543,20 @@ const long offset;
|
||||
if (sp == NULL)
|
||||
return WRONG;
|
||||
#endif /* defined ALL_STATE */
|
||||
for (samei = sp->typecnt - 1; samei >= 0; --samei) {
|
||||
for (i = 0; i < sp->typecnt; ++i)
|
||||
seen[i] = FALSE;
|
||||
nseen = 0;
|
||||
for (i = sp->timecnt - 1; i >= 0; --i)
|
||||
if (!seen[sp->types[i]]) {
|
||||
seen[sp->types[i]] = TRUE;
|
||||
types[nseen++] = sp->types[i];
|
||||
}
|
||||
for (sameind = 0; sameind < nseen; ++sameind) {
|
||||
samei = types[sameind];
|
||||
if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
|
||||
continue;
|
||||
for (otheri = sp->typecnt - 1; otheri >= 0; --otheri) {
|
||||
for (otherind = 0; otherind < nseen; ++otherind) {
|
||||
otheri = types[otherind];
|
||||
if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
|
||||
continue;
|
||||
tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
|
||||
@ -1548,7 +1638,7 @@ struct tm * const tmp;
|
||||
|
||||
/*
|
||||
** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
|
||||
** shall correspond to "Wed Dec 31 23:59:59 GMT 1986", which
|
||||
** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
|
||||
** is not the case if we are accounting for leap seconds.
|
||||
** So, we provide the following conversion routines for use
|
||||
** when exchanging timestamps with POSIX conforming systems.
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char privatehid[] = "@(#)private.h 7.43";
|
||||
static char privatehid[] = "@(#)private.h 7.53";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
@ -38,14 +38,30 @@ static char privatehid[] = "@(#)private.h 7.43";
|
||||
#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_STRERROR
|
||||
#define HAVE_STRERROR 0
|
||||
#define HAVE_STRERROR 1
|
||||
#endif /* !defined HAVE_STRERROR */
|
||||
|
||||
#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 */
|
||||
@ -58,6 +74,11 @@ static char privatehid[] = "@(#)private.h 7.43";
|
||||
#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
|
||||
*/
|
||||
@ -74,6 +95,17 @@ static char privatehid[] = "@(#)private.h 7.43";
|
||||
#include "libintl.h"
|
||||
#endif /* HAVE_GETTEXT - 0 */
|
||||
|
||||
#if HAVE_SYS_WAIT_H - 0
|
||||
#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
|
||||
#endif /* HAVE_SYS_WAIT_H - 0 */
|
||||
|
||||
#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 - 0
|
||||
#include "unistd.h" /* for F_OK and R_OK */
|
||||
#endif /* HAVE_UNISTD_H - 0 */
|
||||
@ -94,16 +126,6 @@ static char privatehid[] = "@(#)private.h 7.43";
|
||||
** 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.
|
||||
*/
|
||||
@ -172,6 +194,19 @@ extern int unlink P((const char * filename));
|
||||
extern int errno;
|
||||
#endif /* !defined errno */
|
||||
|
||||
/*
|
||||
** Private function declarations.
|
||||
*/
|
||||
char * icalloc P((int nelem, int elsize));
|
||||
char * icatalloc P((char * old, const char * new));
|
||||
char * icpyalloc P((const char * string));
|
||||
char * imalloc P((int n));
|
||||
void * irealloc P((void * pointer, int size));
|
||||
void icfree P((char * pointer));
|
||||
void ifree P((char * pointer));
|
||||
char * scheck P((const char *string, const char *format));
|
||||
|
||||
|
||||
/*
|
||||
** Finally, some convenience items.
|
||||
*/
|
||||
@ -200,7 +235,7 @@ extern int errno;
|
||||
** add one more for a minus sign if the type is signed.
|
||||
*/
|
||||
#define INT_STRLEN_MAXIMUM(type) \
|
||||
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 100 + 1 + TYPE_SIGNED(type))
|
||||
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type))
|
||||
#endif /* !defined INT_STRLEN_MAXIMUM */
|
||||
|
||||
/*
|
||||
@ -245,8 +280,15 @@ extern int errno;
|
||||
#define TZ_DOMAIN "tz"
|
||||
#endif /* !defined TZ_DOMAIN */
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#undef asctime_r
|
||||
#undef ctime_r
|
||||
char *asctime_r P((struct tm const *, char *));
|
||||
char *ctime_r P((time_t const *, char *));
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
/*
|
||||
** UNIX was a registered trademark of UNIX System Laboratories in 1993.
|
||||
** UNIX was a registered trademark of The Open Group in 2003.
|
||||
*/
|
||||
|
||||
#endif /* !defined PRIVATE_H */
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)strftime.c 7.47";
|
||||
static char elsieid[] = "@(#)strftime.c 7.64";
|
||||
/*
|
||||
** Based on the UCB version with the ID appearing below.
|
||||
** This is ANSIish only when "multibyte character == plain character".
|
||||
@ -38,10 +38,10 @@ static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89";
|
||||
#include "locale.h"
|
||||
|
||||
struct lc_time_T {
|
||||
const char * mon[12];
|
||||
const char * month[12];
|
||||
const char * wday[7];
|
||||
const char * weekday[7];
|
||||
const char * mon[MONSPERYEAR];
|
||||
const char * month[MONSPERYEAR];
|
||||
const char * wday[DAYSPERWEEK];
|
||||
const char * weekday[DAYSPERWEEK];
|
||||
const char * X_fmt;
|
||||
const char * x_fmt;
|
||||
const char * c_fmt;
|
||||
@ -80,8 +80,7 @@ static const struct lc_time_T C_time_locale = {
|
||||
|
||||
/*
|
||||
** x_fmt
|
||||
** Since the C language standard calls for
|
||||
** "date, using locale's date format," anything goes.
|
||||
** C99 requires this format.
|
||||
** Using just numbers (as here) makes Quakers happier;
|
||||
** it's also compatible with SVR4.
|
||||
*/
|
||||
@ -89,11 +88,13 @@ static const struct lc_time_T C_time_locale = {
|
||||
|
||||
/*
|
||||
** c_fmt
|
||||
** C99 requires this format.
|
||||
** Previously this code used "%D %X", but we now conform to C99.
|
||||
** Note that
|
||||
** "%a %b %d %H:%M:%S %Y"
|
||||
** "%a %b %d %H:%M:%S %Y"
|
||||
** is used by Solaris 2.3.
|
||||
*/
|
||||
"%D %X", /* %m/%d/%y %H:%M:%S */
|
||||
"%a %b %e %T %Y",
|
||||
|
||||
/* am */
|
||||
"AM",
|
||||
@ -107,12 +108,22 @@ static const struct lc_time_T C_time_locale = {
|
||||
|
||||
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 * _fmt P((const char *, const struct tm *, char *, const char *, int *));
|
||||
|
||||
size_t strftime P((char *, size_t, const char *, const struct tm *));
|
||||
|
||||
extern char * tzname[];
|
||||
|
||||
#ifndef YEAR_2000_NAME
|
||||
#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
|
||||
#endif /* !defined YEAR_2000_NAME */
|
||||
|
||||
|
||||
#define IN_NONE 0
|
||||
#define IN_SOME 1
|
||||
#define IN_THIS 2
|
||||
#define IN_ALL 3
|
||||
|
||||
size_t
|
||||
strftime(s, maxsize, format, t)
|
||||
char * const s;
|
||||
@ -121,12 +132,30 @@ const char * const format;
|
||||
const struct tm * const t;
|
||||
{
|
||||
char * p;
|
||||
int warn;
|
||||
|
||||
tzset();
|
||||
#ifdef LOCALE_HOME
|
||||
localebuf.mon[0] = 0;
|
||||
#endif /* defined LOCALE_HOME */
|
||||
p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize);
|
||||
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");
|
||||
if (format == NULL)
|
||||
(void) fprintf(stderr, "NULL strftime format ");
|
||||
else (void) fprintf(stderr, "strftime format \"%s\" ",
|
||||
format);
|
||||
(void) fprintf(stderr, "yields only two digits of years in ");
|
||||
if (warn == IN_SOME)
|
||||
(void) 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");
|
||||
}
|
||||
#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
|
||||
if (p == s + maxsize)
|
||||
return 0;
|
||||
*p = '\0';
|
||||
@ -134,11 +163,12 @@ const struct tm * const t;
|
||||
}
|
||||
|
||||
static char *
|
||||
_fmt(format, t, pt, ptlim)
|
||||
_fmt(format, t, pt, ptlim, warnp)
|
||||
const char * format;
|
||||
const struct tm * const t;
|
||||
char * pt;
|
||||
const char * const ptlim;
|
||||
int * warnp;
|
||||
{
|
||||
for ( ; *format; ++format) {
|
||||
if (*format == '%') {
|
||||
@ -148,23 +178,27 @@ const char * const ptlim;
|
||||
--format;
|
||||
break;
|
||||
case 'A':
|
||||
pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ?
|
||||
pt = _add((t->tm_wday < 0 ||
|
||||
t->tm_wday >= DAYSPERWEEK) ?
|
||||
"?" : Locale->weekday[t->tm_wday],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'a':
|
||||
pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ?
|
||||
pt = _add((t->tm_wday < 0 ||
|
||||
t->tm_wday >= DAYSPERWEEK) ?
|
||||
"?" : Locale->wday[t->tm_wday],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'B':
|
||||
pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ?
|
||||
pt = _add((t->tm_mon < 0 ||
|
||||
t->tm_mon >= MONSPERYEAR) ?
|
||||
"?" : Locale->month[t->tm_mon],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'b':
|
||||
case 'h':
|
||||
pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ?
|
||||
pt = _add((t->tm_mon < 0 ||
|
||||
t->tm_mon >= MONSPERYEAR) ?
|
||||
"?" : Locale->mon[t->tm_mon],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
@ -174,16 +208,24 @@ const char * const ptlim;
|
||||
** _fmt("%a %b %e %X %Y", t);
|
||||
** ...whereas now POSIX 1003.2 calls for
|
||||
** something completely different.
|
||||
** (ado, 5/24/93)
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'c':
|
||||
pt = _fmt(Locale->c_fmt, t, pt, ptlim);
|
||||
{
|
||||
int warn2 = IN_SOME;
|
||||
|
||||
pt = _fmt(Locale->c_fmt, t, pt, ptlim, warnp);
|
||||
if (warn2 == IN_ALL)
|
||||
warn2 = IN_THIS;
|
||||
if (warn2 > *warnp)
|
||||
*warnp = warn2;
|
||||
}
|
||||
continue;
|
||||
case 'D':
|
||||
pt = _fmt("%m/%d/%y", t, pt, ptlim);
|
||||
pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'd':
|
||||
pt = _conv(t->tm_mday, "%02d", pt, ptlim);
|
||||
@ -191,20 +233,21 @@ const char * const ptlim;
|
||||
case 'E':
|
||||
case 'O':
|
||||
/*
|
||||
** POSIX locale extensions, a la
|
||||
** Arnold Robbins' strftime version 3.0.
|
||||
** C99 locale modifiers.
|
||||
** The sequences
|
||||
** %Ec %EC %Ex %Ey %EY
|
||||
** %Ec %EC %Ex %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 'F':
|
||||
pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'H':
|
||||
pt = _conv(t->tm_hour, "%02d", pt, ptlim);
|
||||
continue;
|
||||
@ -225,7 +268,7 @@ const char * const ptlim;
|
||||
** match SunOS 4.1.1 and Arnold Robbins'
|
||||
** strftime version 3.0. That is, "%k" and
|
||||
** "%l" have been swapped.
|
||||
** (ado, 5/24/93)
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv(t->tm_hour, "%2d", pt, ptlim);
|
||||
continue;
|
||||
@ -245,7 +288,7 @@ const char * const ptlim;
|
||||
** 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)
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv((t->tm_hour % 12) ?
|
||||
(t->tm_hour % 12) : 12,
|
||||
@ -261,16 +304,16 @@ const char * const ptlim;
|
||||
pt = _add("\n", pt, ptlim);
|
||||
continue;
|
||||
case 'p':
|
||||
pt = _add((t->tm_hour >= 12) ?
|
||||
pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
|
||||
Locale->pm :
|
||||
Locale->am,
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'R':
|
||||
pt = _fmt("%H:%M", t, pt, ptlim);
|
||||
pt = _fmt("%H:%M", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'r':
|
||||
pt = _fmt("%I:%M:%S %p", t, pt, ptlim);
|
||||
pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'S':
|
||||
pt = _conv(t->tm_sec, "%02d", pt, ptlim);
|
||||
@ -293,13 +336,14 @@ const char * const ptlim;
|
||||
}
|
||||
continue;
|
||||
case 'T':
|
||||
pt = _fmt("%H:%M:%S", t, pt, ptlim);
|
||||
pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 't':
|
||||
pt = _add("\t", pt, ptlim);
|
||||
continue;
|
||||
case 'U':
|
||||
pt = _conv((t->tm_yday + 7 - t->tm_wday) / 7,
|
||||
pt = _conv((t->tm_yday + DAYSPERWEEK -
|
||||
t->tm_wday) / DAYSPERWEEK,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'u':
|
||||
@ -307,9 +351,10 @@ const char * const ptlim;
|
||||
** From Arnold Robbins' strftime version 3.0:
|
||||
** "ISO 8601: Weekday as a decimal number
|
||||
** [1 (Monday) - 7]"
|
||||
** (ado, 5/24/93)
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday,
|
||||
pt = _conv((t->tm_wday == 0) ?
|
||||
DAYSPERWEEK : t->tm_wday,
|
||||
"%d", pt, ptlim);
|
||||
continue;
|
||||
case 'V': /* ISO 8601 week number */
|
||||
@ -381,16 +426,20 @@ const char * const ptlim;
|
||||
DAYSPERNYEAR;
|
||||
}
|
||||
#ifdef XPG4_1994_04_09
|
||||
if (w == 52 && t->tm_mon == TM_JANUARY)
|
||||
if ((w == 52
|
||||
&& t->tm_mon == TM_JANUARY)
|
||||
|| (w == 1
|
||||
&& t->tm_mon == TM_DECEMBER))
|
||||
w = 53;
|
||||
#endif /* defined XPG4_1994_04_09 */
|
||||
if (*format == 'V')
|
||||
pt = _conv(w, "%02d",
|
||||
pt, ptlim);
|
||||
else if (*format == 'G')
|
||||
pt = _conv(year, "%02d",
|
||||
else if (*format == 'g') {
|
||||
*warnp = IN_ALL;
|
||||
pt = _conv(year % 100, "%02d",
|
||||
pt, ptlim);
|
||||
else pt = _conv(year, "%04d",
|
||||
} else pt = _conv(year, "%04d",
|
||||
pt, ptlim);
|
||||
}
|
||||
continue;
|
||||
@ -398,26 +447,36 @@ const char * const ptlim;
|
||||
/*
|
||||
** From Arnold Robbins' strftime version 3.0:
|
||||
** "date as dd-bbb-YYYY"
|
||||
** (ado, 5/24/93)
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _fmt("%e-%b-%Y", t, pt, ptlim);
|
||||
pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'W':
|
||||
pt = _conv((t->tm_yday + 7 -
|
||||
pt = _conv((t->tm_yday + DAYSPERWEEK -
|
||||
(t->tm_wday ?
|
||||
(t->tm_wday - 1) : 6)) / 7,
|
||||
(t->tm_wday - 1) :
|
||||
(DAYSPERWEEK - 1))) / DAYSPERWEEK,
|
||||
"%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);
|
||||
pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'x':
|
||||
pt = _fmt(Locale->x_fmt, t, pt, ptlim);
|
||||
{
|
||||
int warn2 = IN_SOME;
|
||||
|
||||
pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
|
||||
if (warn2 == IN_ALL)
|
||||
warn2 = IN_THIS;
|
||||
if (warn2 > *warnp)
|
||||
*warnp = warn2;
|
||||
}
|
||||
continue;
|
||||
case 'y':
|
||||
*warnp = IN_ALL;
|
||||
pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
@ -431,20 +490,77 @@ const char * const ptlim;
|
||||
pt = _add(t->TM_ZONE, pt, ptlim);
|
||||
else
|
||||
#endif /* defined TM_ZONE */
|
||||
if (t->tm_isdst == 0 || t->tm_isdst == 1) {
|
||||
pt = _add(tzname[t->tm_isdst],
|
||||
if (t->tm_isdst >= 0)
|
||||
pt = _add(tzname[t->tm_isdst != 0],
|
||||
pt, ptlim);
|
||||
} else pt = _add("?", pt, ptlim);
|
||||
/*
|
||||
** C99 says that %Z must be replaced by the
|
||||
** empty string if the time zone is not
|
||||
** determinable.
|
||||
*/
|
||||
continue;
|
||||
case 'z':
|
||||
{
|
||||
int diff;
|
||||
char const * sign;
|
||||
|
||||
if (t->tm_isdst < 0)
|
||||
continue;
|
||||
#ifdef TM_GMTOFF
|
||||
diff = t->TM_GMTOFF;
|
||||
#else /* !defined TM_GMTOFF */
|
||||
/*
|
||||
** C99 says that the UTC offset must
|
||||
** be computed by looking only at
|
||||
** tm_isdst. This requirement is
|
||||
** incorrect, since it means the code
|
||||
** must rely on magic (in this case
|
||||
** altzone and timezone), and the
|
||||
** magic might not have the correct
|
||||
** offset. Doing things correctly is
|
||||
** tricky and requires disobeying C99;
|
||||
** see GNU C strftime for details.
|
||||
** For now, punt and conform to the
|
||||
** standard, even though it's incorrect.
|
||||
**
|
||||
** C99 says that %z must be replaced by the
|
||||
** empty string if the time zone is not
|
||||
** determinable, so output nothing if the
|
||||
** appropriate variables are not available.
|
||||
*/
|
||||
if (t->tm_isdst == 0)
|
||||
#ifdef USG_COMPAT
|
||||
diff = -timezone;
|
||||
#else /* !defined USG_COMPAT */
|
||||
continue;
|
||||
#endif /* !defined USG_COMPAT */
|
||||
else
|
||||
#ifdef ALTZONE
|
||||
diff = -altzone;
|
||||
#else /* !defined ALTZONE */
|
||||
continue;
|
||||
#endif /* !defined ALTZONE */
|
||||
#endif /* !defined TM_GMTOFF */
|
||||
if (diff < 0) {
|
||||
sign = "-";
|
||||
diff = -diff;
|
||||
} else sign = "+";
|
||||
pt = _add(sign, pt, ptlim);
|
||||
diff /= 60;
|
||||
pt = _conv((diff/60)*100 + diff%60,
|
||||
"%04d", pt, ptlim);
|
||||
}
|
||||
continue;
|
||||
case '+':
|
||||
pt = _fmt(Locale->date_fmt, t, pt, ptlim);
|
||||
pt = _fmt(Locale->date_fmt, t, pt, ptlim,
|
||||
warnp);
|
||||
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.
|
||||
*/
|
||||
** 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;
|
||||
}
|
||||
@ -487,7 +603,6 @@ _loc P((void))
|
||||
static const char locale_home[] = LOCALE_HOME;
|
||||
static const char lc_time[] = "LC_TIME";
|
||||
static char * locale_buf;
|
||||
static char locale_buf_C[] = "C";
|
||||
|
||||
int fd;
|
||||
int oldsun; /* "...ain't got nothin' to do..." */
|
||||
@ -525,8 +640,8 @@ _loc P((void))
|
||||
** Slurp the locale file into the cache.
|
||||
*/
|
||||
namesize = strlen(name) + 1;
|
||||
if (sizeof(filename) <
|
||||
sizeof(locale_home) + namesize + sizeof(lc_time))
|
||||
if (sizeof filename <
|
||||
((sizeof locale_home) + namesize + (sizeof lc_time)))
|
||||
goto no_locale;
|
||||
oldsun = 0;
|
||||
(void) sprintf(filename, "%s/%s/%s", locale_home, name, lc_time);
|
||||
@ -548,8 +663,7 @@ _loc P((void))
|
||||
goto bad_locale;
|
||||
bufsize = namesize + st.st_size;
|
||||
locale_buf = NULL;
|
||||
lbuf = (lbuf == NULL || lbuf == locale_buf_C) ?
|
||||
malloc(bufsize) : realloc(lbuf, bufsize);
|
||||
lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize);
|
||||
if (lbuf == NULL)
|
||||
goto bad_locale;
|
||||
(void) strcpy(lbuf, name);
|
||||
@ -598,7 +712,7 @@ _loc P((void))
|
||||
(void) close(fd);
|
||||
no_locale:
|
||||
localebuf = C_time_locale;
|
||||
locale_buf = locale_buf_C;
|
||||
locale_buf = NULL;
|
||||
return &localebuf;
|
||||
}
|
||||
#endif /* defined LOCALE_HOME */
|
||||
|
Loading…
Reference in New Issue
Block a user