From fa12e0eeff27404ac12734c292ac0ec33b60081c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Wed, 2 Feb 2005 22:25:37 +0000 Subject: [PATCH] Updated to tzcode2005c.tar.gz git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11227 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/bin/zic/zdump.c | 342 ++++++++++++++++++++++++++++++--------- src/apps/bin/zic/zic.c | 85 ++++++---- 2 files changed, 319 insertions(+), 108 deletions(-) diff --git a/src/apps/bin/zic/zdump.c b/src/apps/bin/zic/zdump.c index 6e697f3f33..bd7132698f 100644 --- a/src/apps/bin/zic/zdump.c +++ b/src/apps/bin/zic/zdump.c @@ -1,4 +1,4 @@ -static char elsieid[] = "@(#)zdump.c 7.47"; +static char elsieid[] = "@(#)zdump.c 7.61"; /* ** This code has been made independent of the rest of the time @@ -11,6 +11,15 @@ static char elsieid[] = "@(#)zdump.c 7.47"; #include "sys/types.h" /* for time_t */ #include "time.h" /* for struct tm */ #include "stdlib.h" /* for exit, malloc, atoi */ +#include "float.h" /* for FLT_MAX and DBL_MAX */ + +#ifndef ZDUMP_LO_YEAR +#define ZDUMP_LO_YEAR (-500) +#endif /* !defined ZDUMP_LO_YEAR */ + +#ifndef ZDUMP_HI_YEAR +#define ZDUMP_HI_YEAR 2500 +#endif /* !defined ZDUMP_HI_YEAR */ #ifndef MAX_STRING_LENGTH #define MAX_STRING_LENGTH 1024 @@ -71,6 +80,10 @@ static char elsieid[] = "@(#)zdump.c 7.47"; #define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) #endif /* !defined isleap_sum */ +#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) +#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR) +#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY) + #if HAVE_GETTEXT #include "locale.h" /* for setlocale */ #include "libintl.h" @@ -122,18 +135,60 @@ static char elsieid[] = "@(#)zdump.c 7.47"; extern char ** environ; extern int getopt P((int argc, char * const argv[], - const char * options)); + const char * options)); extern char * optarg; extern int optind; extern char * tzname[2]; -static char * abbr P((struct tm * tmp)); -static long delta P((struct tm * newp, struct tm * oldp)); -static time_t hunt P((char * name, time_t lot, time_t hit)); +static time_t absolute_min_time; +static time_t absolute_max_time; static size_t longest; static char * progname; -static void show P((char * zone, time_t t, int v)); + +static char * abbr P((struct tm * tmp)); +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)); +static void setabsolutes P((void)); +static void show P((char * zone, time_t t, int v)); +static const char * tformat P((void)); +static time_t yeartot P((long y)); + +#ifndef TYPECHECK +#define my_localtime localtime +#else /* !defined TYPECHECK */ +static struct tm * +my_localtime(tp) +time_t * tp; +{ + register struct tm * tmp; + + tmp = localtime(tp); + if (tp != NULL && tmp != NULL) { + struct tm tm; + register time_t t; + + tm = *tmp; + t = mktime(&tm); + if (t - *tp >= 1 || *tp - t >= 1) { + (void) fflush(stdout); + (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, " -> "); + (void) fprintf(stderr, tformat(), t); + (void) fprintf(stderr, "\n"); + } + } + return tmp; +} +#endif /* !defined TYPECHECK */ int main(argc, argv) @@ -143,18 +198,22 @@ char * argv[]; register int i; register int c; register int vflag; - register char * cutoff; - register int cutyear; - register long cuttime; - char ** fakeenv; + register char * cutarg; + register long cutloyear = ZDUMP_LO_YEAR; + register long cuthiyear = ZDUMP_HI_YEAR; + register time_t cutlotime; + register time_t cuthitime; + register char ** fakeenv; time_t now; time_t t; time_t newt; - time_t hibit; struct tm tm; struct tm newtm; + register struct tm * tmp; + register struct tm * newtmp; - INITIALIZE(cuttime); + INITIALIZE(cutlotime); + INITIALIZE(cuthitime); #if HAVE_GETTEXT (void) setlocale(LC_MESSAGES, ""); #ifdef TZ_DOMAINDIR @@ -169,39 +228,50 @@ char * argv[]; (void) exit(EXIT_SUCCESS); } vflag = 0; - cutoff = NULL; + cutarg = NULL; while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v') if (c == 'v') vflag = 1; - else cutoff = optarg; + else cutarg = optarg; if ((c != EOF && c != -1) || (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) { (void) fprintf(stderr, -_("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"), - argv[0], argv[0]); +_("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"), + progname, progname); (void) exit(EXIT_FAILURE); } - if (cutoff != NULL) { - int y; + if (vflag) { + if (cutarg != NULL) { + long lo; + long hi; + char dummy; - cutyear = atoi(cutoff); - cuttime = 0; - for (y = EPOCH_YEAR; y < cutyear; ++y) - cuttime += DAYSPERNYEAR + isleap(y); - cuttime *= SECSPERHOUR * HOURSPERDAY; + if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) { + cuthiyear = hi; + } else if (sscanf(cutarg, "%ld,%ld%c", + &lo, &hi, &dummy) == 2) { + cutloyear = lo; + cuthiyear = hi; + } else { +(void) fprintf(stderr, _("%s: wild -c argument %s\n"), + progname, cutarg); + (void) exit(EXIT_FAILURE); + } + } + setabsolutes(); + cutlotime = yeartot(cutloyear); + cuthitime = yeartot(cuthiyear); } (void) time(&now); longest = 0; for (i = optind; i < argc; ++i) if (strlen(argv[i]) > longest) longest = strlen(argv[i]); - for (hibit = 1; (hibit << 1) != 0; hibit <<= 1) - continue; { register int from; register int to; - for (i = 0; environ[i] != NULL; ++i) + for (i = 0; environ[i] != NULL; ++i) continue; fakeenv = (char **) malloc((size_t) ((i + 2) * sizeof *fakeenv)); @@ -226,58 +296,129 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"), show(argv[i], now, FALSE); continue; } - /* - ** Get lowest value of t. - */ - t = hibit; - if (t > 0) /* time_t is unsigned */ - t = 0; + t = absolute_min_time; show(argv[i], t, TRUE); t += SECSPERHOUR * HOURSPERDAY; show(argv[i], t, TRUE); - tm = *localtime(&t); - (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1); + if (t < cutlotime) + t = cutlotime; + tmp = my_localtime(&t); + if (tmp != NULL) { + tm = *tmp; + (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1); + } for ( ; ; ) { - if (cutoff != NULL && t >= cuttime) + if (t >= cuthitime) break; newt = t + SECSPERHOUR * 12; - if (cutoff != NULL && newt >= cuttime) + if (newt >= cuthitime) break; if (newt <= t) break; - newtm = *localtime(&newt); - if (delta(&newtm, &tm) != (newt - t) || + newtmp = localtime(&newt); + if (newtmp != NULL) + newtm = *newtmp; + if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) : + (delta(&newtm, &tm) != (newt - t) || newtm.tm_isdst != tm.tm_isdst || - strcmp(abbr(&newtm), buf) != 0) { + strcmp(abbr(&newtm), buf) != 0)) { newt = hunt(argv[i], t, newt); - newtm = *localtime(&newt); - (void) strncpy(buf, abbr(&newtm), - (sizeof buf) - 1); + newtmp = localtime(&newt); + if (newtmp != NULL) { + newtm = *newtmp; + (void) strncpy(buf, + abbr(&newtm), + (sizeof buf) - 1); + } } t = newt; tm = newtm; + tmp = newtmp; } - /* - ** Get highest value of t. - */ - t = ~((time_t) 0); - if (t < 0) /* time_t is signed */ - t &= ~hibit; + t = absolute_max_time; t -= SECSPERHOUR * HOURSPERDAY; show(argv[i], t, TRUE); t += SECSPERHOUR * HOURSPERDAY; show(argv[i], t, TRUE); } if (fflush(stdout) || ferror(stdout)) { - (void) fprintf(stderr, "%s: ", argv[0]); + (void) fprintf(stderr, "%s: ", progname); (void) perror(_("Error writing standard output")); (void) exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); + /* If exit fails to exit... */ + return EXIT_FAILURE; +} - /* gcc -Wall pacifier */ - for ( ; ; ) - continue; +static void +setabsolutes() +{ + if (0.5 == (time_t) 0.5) { + /* + ** time_t is floating. + */ + if (sizeof (time_t) == sizeof (float)) { + absolute_min_time = (time_t) -FLT_MAX; + absolute_max_time = (time_t) FLT_MAX; + } else if (sizeof (time_t) == sizeof (double)) { + absolute_min_time = (time_t) -DBL_MAX; + absolute_max_time = (time_t) DBL_MAX; + } else { + (void) fprintf(stderr, +_("%s: use of -v on system with floating time_t other than float or double\n"), + progname); + (void) exit(EXIT_FAILURE); + } + } else if (0 > (time_t) -1) { + /* + ** time_t is signed. + */ + register time_t hibit; + + for (hibit = 1; (hibit * 2) != 0; hibit *= 2) + continue; + absolute_min_time = hibit; + absolute_max_time = -(hibit + 1); + } else { + /* + ** time_t is unsigned. + */ + absolute_min_time = 0; + absolute_max_time = absolute_min_time - 1; + } +} + +static time_t +yeartot(y) +const long y; +{ + register long myy; + register long seconds; + register time_t t; + + myy = EPOCH_YEAR; + t = 0; + while (myy != y) { + if (myy < y) { + seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR; + ++myy; + if (t > absolute_max_time - seconds) { + t = absolute_max_time; + break; + } + t += seconds; + } else { + --myy; + seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR; + if (t < absolute_min_time + seconds) { + t = absolute_min_time; + break; + } + t -= seconds; + } + } + return t; } static time_t @@ -286,25 +427,39 @@ char * name; time_t lot; time_t hit; { - time_t t; - struct tm lotm; - struct tm tm; - static char loab[MAX_STRING_LENGTH]; + time_t t; + long diff; + struct tm lotm; + register struct tm * lotmp; + struct tm tm; + register struct tm * tmp; + char loab[MAX_STRING_LENGTH]; - lotm = *localtime(&lot); - (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1); - while ((hit - lot) >= 2) { - t = lot / 2 + hit / 2; + lotmp = my_localtime(&lot); + if (lotmp != NULL) { + lotm = *lotmp; + (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1); + } + for ( ; ; ) { + diff = (long) (hit - lot); + if (diff < 2) + break; + t = lot; + t += diff / 2; if (t <= lot) ++t; else if (t >= hit) --t; - tm = *localtime(&t); - if (delta(&tm, &lotm) == (t - lot) && + tmp = my_localtime(&t); + if (tmp != NULL) + tm = *tmp; + if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) : + (delta(&tm, &lotm) == (t - lot) && tm.tm_isdst == lotm.tm_isdst && - strcmp(abbr(&tm), loab) == 0) { + strcmp(abbr(&tm), loab) == 0)) { lot = t; lotm = tm; + lotmp = tmp; } else hit = t; } show(name, lot, TRUE); @@ -321,8 +476,8 @@ delta(newp, oldp) struct tm * newp; struct tm * oldp; { - long result; - int tmy; + register long result; + register int tmy; if (newp->tm_year < oldp->tm_year) return -delta(oldp, newp); @@ -345,22 +500,30 @@ char * zone; time_t t; int v; { - struct tm * tmp; + register struct tm * tmp; (void) printf("%-*s ", (int) longest, zone); if (v) { - dumptime(gmtime(&t)); - (void) printf(" UTC = "); + tmp = gmtime(&t); + if (tmp == NULL) { + (void) printf(tformat(), t); + } else { + dumptime(tmp); + (void) printf(" UTC"); + } + (void) printf(" = "); } - tmp = localtime(&t); + tmp = my_localtime(&t); dumptime(tmp); - if (*abbr(tmp) != '\0') - (void) printf(" %s", abbr(tmp)); - if (v) { - (void) printf(" isdst=%d", tmp->tm_isdst); + if (tmp != NULL) { + if (*abbr(tmp) != '\0') + (void) printf(" %s", abbr(tmp)); + if (v) { + (void) printf(" isdst=%d", tmp->tm_isdst); #ifdef TM_GMTOFF - (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); + (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); #endif /* defined TM_GMTOFF */ + } } (void) printf("\n"); } @@ -378,6 +541,33 @@ struct tm * tmp; return (result == NULL) ? &nada : result; } +/* +** The code below can fail on certain theoretical systems; +** it works on all known real-world systems as of 2004-12-30. +*/ + +static const char * +tformat() +{ + if (0.5 == (time_t) 0.5) { /* floating */ + if (sizeof (time_t) > sizeof (double)) + return "%Lg"; + return "%g"; + } + if (0 > (time_t) -1) { /* signed */ + if (sizeof (time_t) > sizeof (long)) + return "%lld"; + if (sizeof (time_t) > sizeof (int)) + return "%ld"; + return "%d"; + } + if (sizeof (time_t) > sizeof (unsigned long)) + return "%llu"; + if (sizeof (time_t) > sizeof (unsigned int)) + return "%lu"; + return "%u"; +} + static void dumptime(timeptr) register const struct tm * timeptr; @@ -394,6 +584,10 @@ register const struct tm * timeptr; register int lead; register int trail; + if (timeptr == NULL) { + (void) printf("NULL"); + return; + } /* ** The packaged versions of localtime and gmtime never put out-of-range ** values in tm_wday or tm_mon, but since this code might be compiled diff --git a/src/apps/bin/zic/zic.c b/src/apps/bin/zic/zic.c index 47246811f6..b7d9ec0d7e 100644 --- a/src/apps/bin/zic/zic.c +++ b/src/apps/bin/zic/zic.c @@ -1,4 +1,10 @@ -static char elsieid[] = "@(#)zic.c 7.116"; +static char elsieid[] = "@(#)zic.c 7.118"; + +/* +** Regardless of the type of time_t, we do our work using this type. +*/ + +typedef int zic_t; #include "private.h" #include "locale.h" @@ -50,7 +56,7 @@ struct rule { const char * r_abbrvar; /* variable part of abbreviation */ int r_todo; /* a rule to do (used in outzone) */ - time_t r_temp; /* used in outzone */ + zic_t r_temp; /* used in outzone */ }; /* @@ -76,7 +82,7 @@ struct zone { int z_nrules; struct rule z_untilrule; - time_t z_untiltime; + zic_t z_untiltime; }; extern int getopt P((int argc, char * const argv[], @@ -85,10 +91,10 @@ extern int link P((const char * fromname, const char * toname)); extern char * optarg; extern int optind; -static void addtt P((time_t starttime, int type)); +static void addtt P((zic_t starttime, int type)); static int addtype P((long gmtoff, const char * abbr, int isdst, int ttisstd, int ttisgmt)); -static void leapadd P((time_t t, int positive, int rolling, int count)); +static void leapadd P((zic_t t, int positive, int rolling, int count)); static void adjleap P((void)); static void associate P((void)); static int ciequal P((const char * ap, const char * bp)); @@ -121,13 +127,13 @@ static long oadd P((long t1, long t2)); static void outzone P((const struct zone * zp, int ntzones)); static void puttzcode P((long code, FILE * fp)); static int rcomp P((const void * leftp, const void * rightp)); -static time_t rpytime P((const struct rule * rp, int wantedy)); +static zic_t rpytime P((const struct rule * rp, int wantedy)); static void rulesub P((struct rule * rp, const char * loyearp, const char * hiyearp, const char * typep, const char * monthp, const char * dayp, const char * timep)); static void setboundaries P((void)); -static time_t tadd P((time_t t1, long t2)); +static zic_t tadd P((zic_t t1, long t2)); static void usage P((void)); static void writezone P((const char * name)); static int yearistype P((int year, const char * type)); @@ -141,10 +147,10 @@ static int errors; static const char * filename; static int leapcnt; static int linenum; -static time_t max_time; +static zic_t max_time; static int max_year; static int max_year_representable; -static time_t min_time; +static zic_t min_time; static int min_year; static int min_year_representable; static int noise; @@ -334,7 +340,7 @@ static const int len_years[2] = { }; static struct attype { - time_t at; + zic_t at; unsigned char type; } attypes[TZ_MAX_TIMES]; static long gmtoffs[TZ_MAX_TYPES]; @@ -343,7 +349,7 @@ static unsigned char abbrinds[TZ_MAX_TYPES]; static char ttisstds[TZ_MAX_TYPES]; static char ttisgmts[TZ_MAX_TYPES]; static char chars[TZ_MAX_CHARS]; -static time_t trans[TZ_MAX_LEAPS]; +static zic_t trans[TZ_MAX_LEAPS]; static long corr[TZ_MAX_LEAPS]; static char roll[TZ_MAX_LEAPS]; @@ -665,25 +671,36 @@ const char * const tofile; */ #define MAX_BITS_IN_FILE 32 -#define TIME_T_BITS_IN_FILE ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE) +#define TIME_T_BITS_IN_FILE ((TYPE_BIT(zic_t) < MAX_BITS_IN_FILE) ? \ + TYPE_BIT(zic_t) : MAX_BITS_IN_FILE) static void setboundaries P((void)) { - if (TYPE_SIGNED(time_t)) { - min_time = ~ (time_t) 0; - min_time <<= TIME_T_BITS_IN_FILE - 1; - max_time = ~ (time_t) 0 - min_time; + register int i; + + if (TYPE_SIGNED(zic_t)) { + min_time = -1; + for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i) + min_time *= 2; + max_time = -(min_time + 1); if (sflag) min_time = 0; } else { min_time = 0; max_time = 2 - sflag; - max_time <<= TIME_T_BITS_IN_FILE - 1; + for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i) + max_time *= 2; --max_time; } - min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year; - max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year; + { + time_t t; + + t = (time_t) min_time; + min_year = TM_YEAR_BASE + gmtime(&t)->tm_year; + t = (time_t) max_time; + max_year = TM_YEAR_BASE + gmtime(&t)->tm_year; + } min_year_representable = min_year; max_year_representable = max_year; } @@ -1109,7 +1126,7 @@ const int nfields; register int i, j; int year, month, day; long dayoff, tod; - time_t t; + zic_t t; if (nfields != LEAP_FIELDS) { error(_("wrong number of fields on Leap line")); @@ -1153,7 +1170,7 @@ const int nfields; return; } dayoff = oadd(dayoff, eitol(day - 1)); - if (dayoff < 0 && !TYPE_SIGNED(time_t)) { + if (dayoff < 0 && !TYPE_SIGNED(zic_t)) { error(_("time before zero")); return; } @@ -1165,7 +1182,7 @@ const int nfields; error(_("time too large")); return; } - t = (time_t) dayoff * SECSPERDAY; + t = (zic_t) dayoff * SECSPERDAY; tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE); cp = fields[LP_CORR]; { @@ -1427,7 +1444,7 @@ const char * const name; register int i, j; static char * fullname; static struct tzhead tzh; - time_t ats[TZ_MAX_TIMES]; + zic_t ats[TZ_MAX_TIMES]; unsigned char types[TZ_MAX_TIMES]; /* @@ -1592,7 +1609,7 @@ const int zonecount; register struct rule * rp; register int i, j; register int usestart, useuntil; - register time_t starttime, untiltime; + register zic_t starttime, untiltime; register long gmtoff; register long stdoff; register int year; @@ -1661,7 +1678,7 @@ const int zonecount; } for ( ; ; ) { register int k; - register time_t jtime, ktime; + register zic_t jtime, ktime; register long offset; char buf[BUFSIZ]; @@ -1773,7 +1790,7 @@ error(_("can't determine time zone abbreviation to use just after until time")); static void addtt(starttime, type) -const time_t starttime; +const zic_t starttime; int type; { if (starttime <= min_time || @@ -1857,7 +1874,7 @@ const int ttisgmt; static void leapadd(t, positive, rolling, count) -const time_t t; +const zic_t t; const int positive; const int rolling; int count; @@ -2045,12 +2062,12 @@ const long t2; return t; } -static time_t +static zic_t tadd(t1, t2) -const time_t t1; +const zic_t t1; const long t2; { - register time_t t; + register zic_t t; if (t1 == max_time && t2 > 0) return max_time; @@ -2069,14 +2086,14 @@ const long t2; ** 1970, 00:00 LOCAL time - in that year that the rule refers to. */ -static time_t +static zic_t rpytime(rp, wantedy) register const struct rule * const rp; register const int wantedy; { register int y, m, i; register long dayoff; /* with a nod to Margaret O. */ - register time_t t; + register zic_t t; if (wantedy == INT_MIN) return min_time; @@ -2143,13 +2160,13 @@ register const int wantedy; warning(_("rule goes past start/end of month--will not work with pre-2004 versions of zic")); } } - if (dayoff < 0 && !TYPE_SIGNED(time_t)) + if (dayoff < 0 && !TYPE_SIGNED(zic_t)) return min_time; if (dayoff < min_time / SECSPERDAY) return min_time; if (dayoff > max_time / SECSPERDAY) return max_time; - t = (time_t) dayoff * SECSPERDAY; + t = (zic_t) dayoff * SECSPERDAY; return tadd(t, rp->r_tod); }