Updated to tzcode2005j.tar.gz

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13561 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2005-07-08 23:49:29 +00:00
parent e6aa054a8f
commit b1c123994c
7 changed files with 287 additions and 134 deletions
+17 -14
View File
@@ -25,6 +25,8 @@ static char privatehid[] = "@(#)private.h 7.55";
#endif /* !defined NOID */ #endif /* !defined NOID */
#endif /* !defined lint */ #endif /* !defined lint */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
/* /*
** Defaults for preprocessor symbols. ** 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_ADJTIME=0'.
@@ -91,13 +93,13 @@ static char privatehid[] = "@(#)private.h 7.55";
#include "time.h" #include "time.h"
#include "stdlib.h" #include "stdlib.h"
#if HAVE_GETTEXT - 0 #if HAVE_GETTEXT
#include "libintl.h" #include "libintl.h"
#endif /* HAVE_GETTEXT - 0 */ #endif /* HAVE_GETTEXT */
#if HAVE_SYS_WAIT_H - 0 #if HAVE_SYS_WAIT_H
#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */ #include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
#endif /* HAVE_SYS_WAIT_H - 0 */ #endif /* HAVE_SYS_WAIT_H */
#ifndef WIFEXITED #ifndef WIFEXITED
#define WIFEXITED(status) (((status) & 0xff) == 0) #define WIFEXITED(status) (((status) & 0xff) == 0)
@@ -106,20 +108,20 @@ static char privatehid[] = "@(#)private.h 7.55";
#define WEXITSTATUS(status) (((status) >> 8) & 0xff) #define WEXITSTATUS(status) (((status) >> 8) & 0xff)
#endif /* !defined WEXITSTATUS */ #endif /* !defined WEXITSTATUS */
#if HAVE_UNISTD_H - 0 #if HAVE_UNISTD_H
#include "unistd.h" /* for F_OK and R_OK */ #include "unistd.h" /* for F_OK and R_OK */
#endif /* HAVE_UNISTD_H - 0 */ #endif /* HAVE_UNISTD_H */
#if !(HAVE_UNISTD_H - 0) #if !HAVE_UNISTD_H
#ifndef F_OK #ifndef F_OK
#define F_OK 0 #define F_OK 0
#endif /* !defined F_OK */ #endif /* !defined F_OK */
#ifndef R_OK #ifndef R_OK
#define R_OK 4 #define R_OK 4
#endif /* !defined R_OK */ #endif /* !defined R_OK */
#endif /* !(HAVE_UNISTD_H - 0) */ #endif /* !HAVE_UNISTD_H */
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */ /* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
#define is_digit(c) ((unsigned)(c) - '0' <= 9) #define is_digit(c) ((unsigned)(c) - '0' <= 9)
/* /*
@@ -216,7 +218,7 @@ char * imalloc P((int n));
void * irealloc P((void * pointer, int size)); void * irealloc P((void * pointer, int size));
void icfree P((char * pointer)); void icfree P((char * pointer));
void ifree P((char * pointer)); void ifree P((char * pointer));
char * scheck P((const char *string, const char *format)); char * scheck P((const char *string, char *format));
/* /*
** Finally, some convenience items. ** Finally, some convenience items.
@@ -255,7 +257,8 @@ char * scheck P((const char *string, const char *format));
** add one more for a minus sign if the type is signed. ** add one more for a minus sign if the type is signed.
*/ */
#define INT_STRLEN_MAXIMUM(type) \ #define INT_STRLEN_MAXIMUM(type) \
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type)) ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
1 + TYPE_SIGNED(type))
#endif /* !defined INT_STRLEN_MAXIMUM */ #endif /* !defined INT_STRLEN_MAXIMUM */
/* /*
@@ -289,11 +292,11 @@ char * scheck P((const char *string, const char *format));
*/ */
#ifndef _ #ifndef _
#if HAVE_GETTEXT - 0 #if HAVE_GETTEXT
#define _(msgid) gettext(msgid) #define _(msgid) gettext(msgid)
#else /* !(HAVE_GETTEXT - 0) */ #else /* !HAVE_GETTEXT */
#define _(msgid) msgid #define _(msgid) msgid
#endif /* !(HAVE_GETTEXT - 0) */ #endif /* !HAVE_GETTEXT */
#endif /* !defined _ */ #endif /* !defined _ */
#ifndef TZ_DOMAIN #ifndef TZ_DOMAIN
+2 -24
View File
@@ -21,7 +21,7 @@
#ifndef lint #ifndef lint
#ifndef NOID #ifndef NOID
static char tzfilehid[] = "@(#)tzfile.h 7.16"; static char tzfilehid[] = "@(#)tzfile.h 7.17";
#endif /* !defined NOID */ #endif /* !defined NOID */
#endif /* !defined lint */ #endif /* !defined lint */
@@ -48,7 +48,7 @@ static char tzfilehid[] = "@(#)tzfile.h 7.16";
#define TZ_MAGIC "TZif" #define TZ_MAGIC "TZif"
struct tzhead { struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */ char tzh_magic[4]; /* TZ_MAGIC */
char tzh_reserved[16]; /* reserved for future use */ char tzh_reserved[16]; /* reserved for future use */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
@@ -172,26 +172,4 @@ struct tzhead {
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) #define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
#ifndef USG
/*
** Use of the underscored variants may cause problems if you move your code to
** certain System-V-based systems; for maximum portability, use the
** underscore-free variants. The underscored variants are provided for
** backward compatibility only; they may disappear from future versions of
** this file.
*/
#define SECS_PER_MIN SECSPERMIN
#define MINS_PER_HOUR MINSPERHOUR
#define HOURS_PER_DAY HOURSPERDAY
#define DAYS_PER_WEEK DAYSPERWEEK
#define DAYS_PER_NYEAR DAYSPERNYEAR
#define DAYS_PER_LYEAR DAYSPERLYEAR
#define SECS_PER_HOUR SECSPERHOUR
#define SECS_PER_DAY SECSPERDAY
#define MONS_PER_YEAR MONSPERYEAR
#endif /* !defined USG */
#endif /* !defined TZFILE_H */ #endif /* !defined TZFILE_H */
+2 -2
View File
@@ -1,6 +1,6 @@
#ifndef lint #ifndef lint
#ifndef NOID #ifndef NOID
static char elsieid[] = "@(#)scheck.c 8.15"; static char elsieid[] = "@(#)scheck.c 8.16";
#endif /* !defined lint */ #endif /* !defined lint */
#endif /* !defined NOID */ #endif /* !defined NOID */
@@ -11,7 +11,7 @@ static char elsieid[] = "@(#)scheck.c 8.15";
char * char *
scheck(string, format) scheck(string, format)
const char * const string; const char * const string;
const char * const format; char * const format;
{ {
register char * fbuf; register char * fbuf;
register const char * fp; register const char * fp;
+53 -9
View File
@@ -1,4 +1,4 @@
static char elsieid[] = "@(#)zdump.c 7.61"; static char elsieid[] = "@(#)zdump.c 7.65";
/* /*
** This code has been made independent of the rest of the time ** This code has been made independent of the rest of the time
@@ -144,8 +144,10 @@ static time_t absolute_min_time;
static time_t absolute_max_time; static time_t absolute_max_time;
static size_t longest; static size_t longest;
static char * progname; static char * progname;
static int warned;
static char * abbr P((struct tm * tmp)); static char * abbr P((struct tm * tmp));
static void abbrok P((const char * abbr, const char * zone));
static long delta P((struct tm * newp, struct tm * oldp)); static long delta P((struct tm * newp, struct tm * oldp));
static void dumptime P((const struct tm * tmp)); static void dumptime P((const struct tm * tmp));
static time_t hunt P((char * name, time_t lot, time_t hit)); static time_t hunt P((char * name, time_t lot, time_t hit));
@@ -175,12 +177,13 @@ time_t * tp;
(void) fprintf(stderr, "\n%s: ", progname); (void) fprintf(stderr, "\n%s: ", progname);
(void) fprintf(stderr, tformat(), *tp); (void) fprintf(stderr, tformat(), *tp);
(void) fprintf(stderr, " ->"); (void) fprintf(stderr, " ->");
(void) fprintf(stderr, " sec %d", tmp->tm_sec); (void) fprintf(stderr, " year=%d", tmp->tm_year);
(void) fprintf(stderr, " min %d", tmp->tm_min); (void) fprintf(stderr, " mon=%d", tmp->tm_mon);
(void) fprintf(stderr, " hour %d", tmp->tm_hour); (void) fprintf(stderr, " mday=%d", tmp->tm_mday);
(void) fprintf(stderr, " mday %d", tmp->tm_mday); (void) fprintf(stderr, " hour=%d", tmp->tm_hour);
(void) fprintf(stderr, " mon %d", tmp->tm_mon); (void) fprintf(stderr, " min=%d", tmp->tm_min);
(void) fprintf(stderr, " year %d", tmp->tm_year); (void) fprintf(stderr, " sec=%d", tmp->tm_sec);
(void) fprintf(stderr, " isdst=%d", tmp->tm_isdst);
(void) fprintf(stderr, " -> "); (void) fprintf(stderr, " -> ");
(void) fprintf(stderr, tformat(), t); (void) fprintf(stderr, tformat(), t);
(void) fprintf(stderr, "\n"); (void) fprintf(stderr, "\n");
@@ -190,6 +193,44 @@ time_t * tp;
} }
#endif /* !defined TYPECHECK */ #endif /* !defined TYPECHECK */
static void
abbrok(abbr, zone)
const char * const abbr;
const char * const zone;
{
register int i;
register const char * cp;
register char * wp;
if (warned)
return;
cp = abbr;
wp = NULL;
while (isascii(*cp) && isalpha(*cp))
++cp;
if (cp - abbr == 0)
wp = _("lacks alphabetic at start");
if (cp - abbr < 3)
wp = _("has fewer than 3 alphabetics");
if (cp - abbr > 6)
wp = _("has more than 6 alphabetics");
if (wp == NULL && (*cp == '+' || *cp == '-')) {
++cp;
if (isascii(*cp) && isdigit(*cp))
if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
++cp;
}
if (*cp != '\0')
wp = _("differs from POSIX standard");
if (wp == NULL)
return;
(void) fflush(stdout);
(void) fprintf(stderr,
"%s: warning: zone \"%s\" abbreviation \"%s\" %s\n",
progname, zone, abbr, wp);
warned = TRUE;
}
int int
main(argc, argv) main(argc, argv)
int argc; int argc;
@@ -215,7 +256,7 @@ char * argv[];
INITIALIZE(cutlotime); INITIALIZE(cutlotime);
INITIALIZE(cuthitime); INITIALIZE(cuthitime);
#if HAVE_GETTEXT #if HAVE_GETTEXT
(void) setlocale(LC_MESSAGES, ""); (void) setlocale(LC_ALL, "");
#ifdef TZ_DOMAINDIR #ifdef TZ_DOMAINDIR
(void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
#endif /* defined TEXTDOMAINDIR */ #endif /* defined TEXTDOMAINDIR */
@@ -296,6 +337,7 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
show(argv[i], now, FALSE); show(argv[i], now, FALSE);
continue; continue;
} }
warned = FALSE;
t = absolute_min_time; t = absolute_min_time;
show(argv[i], t, TRUE); show(argv[i], t, TRUE);
t += SECSPERHOUR * HOURSPERDAY; t += SECSPERHOUR * HOURSPERDAY;
@@ -318,7 +360,7 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
newtmp = localtime(&newt); newtmp = localtime(&newt);
if (newtmp != NULL) if (newtmp != NULL)
newtm = *newtmp; newtm = *newtmp;
if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) : if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) :
(delta(&newtm, &tm) != (newt - t) || (delta(&newtm, &tm) != (newt - t) ||
newtm.tm_isdst != tm.tm_isdst || newtm.tm_isdst != tm.tm_isdst ||
strcmp(abbr(&newtm), buf) != 0)) { strcmp(abbr(&newtm), buf) != 0)) {
@@ -526,6 +568,8 @@ int v;
} }
} }
(void) printf("\n"); (void) printf("\n");
if (tmp != NULL && *abbr(tmp) != '\0')
abbrok(abbr(tmp), zone);
} }
static char * static char *
+107 -48
View File
@@ -1,4 +1,4 @@
static char elsieid[] = "@(#)zic.c 7.118"; static char elsieid[] = "@(#)zic.c 7.124";
/* /*
** Regardless of the type of time_t, we do our work using this type. ** Regardless of the type of time_t, we do our work using this type.
@@ -10,6 +10,10 @@ typedef int zic_t;
#include "locale.h" #include "locale.h"
#include "tzfile.h" #include "tzfile.h"
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
#define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
#if HAVE_SYS_STAT_H #if HAVE_SYS_STAT_H
#include "sys/stat.h" #include "sys/stat.h"
#endif #endif
@@ -21,7 +25,7 @@ typedef int zic_t;
/* /*
** On some ancient hosts, predicates like `isspace(C)' are defined ** On some ancient hosts, predicates like `isspace(C)' are defined
** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, ** only if isascii(C) || C == EOF. Modern hosts obey the C Standard,
** which says they are defined only if C == ((unsigned char) C) || C == EOF. ** which says they are defined only if C == ((unsigned char) C) || C == EOF.
** Neither the C Standard nor Posix require that `isascii' exist. ** Neither the C Standard nor Posix require that `isascii' exist.
** For portability, we check both ancient and modern requirements. ** For portability, we check both ancient and modern requirements.
@@ -138,9 +142,9 @@ static void usage P((void));
static void writezone P((const char * name)); static void writezone P((const char * name));
static int yearistype P((int year, const char * type)); static int yearistype P((int year, const char * type));
#if !(HAVE_STRERROR - 0) #if !HAVE_STRERROR
static char * strerror P((int)); static char * strerror P((int));
#endif /* !(HAVE_STRERROR - 0) */ #endif /* !HAVE_STRERROR */
static int charcnt; static int charcnt;
static int errors; static int errors;
@@ -380,7 +384,7 @@ char * const ptr;
** Error handling. ** Error handling.
*/ */
#if !(HAVE_STRERROR - 0) #if !HAVE_STRERROR
static char * static char *
strerror(errnum) strerror(errnum)
int errnum; int errnum;
@@ -391,7 +395,7 @@ int errnum;
return (errnum > 0 && errnum <= sys_nerr) ? return (errnum > 0 && errnum <= sys_nerr) ?
sys_errlist[errnum] : _("Unknown system error"); sys_errlist[errnum] : _("Unknown system error");
} }
#endif /* !(HAVE_STRERROR - 0) */ #endif /* !HAVE_STRERROR */
static void static void
eats(name, num, rname, rnum) eats(name, num, rname, rnum)
@@ -448,7 +452,9 @@ const char * const string;
static void static void
usage P((void)) usage P((void))
{ {
(void) fprintf(stderr, _("%s: usage is %s [ --version ] [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"), (void) fprintf(stderr, _("%s: usage is %s \
[ --version ] [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"),
progname, progname); progname, progname);
(void) exit(EXIT_FAILURE); (void) exit(EXIT_FAILURE);
} }
@@ -472,13 +478,13 @@ char * argv[];
#ifdef unix #ifdef unix
(void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
#endif /* defined unix */ #endif /* defined unix */
#if HAVE_GETTEXT - 0 #if HAVE_GETTEXT
(void) setlocale(LC_MESSAGES, ""); (void) setlocale(LC_ALL, "");
#ifdef TZ_DOMAINDIR #ifdef TZ_DOMAINDIR
(void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
#endif /* defined TEXTDOMAINDIR */ #endif /* defined TEXTDOMAINDIR */
(void) textdomain(TZ_DOMAIN); (void) textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT - 0 */ #endif /* HAVE_GETTEXT */
progname = argv[0]; progname = argv[0];
for (i = 1; i < argc; ++i) for (i = 1; i < argc; ++i)
if (strcmp(argv[i], "--version") == 0) { if (strcmp(argv[i], "--version") == 0) {
@@ -579,6 +585,11 @@ _("%s: More than one -L option specified\n"),
for (i = 0; i < nlinks; ++i) { for (i = 0; i < nlinks; ++i) {
eat(links[i].l_filename, links[i].l_linenum); eat(links[i].l_filename, links[i].l_linenum);
dolink(links[i].l_from, links[i].l_to); dolink(links[i].l_from, links[i].l_to);
if (noise)
for (j = 0; j < nlinks; ++j)
if (strcmp(links[i].l_to,
links[j].l_from) == 0)
warning(_("link to link"));
} }
if (lcltime != NULL) { if (lcltime != NULL) {
eat("command line", 1); eat("command line", 1);
@@ -626,22 +637,27 @@ const char * const tofile;
(void) exit(EXIT_FAILURE); (void) exit(EXIT_FAILURE);
result = link(fromname, toname); result = link(fromname, toname);
#if (HAVE_SYMLINK - 0) #if HAVE_SYMLINK
if (result != 0 && if (result != 0 &&
access(fromname, F_OK) == 0 && access(fromname, F_OK) == 0 &&
!itsdir(fromname)) { !itsdir(fromname)) {
const char *s = tofile; const char *s = tofile;
register char * symlinkcontents = NULL; register char * symlinkcontents = NULL;
while ((s = strchr(s+1, '/')) != NULL)
symlinkcontents = ecatalloc(symlinkcontents, "../");
symlinkcontents = ecatalloc(symlinkcontents, fromfile);
result = symlink(symlinkcontents, toname); while ((s = strchr(s+1, '/')) != NULL)
if (result == 0) symlinkcontents =
//warning(_("hard link failed, symbolic link used")); ecatalloc(symlinkcontents,
ifree(symlinkcontents); "../");
symlinkcontents =
ecatalloc(symlinkcontents,
fromfile);
result = symlink(symlinkcontents,
toname);
if (result == 0)
warning(_("hard link failed, symbolic link used"));
ifree(symlinkcontents);
} }
#endif #endif /* HAVE_SYMLINK */
if (result != 0) { if (result != 0) {
const char *e = strerror(errno); const char *e = strerror(errno);
@@ -799,7 +815,7 @@ associate P((void))
*/ */
eat(zp->z_filename, zp->z_linenum); eat(zp->z_filename, zp->z_linenum);
zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"),
TRUE); TRUE);
/* /*
** Note, though, that if there's no rule, ** Note, though, that if there's no rule,
** a '%s' in the format is a bad thing. ** a '%s' in the format is a bad thing.
@@ -1102,7 +1118,9 @@ const int iscont;
zones[nzones - 1].z_untiltime > min_time && zones[nzones - 1].z_untiltime > min_time &&
zones[nzones - 1].z_untiltime < max_time && zones[nzones - 1].z_untiltime < max_time &&
zones[nzones - 1].z_untiltime >= z.z_untiltime) { zones[nzones - 1].z_untiltime >= z.z_untiltime) {
error(_("Zone continuation line end time is not after end time of previous line")); error(_(
"Zone continuation line end time is not after end time of previous line"
));
return FALSE; return FALSE;
} }
} }
@@ -1135,11 +1153,11 @@ const int nfields;
dayoff = 0; dayoff = 0;
cp = fields[LP_YEAR]; cp = fields[LP_YEAR];
if (sscanf(cp, scheck(cp, "%d"), &year) != 1) { if (sscanf(cp, scheck(cp, "%d"), &year) != 1) {
/* /*
* Leapin' Lizards! ** Leapin' Lizards!
*/ */
error(_("invalid leaping year")); error(_("invalid leaping year"));
return; return;
} }
j = EPOCH_YEAR; j = EPOCH_YEAR;
while (j != year) { while (j != year) {
@@ -1206,7 +1224,9 @@ const int nfields;
return; return;
} }
if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) { if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) {
error(_("illegal Rolling/Stationary field on Leap line")); error(_(
"illegal Rolling/Stationary field on Leap line"
));
return; return;
} }
leapadd(tadd(t, tod), positive, lp->l_value, count); leapadd(tadd(t, tod), positive, lp->l_value, count);
@@ -1468,14 +1488,13 @@ const char * const name;
while (fromi < timecnt && attypes[fromi].type == 0) while (fromi < timecnt && attypes[fromi].type == 0)
++fromi; /* handled by default rule */ ++fromi; /* handled by default rule */
for ( ; fromi < timecnt; ++fromi) { for ( ; fromi < timecnt; ++fromi) {
if (toi != 0 if (toi != 0 && ((attypes[fromi].at +
&& ((attypes[fromi].at gmtoffs[attypes[toi - 1].type]) <=
+ gmtoffs[attypes[toi - 1].type]) (attypes[toi - 1].at + gmtoffs[toi == 1 ? 0
<= (attypes[toi - 1].at : attypes[toi - 2].type]))) {
+ gmtoffs[toi == 1 ? 0 attypes[toi - 1].type =
: attypes[toi - 2].type]))) { attypes[fromi].type;
attypes[toi - 1].type = attypes[fromi].type; continue;
continue;
} }
if (toi == 0 || if (toi == 0 ||
attypes[toi - 1].type != attypes[fromi].type) attypes[toi - 1].type != attypes[fromi].type)
@@ -1521,7 +1540,8 @@ const char * const name;
convert(eitol(typecnt), tzh.tzh_typecnt); convert(eitol(typecnt), tzh.tzh_typecnt);
convert(eitol(charcnt), tzh.tzh_charcnt); convert(eitol(charcnt), tzh.tzh_charcnt);
(void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
#define DO(field) (void) fwrite((void *) tzh.field, (size_t) sizeof tzh.field, (size_t) 1, fp) #define DO(field) (void) fwrite((void *) tzh.field, \
(size_t) sizeof tzh.field, (size_t) 1, fp)
DO(tzh_magic); DO(tzh_magic);
DO(tzh_reserved); DO(tzh_reserved);
DO(tzh_ttisgmtcnt); DO(tzh_ttisgmtcnt);
@@ -1740,12 +1760,13 @@ const int zonecount;
continue; continue;
} }
if (*startbuf == '\0' && if (*startbuf == '\0' &&
startoff == oadd(zp->z_gmtoff, startoff == oadd(zp->z_gmtoff,
stdoff)) { stdoff))
doabbr(startbuf, zp->z_format, doabbr(startbuf,
rp->r_abbrvar, zp->z_format,
rp->r_stdoff != 0); rp->r_abbrvar,
} rp->r_stdoff !=
0);
} }
eats(zp->z_filename, zp->z_linenum, eats(zp->z_filename, zp->z_linenum,
rp->r_filename, rp->r_linenum); rp->r_filename, rp->r_linenum);
@@ -2036,7 +2057,9 @@ register char * cp;
else while ((*dp = *cp++) != '"') else while ((*dp = *cp++) != '"')
if (*dp != '\0') if (*dp != '\0')
++dp; ++dp;
else error(_("Odd number of quotation marks")); else error(_(
"Odd number of quotation marks"
));
} while (*cp != '\0' && *cp != '#' && } while (*cp != '\0' && *cp != '#' &&
(!isascii(*cp) || !isspace((unsigned char) *cp))); (!isascii(*cp) || !isspace((unsigned char) *cp)));
if (isascii(*cp) && isspace((unsigned char) *cp)) if (isascii(*cp) && isspace((unsigned char) *cp))
@@ -2157,7 +2180,8 @@ register const int wantedy;
} }
if (i < 0 || i >= len_months[isleap(y)][m]) { if (i < 0 || i >= len_months[isleap(y)][m]) {
if (noise) if (noise)
warning(_("rule goes past start/end of month--will not work with pre-2004 versions of zic")); warning(_("rule goes past start/end of month--\
will not work with pre-2004 versions of zic"));
} }
} }
if (dayoff < 0 && !TYPE_SIGNED(zic_t)) if (dayoff < 0 && !TYPE_SIGNED(zic_t))
@@ -2176,6 +2200,41 @@ const char * const string;
{ {
register int i; register int i;
if (strcmp(string, GRANDPARENTED) != 0) {
register const char * cp;
register char * wp;
/*
** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics
** optionally followed by a + or - and a number from 1 to 14.
*/
cp = string;
wp = NULL;
while (isascii(*cp) && isalpha(*cp))
++cp;
if (cp - string == 0)
wp = _("time zone abbreviation lacks alphabetic at start");
if (noise && cp - string > 3)
wp = _("time zone abbreviation has more than 3 alphabetics");
if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN)
wp = _("time zone abbreviation has too many alphabetics");
if (wp == NULL && (*cp == '+' || *cp == '-')) {
++cp;
if (isascii(*cp) && isdigit(*cp))
if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
++cp;
}
if (*cp != '\0')
wp = _("time zone abbreviation differs from POSIX standard");
if (wp != NULL) {
wp = ecpyalloc(wp);
wp = ecatalloc(wp, " (");
wp = ecatalloc(wp, string);
wp = ecatalloc(wp, ")");
warning(wp);
ifree(wp);
}
}
i = strlen(string) + 1; i = strlen(string) + 1;
if (charcnt + i > TZ_MAX_CHARS) { if (charcnt + i > TZ_MAX_CHARS) {
error(_("too many, or too long, time zone abbreviations")); error(_("too many, or too long, time zone abbreviations"));
+92 -24
View File
@@ -5,7 +5,7 @@
#ifndef lint #ifndef lint
#ifndef NOID #ifndef NOID
static char elsieid[] = "@(#)localtime.c 7.89"; static char elsieid[] = "@(#)localtime.c 7.95";
#endif /* !defined NOID */ #endif /* !defined NOID */
#endif /* !defined lint */ #endif /* !defined lint */
@@ -20,6 +20,20 @@ static char elsieid[] = "@(#)localtime.c 7.89";
#include "private.h" #include "private.h"
#include "tzfile.h" #include "tzfile.h"
#include "fcntl.h" #include "fcntl.h"
#include "float.h" /* for FLT_MAX and DBL_MAX */
#ifndef TZ_ABBR_MAX_LEN
#define TZ_ABBR_MAX_LEN 16
#endif /* !defined TZ_ABBR_MAX_LEN */
#ifndef TZ_ABBR_CHAR_SET
#define TZ_ABBR_CHAR_SET \
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
#endif /* !defined TZ_ABBR_CHAR_SET */
#ifndef TZ_ABBR_ERR_CHAR
#define TZ_ABBR_ERR_CHAR '_'
#endif /* !defined TZ_ABBR_ERR_CHAR */
/* /*
** SunOS 4.1.1 headers lack O_BINARY. ** SunOS 4.1.1 headers lack O_BINARY.
@@ -46,9 +60,9 @@ static char elsieid[] = "@(#)localtime.c 7.89";
** 5. They might reference tm.TM_ZONE after calling offtime. ** 5. They might reference tm.TM_ZONE after calling offtime.
** What's best to do in the above cases is open to debate; ** What's best to do in the above cases is open to debate;
** for now, we just set things up so that in any of the five cases ** for now, we just set things up so that in any of the five cases
** WILDABBR is used. Another possibility: initialize tzname[0] to the ** WILDABBR is used. Another possibility: initialize tzname[0] to the
** string "tzname[0] used before set", and similarly for the other cases. ** string "tzname[0] used before set", and similarly for the other cases.
** And another: initialize tzname[0] to "ERA", with an explanation in the ** And another: initialize tzname[0] to "ERA", with an explanation in the
** manual page of what this "time zone abbreviation" means (doing this so ** manual page of what this "time zone abbreviation" means (doing this so
** that tzname[0] has the "normal" length of three characters). ** that tzname[0] has the "normal" length of three characters).
*/ */
@@ -123,6 +137,7 @@ struct rule {
static long detzcode P((const char * codep)); static long detzcode P((const char * codep));
static const char * getzname P((const char * strp)); static const char * getzname P((const char * strp));
static const char * getqzname P((const char * strp, const char delim));
static const char * getnum P((const char * strp, int * nump, int min, static const char * getnum P((const char * strp, int * nump, int min,
int max)); int max));
static const char * getsecs P((const char * strp, long * secsp)); static const char * getsecs P((const char * strp, long * secsp));
@@ -268,6 +283,24 @@ settzname P((void))
tzname[ttisp->tt_isdst] = tzname[ttisp->tt_isdst] =
&sp->chars[ttisp->tt_abbrind]; &sp->chars[ttisp->tt_abbrind];
} }
/*
** Finally, scrub the abbreviations.
** First, replace bogus characters.
*/
for (i = 0; i < sp->charcnt; ++i)
if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
sp->chars[i] = TZ_ABBR_ERR_CHAR;
/*
** Second, truncate long abbreviations.
*/
for (i = 0; i < sp->typecnt; ++i) {
register const struct ttinfo * const ttisp = &sp->ttis[i];
register char * cp = &sp->chars[ttisp->tt_abbrind];
if (strlen(cp) > TZ_ABBR_MAX_LEN &&
strcmp(cp, GRANDPARENTED) != 0)
*(cp + TZ_ABBR_MAX_LEN) = '\0';
}
} }
static int static int
@@ -452,7 +485,7 @@ static const int year_lengths[2] = {
/* /*
** Given a pointer into a time zone string, scan until a character that is not ** Given a pointer into a time zone string, scan until a character that is not
** a valid character in a zone name is found. Return a pointer to that ** a valid character in a zone name is found. Return a pointer to that
** character. ** character.
*/ */
@@ -468,6 +501,27 @@ register const char * strp;
return strp; return strp;
} }
/*
** Given a pointer into an extended time zone string, scan until the ending
** delimiter of the zone name is located. Return a pointer to the delimiter.
**
** As with getzname above, the legal character set is actually quite
** restricted, with other characters producing undefined results.
** We choose not to care - allowing almost anything to be in the zone abbrev.
*/
static const char *
getqzname(strp, delim)
register const char * strp;
const char delim;
{
register char c;
while ((c = *strp) != '\0' && c != delim)
++strp;
return strp;
}
/* /*
** Given a pointer into a time zone string, extract a number from that string. ** Given a pointer into a time zone string, extract a number from that string.
** Check that the number is within a specified range; if it is not, return ** Check that the number is within a specified range; if it is not, return
@@ -533,7 +587,7 @@ long * const secsp;
*secsp += num * SECSPERMIN; *secsp += num * SECSPERMIN;
if (*strp == ':') { if (*strp == ':') {
++strp; ++strp;
/* `SECSPERMIN' allows for leap seconds. */ /* `SECSPERMIN' allows for leap seconds. */
strp = getnum(strp, &num, 0, SECSPERMIN); strp = getnum(strp, &num, 0, SECSPERMIN);
if (strp == NULL) if (strp == NULL)
return NULL; return NULL;
@@ -572,7 +626,7 @@ long * const offsetp;
/* /*
** Given a pointer into a time zone string, extract a rule in the form ** Given a pointer into a time zone string, extract a rule in the form
** date[/time]. See POSIX section 8 for the format of "date" and "time". ** date[/time]. See POSIX section 8 for the format of "date" and "time".
** If a valid rule is not found, return NULL. ** If a valid rule is not found, return NULL.
** Otherwise, return a pointer to the first character not part of the rule. ** Otherwise, return a pointer to the first character not part of the rule.
*/ */
@@ -691,7 +745,7 @@ const long offset;
dow += DAYSPERWEEK; dow += DAYSPERWEEK;
/* /*
** "dow" is the day-of-week of the first day of the month. Get ** "dow" is the day-of-week of the first day of the month. Get
** the day-of-month (zero-origin) of the first "dow" day of the ** the day-of-month (zero-origin) of the first "dow" day of the
** month. ** month.
*/ */
@@ -714,7 +768,7 @@ const long offset;
/* /*
** "value" is the Epoch-relative time of 00:00:00 UTC 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 ** question. To get the Epoch-relative time of the specified local
** time on that day, add the transition time and the current offset ** time on that day, add the transition time and the current offset
** from UTC. ** from UTC.
*/ */
@@ -752,10 +806,18 @@ const int lastditch;
stdlen = (sizeof sp->chars) - 1; stdlen = (sizeof sp->chars) - 1;
stdoffset = 0; stdoffset = 0;
} else { } else {
name = getzname(name); if (*name == '<') {
stdlen = name - stdname; name++;
if (stdlen < 3) stdname = name;
return -1; name = getqzname(name, '>');
if (*name != '>')
return (-1);
stdlen = name - stdname;
name++;
} else {
name = getzname(name);
stdlen = name - stdname;
}
if (*name == '\0') if (*name == '\0')
return -1; return -1;
name = getoffset(name, &stdoffset); name = getoffset(name, &stdoffset);
@@ -766,11 +828,18 @@ const int lastditch;
if (load_result != 0) if (load_result != 0)
sp->leapcnt = 0; /* so, we're off a little */ sp->leapcnt = 0; /* so, we're off a little */
if (*name != '\0') { if (*name != '\0') {
dstname = name; if (*name == '<') {
name = getzname(name); dstname = ++name;
dstlen = name - dstname; /* length of DST zone name */ name = getqzname(name, '>');
if (dstlen < 3) if (*name != '>')
return -1; return -1;
dstlen = name - dstname;
name++;
} else {
dstname = name;
name = getzname(name);
dstlen = name - dstname; /* length of DST zone name */
}
if (*name != '\0' && *name != ',' && *name != ';') { if (*name != '\0' && *name != ',' && *name != ';') {
name = getoffset(name, &dstoffset); name = getoffset(name, &dstoffset);
if (name == NULL) if (name == NULL)
@@ -1031,7 +1100,7 @@ tzset P((void))
/* /*
** The easy way to behave "as if no library function calls" localtime ** The easy way to behave "as if no library function calls" localtime
** is to not call it--so we drop its guts into "localsub", which can be ** is to not call it--so we drop its guts into "localsub", which can be
** freely called. (And no, the PANS doesn't require the above behavior-- ** freely called. (And no, the PANS doesn't require the above behavior--
** but it *is* desirable.) ** but it *is* desirable.)
** **
** The unused offset argument is for the benefit of mktime variants. ** The unused offset argument is for the benefit of mktime variants.
@@ -1187,7 +1256,7 @@ static int
leaps_thru_end_of(y) leaps_thru_end_of(y)
register const int y; register const int y;
{ {
return (y >= 0) ? (y / 4 - y / 100 + y / 400) : return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
-(leaps_thru_end_of(-(y + 1)) + 1); -(leaps_thru_end_of(-(y + 1)) + 1);
} }
@@ -1311,7 +1380,7 @@ register struct tm * const tmp;
tmp->tm_min = (int) (rem / SECSPERMIN); tmp->tm_min = (int) (rem / SECSPERMIN);
/* /*
** A positive leap second requires a special ** A positive leap second requires a special
** representation. This uses "... ??:59:60" et seq. ** representation. This uses "... ??:59:60" et seq.
*/ */
tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
ip = mon_lengths[isleap(y)]; ip = mon_lengths[isleap(y)];
@@ -1325,13 +1394,12 @@ register struct tm * const tmp;
return tmp; return tmp;
} }
/* /*
** Adapted from code provided by Robert Elz, who writes: ** Adapted from code provided by Robert Elz, who writes:
** The "best" way to do mktime I think is based on an idea of Bob ** The "best" way to do mktime I think is based on an idea of Bob
** Kridle's (so its said...) from a long time ago. ** Kridle's (so its said...) from a long time ago.
** [kridle@xinet.com as of 1996-01-16.] ** [kridle@xinet.com as of 1996-01-16.]
** It does a binary search of the time_t space. Since time_t's are ** It does a binary search of the time_t space. Since time_t's are
** just 32 bits, its a max of 32 iterations (even at 64 bits it ** just 32 bits, its a max of 32 iterations (even at 64 bits it
** would still be very reasonable). ** would still be very reasonable).
*/ */
@@ -1481,7 +1549,7 @@ const int do_norm_secs;
return WRONG; return WRONG;
yourtm.tm_year = y; yourtm.tm_year = y;
if (yourtm.tm_year != y) if (yourtm.tm_year != y)
return WRONG; return WRONG;
if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
saved_seconds = 0; saved_seconds = 0;
else if (y + TM_YEAR_BASE < EPOCH_YEAR) { else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
@@ -1802,7 +1870,7 @@ time_t t;
tzset(); tzset();
/* /*
** For a positive leap second hit, the result ** For a positive leap second hit, the result
** is not unique. For a negative leap second ** is not unique. For a negative leap second
** hit, the corresponding time doesn't exist, ** hit, the corresponding time doesn't exist,
** so we return an adjacent second. ** so we return an adjacent second.
*/ */
+14 -13
View File
@@ -1,6 +1,6 @@
#ifndef lint #ifndef lint
#ifndef NOID #ifndef NOID
static char elsieid[] = "@(#)strftime.c 7.74"; static char elsieid[] = "@(#)strftime.c 7.75";
/* /*
** Based on the UCB version with the ID appearing below. ** Based on the UCB version with the ID appearing below.
** This is ANSIish only when "multibyte character == plain character". ** This is ANSIish only when "multibyte character == plain character".
@@ -19,7 +19,7 @@ static char elsieid[] = "@(#)strftime.c 7.74";
** duplicated in all such forms and that any documentation, ** duplicated in all such forms and that any documentation,
** advertising materials, and other materials related to such ** advertising materials, and other materials related to such
** distribution and use acknowledge that the software was developed ** distribution and use acknowledge that the software was developed
** by the University of California, Berkeley. The name of the ** by the University of California, Berkeley. The name of the
** University may not be used to endorse or promote products derived ** University may not be used to endorse or promote products derived
** from this software without specific prior written permission. ** from this software without specific prior written permission.
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
@@ -91,7 +91,7 @@ static const struct lc_time_T C_time_locale = {
** C99 requires this format. ** C99 requires this format.
** Previously this code used "%D %X", but we now conform to C99. ** Previously this code used "%D %X", but we now conform to C99.
** Note that ** Note that
** "%a %b %d %H:%M:%S %Y" ** "%a %b %d %H:%M:%S %Y"
** is used by Solaris 2.3. ** is used by Solaris 2.3.
*/ */
"%a %b %e %T %Y", "%a %b %e %T %Y",
@@ -108,7 +108,8 @@ static const struct lc_time_T C_time_locale = {
static char * _add P((const char *, char *, const char *)); static char * _add P((const char *, char *, const char *));
static char * _conv P((int, 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 *, int *)); static char * _fmt P((const char *, const struct tm *, char *, const char *,
int *));
static char * _yconv P((int, int, int, int, char *, const char *)); static char * _yconv P((int, int, int, int, char *, const char *));
extern char * tzname[]; extern char * tzname[];
@@ -264,7 +265,7 @@ label:
** t->tm_hour % 12 : 12, 2, ' '); ** t->tm_hour % 12 : 12, 2, ' ');
** ...and has been changed to the below to ** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbins' ** match SunOS 4.1.1 and Arnold Robbins'
** strftime version 3.0. That is, "%k" and ** strftime version 3.0. That is, "%k" and
** "%l" have been swapped. ** "%l" have been swapped.
** (ado, 1993-05-24) ** (ado, 1993-05-24)
*/ */
@@ -284,7 +285,7 @@ label:
** _conv(t->tm_hour, 2, ' '); ** _conv(t->tm_hour, 2, ' ');
** ...and has been changed to the below to ** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbin's ** match SunOS 4.1.1 and Arnold Robbin's
** strftime version 3.0. That is, "%k" and ** strftime version 3.0. That is, "%k" and
** "%l" have been swapped. ** "%l" have been swapped.
** (ado, 1993-05-24) ** (ado, 1993-05-24)
*/ */
@@ -359,7 +360,7 @@ label:
case 'G': /* ISO 8601 year (four digits) */ case 'G': /* ISO 8601 year (four digits) */
case 'g': /* ISO 8601 year (two digits) */ case 'g': /* ISO 8601 year (two digits) */
/* /*
** From Arnold Robbins' strftime version 3.0: "the week number of the ** From Arnold Robbins' strftime version 3.0: "the week number of the
** year (the first Monday as the first day of week 1) as a decimal number ** year (the first Monday as the first day of week 1) as a decimal number
** (01-53)." ** (01-53)."
** (ado, 1993-05-24) ** (ado, 1993-05-24)
@@ -372,7 +373,7 @@ label:
** might also contain days from the previous year and the week before week ** might also contain days from the previous year and the week before week
** 01 of a year is the last week (52 or 53) of the previous year even if ** 01 of a year is the last week (52 or 53) of the previous year even if
** it contains days from the new year. A week starts with Monday (day 1) ** it contains days from the new year. A week starts with Monday (day 1)
** and ends with Sunday (day 7). For example, the first week of the year ** and ends with Sunday (day 7). For example, the first week of the year
** 1997 lasts from 1996-12-30 to 1997-01-05..." ** 1997 lasts from 1996-12-30 to 1997-01-05..."
** (ado, 1996-01-02) ** (ado, 1996-01-02)
*/ */
@@ -512,12 +513,12 @@ label:
/* /*
** C99 says that the UTC offset must ** C99 says that the UTC offset must
** be computed by looking only at ** be computed by looking only at
** tm_isdst. This requirement is ** tm_isdst. This requirement is
** incorrect, since it means the code ** incorrect, since it means the code
** must rely on magic (in this case ** must rely on magic (in this case
** altzone and timezone), and the ** altzone and timezone), and the
** magic might not have the correct ** magic might not have the correct
** offset. Doing things correctly is ** offset. Doing things correctly is
** tricky and requires disobeying C99; ** tricky and requires disobeying C99;
** see GNU C strftime for details. ** see GNU C strftime for details.
** For now, punt and conform to the ** For now, punt and conform to the
@@ -559,7 +560,7 @@ label:
case '%': case '%':
/* /*
** X311J/88-090 (4.12.3.5): if conversion char is ** X311J/88-090 (4.12.3.5): if conversion char is
** undefined, behavior is undefined. Print out the ** undefined, behavior is undefined. Print out the
** character itself as printf(3) also does. ** character itself as printf(3) also does.
*/ */
default: default:
@@ -682,7 +683,7 @@ _loc P((void))
** Slurp the locale file into the cache. ** Slurp the locale file into the cache.
*/ */
namesize = strlen(name) + 1; namesize = strlen(name) + 1;
if (sizeof filename < if (sizeof filename <
((sizeof locale_home) + namesize + (sizeof lc_time))) ((sizeof locale_home) + namesize + (sizeof lc_time)))
goto no_locale; goto no_locale;
oldsun = 0; oldsun = 0;
@@ -705,7 +706,7 @@ _loc P((void))
goto bad_locale; goto bad_locale;
bufsize = namesize + st.st_size; bufsize = namesize + st.st_size;
locale_buf = NULL; locale_buf = NULL;
lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize); lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize);
if (lbuf == NULL) if (lbuf == NULL)
goto bad_locale; goto bad_locale;
(void) strcpy(lbuf, name); (void) strcpy(lbuf, name);