From b1c123994cb5cdaf588b854a7f5156759ec51436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Fri, 8 Jul 2005 23:49:29 +0000 Subject: [PATCH] Updated to tzcode2005j.tar.gz git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13561 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/libroot/time/private.h | 31 +++-- headers/private/libroot/time/tzfile.h | 26 +--- src/bin/zic/scheck.c | 4 +- src/bin/zic/zdump.c | 62 +++++++-- src/bin/zic/zic.c | 155 +++++++++++++++------- src/system/libroot/posix/time/localtime.c | 116 ++++++++++++---- src/system/libroot/posix/time/strftime.c | 27 ++-- 7 files changed, 287 insertions(+), 134 deletions(-) diff --git a/headers/private/libroot/time/private.h b/headers/private/libroot/time/private.h index 5de2f7dfe4..9a1ef22abb 100644 --- a/headers/private/libroot/time/private.h +++ b/headers/private/libroot/time/private.h @@ -25,6 +25,8 @@ static char privatehid[] = "@(#)private.h 7.55"; #endif /* !defined NOID */ #endif /* !defined lint */ +#define GRANDPARENTED "Local time zone must be set--see zic manual page" + /* ** Defaults for preprocessor symbols. ** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. @@ -91,13 +93,13 @@ static char privatehid[] = "@(#)private.h 7.55"; #include "time.h" #include "stdlib.h" -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #include "libintl.h" -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ -#if HAVE_SYS_WAIT_H - 0 +#if HAVE_SYS_WAIT_H #include /* for WIFEXITED and WEXITSTATUS */ -#endif /* HAVE_SYS_WAIT_H - 0 */ +#endif /* HAVE_SYS_WAIT_H */ #ifndef WIFEXITED #define WIFEXITED(status) (((status) & 0xff) == 0) @@ -106,20 +108,20 @@ static char privatehid[] = "@(#)private.h 7.55"; #define WEXITSTATUS(status) (((status) >> 8) & 0xff) #endif /* !defined WEXITSTATUS */ -#if HAVE_UNISTD_H - 0 +#if HAVE_UNISTD_H #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 #define F_OK 0 #endif /* !defined F_OK */ #ifndef R_OK #define R_OK 4 #endif /* !defined R_OK */ -#endif /* !(HAVE_UNISTD_H - 0) */ +#endif /* !HAVE_UNISTD_H */ -/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #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 icfree 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. @@ -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. */ #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 */ /* @@ -289,11 +292,11 @@ char * scheck P((const char *string, const char *format)); */ #ifndef _ -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #define _(msgid) gettext(msgid) -#else /* !(HAVE_GETTEXT - 0) */ +#else /* !HAVE_GETTEXT */ #define _(msgid) msgid -#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !HAVE_GETTEXT */ #endif /* !defined _ */ #ifndef TZ_DOMAIN diff --git a/headers/private/libroot/time/tzfile.h b/headers/private/libroot/time/tzfile.h index 0e9966a950..2dad932ef4 100644 --- a/headers/private/libroot/time/tzfile.h +++ b/headers/private/libroot/time/tzfile.h @@ -21,7 +21,7 @@ #ifndef lint #ifndef NOID -static char tzfilehid[] = "@(#)tzfile.h 7.16"; +static char tzfilehid[] = "@(#)tzfile.h 7.17"; #endif /* !defined NOID */ #endif /* !defined lint */ @@ -48,7 +48,7 @@ static char tzfilehid[] = "@(#)tzfile.h 7.16"; #define TZ_MAGIC "TZif" struct tzhead { - char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_magic[4]; /* TZ_MAGIC */ char tzh_reserved[16]; /* reserved for future use */ char tzh_ttisgmtcnt[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) -#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 */ diff --git a/src/bin/zic/scheck.c b/src/bin/zic/scheck.c index 39feeba701..2dd9b35285 100644 --- a/src/bin/zic/scheck.c +++ b/src/bin/zic/scheck.c @@ -1,6 +1,6 @@ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)scheck.c 8.15"; +static char elsieid[] = "@(#)scheck.c 8.16"; #endif /* !defined lint */ #endif /* !defined NOID */ @@ -11,7 +11,7 @@ static char elsieid[] = "@(#)scheck.c 8.15"; char * scheck(string, format) const char * const string; -const char * const format; +char * const format; { register char * fbuf; register const char * fp; diff --git a/src/bin/zic/zdump.c b/src/bin/zic/zdump.c index bd7132698f..78cc28ef65 100644 --- a/src/bin/zic/zdump.c +++ b/src/bin/zic/zdump.c @@ -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 @@ -144,8 +144,10 @@ static time_t absolute_min_time; static time_t absolute_max_time; static size_t longest; static char * progname; +static int warned; 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 void dumptime P((const struct tm * tmp)); 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, tformat(), *tp); (void) fprintf(stderr, " ->"); - (void) fprintf(stderr, " sec %d", tmp->tm_sec); - (void) fprintf(stderr, " min %d", tmp->tm_min); - (void) fprintf(stderr, " hour %d", tmp->tm_hour); - (void) fprintf(stderr, " mday %d", tmp->tm_mday); - (void) fprintf(stderr, " mon %d", tmp->tm_mon); - (void) fprintf(stderr, " year %d", tmp->tm_year); + (void) fprintf(stderr, " year=%d", tmp->tm_year); + (void) fprintf(stderr, " mon=%d", tmp->tm_mon); + (void) fprintf(stderr, " mday=%d", tmp->tm_mday); + (void) fprintf(stderr, " hour=%d", tmp->tm_hour); + (void) fprintf(stderr, " min=%d", tmp->tm_min); + (void) fprintf(stderr, " sec=%d", tmp->tm_sec); + (void) fprintf(stderr, " isdst=%d", tmp->tm_isdst); (void) fprintf(stderr, " -> "); (void) fprintf(stderr, tformat(), t); (void) fprintf(stderr, "\n"); @@ -190,6 +193,44 @@ time_t * tp; } #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 main(argc, argv) int argc; @@ -215,7 +256,7 @@ char * argv[]; INITIALIZE(cutlotime); INITIALIZE(cuthitime); #if HAVE_GETTEXT - (void) setlocale(LC_MESSAGES, ""); + (void) setlocale(LC_ALL, ""); #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); #endif /* defined TEXTDOMAINDIR */ @@ -296,6 +337,7 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"), show(argv[i], now, FALSE); continue; } + warned = FALSE; t = absolute_min_time; show(argv[i], t, TRUE); t += SECSPERHOUR * HOURSPERDAY; @@ -318,7 +360,7 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"), newtmp = localtime(&newt); if (newtmp != NULL) newtm = *newtmp; - if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) : + if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) : (delta(&newtm, &tm) != (newt - t) || newtm.tm_isdst != tm.tm_isdst || strcmp(abbr(&newtm), buf) != 0)) { @@ -526,6 +568,8 @@ int v; } } (void) printf("\n"); + if (tmp != NULL && *abbr(tmp) != '\0') + abbrok(abbr(tmp), zone); } static char * diff --git a/src/bin/zic/zic.c b/src/bin/zic/zic.c index b7d9ec0d7e..57dc5311d5 100644 --- a/src/bin/zic/zic.c +++ b/src/bin/zic/zic.c @@ -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. @@ -10,6 +10,10 @@ typedef int zic_t; #include "locale.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 #include "sys/stat.h" #endif @@ -21,7 +25,7 @@ typedef int zic_t; /* ** 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. ** Neither the C Standard nor Posix require that `isascii' exist. ** 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 int yearistype P((int year, const char * type)); -#if !(HAVE_STRERROR - 0) +#if !HAVE_STRERROR static char * strerror P((int)); -#endif /* !(HAVE_STRERROR - 0) */ +#endif /* !HAVE_STRERROR */ static int charcnt; static int errors; @@ -380,7 +384,7 @@ char * const ptr; ** Error handling. */ -#if !(HAVE_STRERROR - 0) +#if !HAVE_STRERROR static char * strerror(errnum) int errnum; @@ -391,7 +395,7 @@ int errnum; return (errnum > 0 && errnum <= sys_nerr) ? sys_errlist[errnum] : _("Unknown system error"); } -#endif /* !(HAVE_STRERROR - 0) */ +#endif /* !HAVE_STRERROR */ static void eats(name, num, rname, rnum) @@ -448,7 +452,9 @@ const char * const string; static 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); (void) exit(EXIT_FAILURE); } @@ -472,13 +478,13 @@ char * argv[]; #ifdef unix (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); #endif /* defined unix */ -#if HAVE_GETTEXT - 0 - (void) setlocale(LC_MESSAGES, ""); +#if HAVE_GETTEXT + (void) setlocale(LC_ALL, ""); #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); #endif /* defined TEXTDOMAINDIR */ (void) textdomain(TZ_DOMAIN); -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ progname = argv[0]; for (i = 1; i < argc; ++i) if (strcmp(argv[i], "--version") == 0) { @@ -579,6 +585,11 @@ _("%s: More than one -L option specified\n"), for (i = 0; i < nlinks; ++i) { eat(links[i].l_filename, links[i].l_linenum); 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) { eat("command line", 1); @@ -626,22 +637,27 @@ const char * const tofile; (void) exit(EXIT_FAILURE); result = link(fromname, toname); -#if (HAVE_SYMLINK - 0) +#if HAVE_SYMLINK if (result != 0 && - access(fromname, F_OK) == 0 && - !itsdir(fromname)) { - const char *s = tofile; - register char * symlinkcontents = NULL; - while ((s = strchr(s+1, '/')) != NULL) - symlinkcontents = ecatalloc(symlinkcontents, "../"); - symlinkcontents = ecatalloc(symlinkcontents, fromfile); + access(fromname, F_OK) == 0 && + !itsdir(fromname)) { + const char *s = tofile; + register char * symlinkcontents = NULL; - result = symlink(symlinkcontents, toname); - if (result == 0) -//warning(_("hard link failed, symbolic link used")); - ifree(symlinkcontents); + while ((s = strchr(s+1, '/')) != NULL) + symlinkcontents = + ecatalloc(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) { const char *e = strerror(errno); @@ -799,7 +815,7 @@ associate P((void)) */ eat(zp->z_filename, zp->z_linenum); zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), - TRUE); + TRUE); /* ** Note, though, that if there's no rule, ** 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 < max_time && 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; } } @@ -1135,11 +1153,11 @@ const int nfields; dayoff = 0; cp = fields[LP_YEAR]; if (sscanf(cp, scheck(cp, "%d"), &year) != 1) { - /* - * Leapin' Lizards! - */ - error(_("invalid leaping year")); - return; + /* + ** Leapin' Lizards! + */ + error(_("invalid leaping year")); + return; } j = EPOCH_YEAR; while (j != year) { @@ -1206,7 +1224,9 @@ const int nfields; return; } 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; } leapadd(tadd(t, tod), positive, lp->l_value, count); @@ -1468,14 +1488,13 @@ const char * const name; while (fromi < timecnt && attypes[fromi].type == 0) ++fromi; /* handled by default rule */ for ( ; fromi < timecnt; ++fromi) { - if (toi != 0 - && ((attypes[fromi].at - + gmtoffs[attypes[toi - 1].type]) - <= (attypes[toi - 1].at - + gmtoffs[toi == 1 ? 0 - : attypes[toi - 2].type]))) { - attypes[toi - 1].type = attypes[fromi].type; - continue; + if (toi != 0 && ((attypes[fromi].at + + gmtoffs[attypes[toi - 1].type]) <= + (attypes[toi - 1].at + gmtoffs[toi == 1 ? 0 + : attypes[toi - 2].type]))) { + attypes[toi - 1].type = + attypes[fromi].type; + continue; } if (toi == 0 || attypes[toi - 1].type != attypes[fromi].type) @@ -1521,7 +1540,8 @@ const char * const name; convert(eitol(typecnt), tzh.tzh_typecnt); convert(eitol(charcnt), tzh.tzh_charcnt); (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_reserved); DO(tzh_ttisgmtcnt); @@ -1740,12 +1760,13 @@ const int zonecount; continue; } if (*startbuf == '\0' && - startoff == oadd(zp->z_gmtoff, - stdoff)) { - doabbr(startbuf, zp->z_format, - rp->r_abbrvar, - rp->r_stdoff != 0); - } + startoff == oadd(zp->z_gmtoff, + stdoff)) + doabbr(startbuf, + zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != + 0); } eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); @@ -2036,7 +2057,9 @@ register char * cp; else while ((*dp = *cp++) != '"') if (*dp != '\0') ++dp; - else error(_("Odd number of quotation marks")); + else error(_( + "Odd number of quotation marks" + )); } while (*cp != '\0' && *cp != '#' && (!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 (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)) @@ -2176,6 +2200,41 @@ const char * const string; { 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; if (charcnt + i > TZ_MAX_CHARS) { error(_("too many, or too long, time zone abbreviations")); diff --git a/src/system/libroot/posix/time/localtime.c b/src/system/libroot/posix/time/localtime.c index d4d7a37550..a170741569 100644 --- a/src/system/libroot/posix/time/localtime.c +++ b/src/system/libroot/posix/time/localtime.c @@ -5,7 +5,7 @@ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)localtime.c 7.89"; +static char elsieid[] = "@(#)localtime.c 7.95"; #endif /* !defined NOID */ #endif /* !defined lint */ @@ -20,6 +20,20 @@ static char elsieid[] = "@(#)localtime.c 7.89"; #include "private.h" #include "tzfile.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. @@ -46,9 +60,9 @@ static char elsieid[] = "@(#)localtime.c 7.89"; ** 5. They might reference tm.TM_ZONE after calling offtime. ** 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 -** 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. -** 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 ** that tzname[0] has the "normal" length of three characters). */ @@ -123,6 +137,7 @@ struct rule { static long detzcode P((const char * codep)); 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, int max)); static const char * getsecs P((const char * strp, long * secsp)); @@ -268,6 +283,24 @@ settzname P((void)) tzname[ttisp->tt_isdst] = &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 @@ -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 -** 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. */ @@ -468,6 +501,27 @@ register const char * 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. ** Check that the number is within a specified range; if it is not, return @@ -533,7 +587,7 @@ long * const secsp; *secsp += num * SECSPERMIN; if (*strp == ':') { ++strp; - /* `SECSPERMIN' allows for leap seconds. */ + /* `SECSPERMIN' allows for leap seconds. */ strp = getnum(strp, &num, 0, SECSPERMIN); if (strp == NULL) return NULL; @@ -572,7 +626,7 @@ long * const offsetp; /* ** 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. ** Otherwise, return a pointer to the first character not part of the rule. */ @@ -691,7 +745,7 @@ const long offset; 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 ** month. */ @@ -714,7 +768,7 @@ const long offset; /* ** "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 ** from UTC. */ @@ -752,10 +806,18 @@ const int lastditch; stdlen = (sizeof sp->chars) - 1; stdoffset = 0; } else { - name = getzname(name); - stdlen = name - stdname; - if (stdlen < 3) - return -1; + if (*name == '<') { + name++; + stdname = name; + name = getqzname(name, '>'); + if (*name != '>') + return (-1); + stdlen = name - stdname; + name++; + } else { + name = getzname(name); + stdlen = name - stdname; + } if (*name == '\0') return -1; name = getoffset(name, &stdoffset); @@ -766,11 +828,18 @@ const int lastditch; if (load_result != 0) sp->leapcnt = 0; /* so, we're off a little */ if (*name != '\0') { - dstname = name; - name = getzname(name); - dstlen = name - dstname; /* length of DST zone name */ - if (dstlen < 3) - return -1; + if (*name == '<') { + dstname = ++name; + name = getqzname(name, '>'); + if (*name != '>') + 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 != ';') { name = getoffset(name, &dstoffset); if (name == NULL) @@ -1031,7 +1100,7 @@ tzset P((void)) /* ** 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 -** 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.) ** ** The unused offset argument is for the benefit of mktime variants. @@ -1187,7 +1256,7 @@ static int leaps_thru_end_of(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); } @@ -1311,7 +1380,7 @@ register struct tm * const tmp; tmp->tm_min = (int) (rem / SECSPERMIN); /* ** 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; ip = mon_lengths[isleap(y)]; @@ -1325,13 +1394,12 @@ register struct tm * const tmp; return tmp; } - /* ** Adapted from code provided by Robert Elz, who writes: ** 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@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 ** would still be very reasonable). */ @@ -1481,7 +1549,7 @@ const int do_norm_secs; return WRONG; yourtm.tm_year = y; if (yourtm.tm_year != y) - return WRONG; + return WRONG; if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) saved_seconds = 0; else if (y + TM_YEAR_BASE < EPOCH_YEAR) { @@ -1802,7 +1870,7 @@ time_t t; tzset(); /* ** 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, ** so we return an adjacent second. */ diff --git a/src/system/libroot/posix/time/strftime.c b/src/system/libroot/posix/time/strftime.c index a0bf8639b5..af328ce547 100644 --- a/src/system/libroot/posix/time/strftime.c +++ b/src/system/libroot/posix/time/strftime.c @@ -1,6 +1,6 @@ #ifndef lint #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. ** 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, ** advertising materials, and other materials related to such ** distribution and use acknowledge that the software was developed -** by the University of California, Berkeley. The name of the +** by the University of California, Berkeley. The name of the ** University may not be used to endorse or promote products derived ** from this software without specific prior written permission. ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR @@ -91,7 +91,7 @@ static const struct lc_time_T C_time_locale = { ** 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. */ "%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 * _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 *)); extern char * tzname[]; @@ -264,7 +265,7 @@ label: ** t->tm_hour % 12 : 12, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbins' - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ @@ -284,7 +285,7 @@ label: ** _conv(t->tm_hour, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbin's - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ @@ -359,7 +360,7 @@ label: case 'G': /* ISO 8601 year (four 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 ** (01-53)." ** (ado, 1993-05-24) @@ -372,7 +373,7 @@ label: ** 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 ** 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..." ** (ado, 1996-01-02) */ @@ -512,12 +513,12 @@ label: /* ** C99 says that the UTC offset must ** be computed by looking only at - ** tm_isdst. This requirement is + ** 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 + ** offset. Doing things correctly is ** tricky and requires disobeying C99; ** see GNU C strftime for details. ** For now, punt and conform to the @@ -559,7 +560,7 @@ label: case '%': /* ** 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. */ default: @@ -682,7 +683,7 @@ _loc P((void)) ** Slurp the locale file into the cache. */ namesize = strlen(name) + 1; - if (sizeof filename < + if (sizeof filename < ((sizeof locale_home) + namesize + (sizeof lc_time))) goto no_locale; oldsun = 0; @@ -705,7 +706,7 @@ _loc P((void)) goto bad_locale; bufsize = namesize + st.st_size; locale_buf = NULL; - lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize); + lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize); if (lbuf == NULL) goto bad_locale; (void) strcpy(lbuf, name);