X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..374ca955a76ecab1204ca8bfa63ff9238d998416:/icuSources/tools/tzcode/patch-icu-tzcode diff --git a/icuSources/tools/tzcode/patch-icu-tzcode b/icuSources/tools/tzcode/patch-icu-tzcode new file mode 100644 index 00000000..37da1380 --- /dev/null +++ b/icuSources/tools/tzcode/patch-icu-tzcode @@ -0,0 +1,475 @@ +diff -u -r ../tzcode.orig/Makefile ./Makefile +--- ../tzcode.orig/Makefile 2003-12-15 06:33:34.000000000 -0800 ++++ ./Makefile 2004-05-24 14:30:31.659356800 -0700 +@@ -40,7 +40,7 @@ + # (and subdirectories). + # Use an absolute path name for TZDIR unless you're just testing the software. + +-TZDIR= $(TOPDIR)/etc/zoneinfo ++TZDIR= zoneinfo + + # The "tzselect", "zic", and "zdump" commands get installed in. . . + +@@ -239,9 +239,11 @@ + + ############################################################################### + +-cc= cc ++cc= gcc + CC= $(cc) -DTZDIR=\"$(TZDIR)\" + ++CPP= g++ ++ + TZCSRCS= zic.c localtime.c asctime.c scheck.c ialloc.c + TZCOBJS= zic.o localtime.o asctime.o scheck.o ialloc.o + TZDSRCS= zdump.c localtime.c asctime.c ialloc.c +@@ -275,7 +277,10 @@ + + SHELL= /bin/sh + +-all: tzselect zic zdump $(LIBOBJS) ++LS= /usr/bin/ls ++SED= /usr/bin/sed ++ ++all: tzselect zic zdump $(LIBOBJS) tz2icu + + ALL: all date + +@@ -308,9 +313,12 @@ + zdump: $(TZDOBJS) + $(CC) $(CFLAGS) $(LFLAGS) $(TZDOBJS) $(LDLIBS) -o $@ + +-zic: $(TZCOBJS) yearistype ++zic: $(TZCOBJS) yearistype tz2icu.h + $(CC) $(CFLAGS) $(LFLAGS) $(TZCOBJS) $(LDLIBS) -o $@ + ++tz2icu: tz2icu.cpp tz2icu.h ++ $(CPP) -W -Wall -pedantic tz2icu.cpp -o $@ ++ + yearistype: yearistype.sh + cp yearistype.sh yearistype + chmod +x yearistype +@@ -321,6 +329,9 @@ + right_only: zic leapseconds $(TDATA) + $(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L leapseconds $(TDATA) + ++icu_data: tz2icu posix_only ++ ./tz2icu zoneinfo zone.tab `$(LS) tzdata*.tar.gz | $(SED) -e "s/^tzdata//;s/\.tar\.gz$$//"` ++ + # In earlier versions of this makefile, the other two directories were + # subdirectories of $(TZDIR). However, this led to configuration errors. + # For example, with posix_right under the earlier scheme, +diff -u -r ../tzcode.orig/zic.c ./zic.c +--- ../tzcode.orig/zic.c 2003-12-15 06:36:35.000000000 -0800 ++++ ./zic.c 2004-05-24 14:03:43.937566400 -0700 +@@ -13,6 +13,20 @@ + #define MKDIR_UMASK 0755 + #endif + ++/* Enable extensions and modifications for ICU. */ ++#define ICU ++ ++/* Continue executing after link failure. Even if ICU is undefined ++ * (for vanilla zic behavior), ICU_LINKS should be defined, since zic ++ * appears to fail on the 2003 data the first time through during the ++ * linking phase. Running zic twice, with ICU_LINKS defined, causes ++ * links to be handled correctly. */ ++#define ICU_LINKS ++ ++#ifdef ICU ++#include "tz2icu.h" ++#endif ++ + /* + ** On some ancient hosts, predicates like `isspace(C)' are defined + ** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, +@@ -86,8 +100,14 @@ + extern int optind; + + static void addtt P((time_t starttime, int type)); ++#ifdef ICU ++static int addtype P((long gmtoff, long rawoff, long dstoff, ++ const char * abbr, int isdst, ++ int ttisstd, int ttisgmt)); ++#else + static int addtype P((long gmtoff, const char * abbr, int isdst, + int ttisstd, int ttisgmt)); ++#endif + static void leapadd P((time_t t, int positive, int rolling, int count)); + static void adjleap P((void)); + static void associate P((void)); +@@ -256,6 +276,18 @@ + const int l_value; + }; + ++#ifdef ICU ++ ++/* Indices into rules[] for final rules. They will occur in pairs, ++ * with finalRules[i] occurring before finalRules[i+1] in the year. ++ * Each zone need only store a start year, a standard offset, and an ++ * index into finalRules[]. FinalRules[] are aliases into rules[]. */ ++ ++static const struct rule ** finalRules; ++static int finalRulesCount; ++ ++#endif ++ + static struct lookup const * byword P((const char * string, + const struct lookup * lp)); + +@@ -338,6 +370,11 @@ + unsigned char type; + } attypes[TZ_MAX_TIMES]; + static long gmtoffs[TZ_MAX_TYPES]; ++#ifdef ICU ++/* gmtoffs[i] = rawoffs[i] + dstoffs[i] */ ++static long rawoffs[TZ_MAX_TYPES]; ++static long dstoffs[TZ_MAX_TYPES]; ++#endif + static char isdsts[TZ_MAX_TYPES]; + static unsigned char abbrinds[TZ_MAX_TYPES]; + static char ttisstds[TZ_MAX_TYPES]; +@@ -447,6 +484,62 @@ + (void) exit(EXIT_FAILURE); + } + ++#ifdef ICU ++ ++/* File into which we will write supplemental ICU data. */ ++static FILE * icuFile; ++ ++void emit_icu_zone(FILE* f, const char* zoneName, int zoneOffset, ++ const struct rule* rule, ++ int ruleIndex, int startYear) { ++ /* machine-readable section */ ++ fprintf(f, "zone %s %d %d %s", zoneName, zoneOffset, startYear, rule->r_name); ++ ++ /* human-readable section */ ++ fprintf(f, " # zone %s, offset %d, year >= %d, rule %s (%d)\n", ++ zoneName, zoneOffset, startYear, ++ rule->r_name, ruleIndex); ++} ++ ++void emit_icu_link(FILE* f, const char* from, const char* to) { ++ /* machine-readable section */ ++ fprintf(f, "link %s %s\n", from, to); ++} ++ ++static const char* DYCODE[] = {"DOM", "DOWGEQ", "DOWLEQ"}; ++ ++void emit_icu_rule(FILE* f, const struct rule* r, int ruleIndex) { ++ if (r->r_yrtype != NULL) { ++ warning("year types not supported by ICU"); ++ fprintf(stderr, "rule %s, file %s, line %d\n", ++ r->r_name, r->r_filename, r->r_linenum); ++ } ++ ++ /* machine-readable section */ ++ fprintf(f, "rule %s %s %d %d %d %d %d %d %d", ++ r->r_name, DYCODE[r->r_dycode], ++ r->r_month, r->r_dayofmonth, ++ (r->r_dycode == DC_DOM ? -1 : r->r_wday), ++ r->r_tod, r->r_todisstd, r->r_todisgmt, r->r_stdoff ++ ); ++ ++ /* human-readable section */ ++ fprintf(f, " # %d: %s, file %s, line %d", ++ ruleIndex, r->r_name, r->r_filename, r->r_linenum); ++ fprintf(f, ", mode %s", DYCODE[r->r_dycode]); ++ fprintf(f, ", %s, dom %d", mon_names[r->r_month].l_word, r->r_dayofmonth); ++ if (r->r_dycode != DC_DOM) { ++ fprintf(f, ", %s", wday_names[r->r_wday].l_word); ++ } ++ fprintf(f, ", time %d", r->r_tod); ++ fprintf(f, ", isstd %d", r->r_todisstd); ++ fprintf(f, ", isgmt %d", r->r_todisgmt); ++ fprintf(f, ", offset %ld", r->r_stdoff); ++ fprintf(f, "\n"); ++} ++ ++#endif ++ + static const char * psxrules; + static const char * lcltime; + static const char * directory; +@@ -554,6 +647,14 @@ + adjleap(); + } + ++#ifdef ICU ++ if ((icuFile = fopen(ICU_ZONE_FILE, "w")) == NULL) { ++ const char *e = strerror(errno); ++ (void) fprintf(stderr, _("%s: Can't open %s: %s\n"), ++ progname, ICU_ZONE_FILE, e); ++ (void) exit(EXIT_FAILURE); ++ } ++#endif + for (i = optind; i < argc; ++i) + infile(argv[i]); + if (errors) +@@ -573,6 +674,9 @@ + for (i = 0; i < nlinks; ++i) { + eat(links[i].l_filename, links[i].l_linenum); + dolink(links[i].l_from, links[i].l_to); ++#ifdef ICU ++ emit_icu_link(icuFile, links[i].l_from, links[i].l_to); ++#endif + } + if (lcltime != NULL) { + eat("command line", 1); +@@ -582,6 +686,11 @@ + eat("command line", 1); + dolink(psxrules, TZDEFRULES); + } ++#ifdef ICU ++ for (i=0; iz_filename, zp->z_linenum); + *startbuf = '\0'; + startoff = zp->z_gmtoff; ++#ifdef ICU ++ finalRuleYear = finalRuleIndex = -1; ++ finalRule1 = finalRule2 = NULL; ++ if (i == (zonecount - 1)) { /* !useuntil */ ++ /* Look for exactly 2 rules that end at 'max' and ++ * note them. Determine max(r_loyear) for the 2 of ++ * them. */ ++ for (j=0; jz_nrules; ++j) { ++ rp = &zp->z_rules[j]; ++ if (rp->r_hiyear == INT_MAX) { ++ if (finalRule1 == NULL) { ++ finalRule1 = rp; ++ finalRuleYear = rp->r_loyear; ++ } else if (finalRule2 == NULL) { ++ finalRule2 = rp; ++ if (rp->r_loyear > finalRuleYear) { ++ finalRuleYear = rp->r_loyear; ++ } ++ } else { ++ error("more than two max rules found (ICU)"); ++ exit(EXIT_FAILURE); ++ } ++ } ++ } ++ if (finalRule1 != NULL && finalRule2 == NULL) { ++ error("only one max rule found (ICU)"); ++ exit(EXIT_FAILURE); ++ } ++ if (finalRule1 != NULL) { ++ /* Swap if necessary so finalRule1 occurs before ++ * finalRule2 */ ++ if (finalRule1->r_month > finalRule2->r_month) { ++ const struct rule* t = finalRule1; ++ finalRule1 = finalRule2; ++ finalRule2 = t; ++ } ++ /* Add final rule to our list */ ++ finalRuleIndex = add_icu_final_rules(finalRule1, finalRule2); ++ } ++ } ++#endif + if (zp->z_nrules == 0) { + stdoff = zp->z_stdoff; + doabbr(startbuf, zp->z_format, + (char *) NULL, stdoff != 0); + type = addtype(oadd(zp->z_gmtoff, stdoff), ++#ifdef ICU ++ zp->z_gmtoff, stdoff, ++#endif + startbuf, stdoff != 0, startttisstd, + startttisgmt); + if (usestart) { +@@ -1708,6 +1896,15 @@ + break; /* go on to next year */ + rp = &zp->z_rules[k]; + rp->r_todo = FALSE; ++#ifdef ICU ++ if (year >= finalRuleYear && rp == finalRule1) { ++ emit_icu_zone(icuFile, ++ zpfirst->z_name, zp->z_gmtoff, ++ rp, finalRuleIndex, year); ++ /* only emit this for the first year */ ++ finalRule1 = NULL; ++ } ++#endif + if (useuntil && ktime >= untiltime) + break; + stdoff = rp->r_stdoff; +@@ -1735,8 +1932,14 @@ + doabbr(buf, zp->z_format, rp->r_abbrvar, + rp->r_stdoff != 0); + offset = oadd(zp->z_gmtoff, rp->r_stdoff); ++#ifdef ICU ++ type = addtype(offset, zp->z_gmtoff, rp->r_stdoff, ++ buf, rp->r_stdoff != 0, ++ rp->r_todisstd, rp->r_todisgmt); ++#else + type = addtype(offset, buf, rp->r_stdoff != 0, + rp->r_todisstd, rp->r_todisgmt); ++#endif + addtt(ktime, type); + } + } +@@ -1750,10 +1953,19 @@ + if (*startbuf == '\0') + error(_("can't determine time zone abbreviation to use just after until time")); + else addtt(starttime, ++#ifdef ICU ++ addtype(startoff, ++ zp->z_gmtoff, startoff - zp->z_gmtoff, ++ startbuf, ++ startoff != zp->z_gmtoff, ++ startttisstd, ++ startttisgmt)); ++#else + addtype(startoff, startbuf, + startoff != zp->z_gmtoff, + startttisstd, + startttisgmt)); ++#endif + } + /* + ** Now we may get to set starttime for the next zone line. +@@ -1779,6 +1991,10 @@ + if (starttime <= min_time || + (timecnt == 1 && attypes[0].at < min_time)) { + gmtoffs[0] = gmtoffs[type]; ++#ifdef ICU ++ rawoffs[0] = rawoffs[type]; ++ dstoffs[0] = dstoffs[type]; ++#endif + isdsts[0] = isdsts[type]; + ttisstds[0] = ttisstds[type]; + ttisgmts[0] = ttisgmts[type]; +@@ -1800,8 +2016,15 @@ + } + + static int ++#ifdef ICU ++addtype(gmtoff, rawoff, dstoff, abbr, isdst, ttisstd, ttisgmt) ++const long gmtoff; ++const long rawoff; ++const long dstoff; ++#else + addtype(gmtoff, abbr, isdst, ttisstd, ttisgmt) + const long gmtoff; ++#endif + const char * const abbr; + const int isdst; + const int ttisstd; +@@ -1821,12 +2044,25 @@ + error(_("internal error - addtype called with bad ttisgmt")); + (void) exit(EXIT_FAILURE); + } ++#ifdef ICU ++ if (isdst != (dstoff != 0)) { ++ error(_("internal error - addtype called with bad isdst/dstoff")); ++ (void) exit(EXIT_FAILURE); ++ } ++ if (gmtoff != (rawoff + dstoff)) { ++ error(_("internal error - addtype called with bad gmt/raw/dstoff")); ++ (void) exit(EXIT_FAILURE); ++ } ++#endif + /* + ** See if there's already an entry for this zone type. + ** If so, just return its index. + */ + for (i = 0; i < typecnt; ++i) { + if (gmtoff == gmtoffs[i] && isdst == isdsts[i] && ++#ifdef ICU ++ rawoff == rawoffs[i] && dstoff == dstoffs[i] && ++#endif + strcmp(abbr, &chars[abbrinds[i]]) == 0 && + ttisstd == ttisstds[i] && + ttisgmt == ttisgmts[i]) +@@ -1841,6 +2077,10 @@ + (void) exit(EXIT_FAILURE); + } + gmtoffs[i] = gmtoff; ++#ifdef ICU ++ rawoffs[i] = rawoff; ++ dstoffs[i] = dstoff; ++#endif + isdsts[i] = isdst; + ttisstds[i] = ttisstd; + ttisgmts[i] = ttisgmt;