aff09b5e97
X-SVN-Rev: 19096
475 lines
15 KiB
Plaintext
475 lines
15 KiB
Plaintext
diff -ur ../tzcode.orig/Makefile ./Makefile
|
|
--- ../tzcode.orig/Makefile 2005-06-13 11:33:54.000000000 -0700
|
|
+++ ./Makefile 2005-06-30 16:14:15.000000000 -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. . .
|
|
|
|
@@ -240,9 +240,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 ialloc.c
|
|
@@ -276,7 +278,10 @@
|
|
|
|
SHELL= /bin/sh
|
|
|
|
-all: tzselect zic zdump $(LIBOBJS)
|
|
+LS= /bin/ls
|
|
+SED= sed
|
|
+
|
|
+all: tzselect zic zdump $(LIBOBJS) tz2icu
|
|
|
|
ALL: all date
|
|
|
|
@@ -309,9 +314,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
|
|
@@ -322,6 +330,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,
|
|
--- zic.c.orig 2005-12-22 06:31:15.000000000 -0800
|
|
+++ zic.c 2006-01-19 19:34:06.000000000 -0800
|
|
@@ -23,6 +23,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,
|
|
@@ -96,8 +110,14 @@
|
|
extern int optind;
|
|
|
|
static void addtt P((zic_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((zic_t t, int positive, int rolling, int count));
|
|
static void adjleap P((void));
|
|
static void associate P((void));
|
|
@@ -266,6 +286,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));
|
|
|
|
@@ -348,6 +380,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];
|
|
@@ -459,6 +496,62 @@
|
|
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;
|
|
@@ -566,6 +659,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)
|
|
@@ -585,6 +686,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 (noise)
|
|
for (j = 0; j < nlinks; ++j)
|
|
if (strcmp(links[i].l_to,
|
|
@@ -599,6 +703,11 @@
|
|
eat("command line", 1);
|
|
dolink(psxrules, TZDEFRULES);
|
|
}
|
|
+#ifdef ICU
|
|
+ for (i=0; i<finalRulesCount; ++i) {
|
|
+ emit_icu_rule(icuFile, finalRules[i], i);
|
|
+ }
|
|
+#endif /*ICU*/
|
|
return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
}
|
|
|
|
@@ -664,7 +773,9 @@
|
|
(void) fprintf(stderr,
|
|
_("%s: Can't link from %s to %s: %s\n"),
|
|
progname, fromname, toname, e);
|
|
+#ifndef ICU_LINKS
|
|
exit(EXIT_FAILURE);
|
|
+#endif
|
|
}
|
|
}
|
|
ifree(fromname);
|
|
@@ -1539,7 +1650,12 @@
|
|
convert(eitol(timecnt), tzh.tzh_timecnt);
|
|
convert(eitol(typecnt), tzh.tzh_typecnt);
|
|
convert(eitol(charcnt), tzh.tzh_charcnt);
|
|
+#ifdef ICU
|
|
+ * (ICUZoneinfoVersion*) &tzh.tzh_reserved = TZ_ICU_VERSION;
|
|
+ (void) strncpy(tzh.tzh_magic, TZ_ICU_MAGIC, sizeof tzh.tzh_magic);
|
|
+#else
|
|
(void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
|
|
+#endif
|
|
#define DO(field) (void) fwrite((void *) tzh.field, \
|
|
(size_t) sizeof tzh.field, (size_t) 1, fp)
|
|
DO(tzh_magic);
|
|
@@ -1564,7 +1680,12 @@
|
|
(void) fwrite((void *) types, (size_t) sizeof types[0],
|
|
(size_t) timecnt, fp);
|
|
for (i = 0; i < typecnt; ++i) {
|
|
+#ifdef ICU
|
|
+ puttzcode((long) rawoffs[i], fp);
|
|
+ puttzcode((long) dstoffs[i], fp);
|
|
+#else
|
|
puttzcode((long) gmtoffs[i], fp);
|
|
+#endif
|
|
(void) putc(isdsts[i], fp);
|
|
(void) putc(abbrinds[i], fp);
|
|
}
|
|
@@ -1620,6 +1741,24 @@
|
|
}
|
|
}
|
|
|
|
+#ifdef ICU
|
|
+
|
|
+int add_icu_final_rules(const struct rule* r1, const struct rule* r2) {
|
|
+ int i;
|
|
+
|
|
+ for (i=0; i<finalRulesCount; ++i) { /* i+=2 should work too */
|
|
+ if (r1==finalRules[i]) return i; /* [sic] pointer comparison */
|
|
+ }
|
|
+
|
|
+ finalRules = (const struct rule**) (void*) erealloc((char *) finalRules,
|
|
+ (finalRulesCount + 2) * sizeof(*finalRules));
|
|
+ finalRules[finalRulesCount++] = r1;
|
|
+ finalRules[finalRulesCount++] = r2;
|
|
+ return finalRulesCount - 2;
|
|
+}
|
|
+
|
|
+#endif /*ICU*/
|
|
+
|
|
static void
|
|
outzone(zpfirst, zonecount)
|
|
const struct zone * const zpfirst;
|
|
@@ -1638,6 +1777,11 @@
|
|
register int startttisgmt;
|
|
register int type;
|
|
char startbuf[BUFSIZ];
|
|
+#ifdef ICU
|
|
+ int finalRuleYear, finalRuleIndex;
|
|
+ const struct rule* finalRule1;
|
|
+ const struct rule* finalRule2;
|
|
+#endif
|
|
|
|
INITIALIZE(untiltime);
|
|
INITIALIZE(starttime);
|
|
@@ -1667,11 +1811,55 @@
|
|
eat(zp->z_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; j<zp->z_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) {
|
|
@@ -1745,6 +1933,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;
|
|
@@ -1773,8 +1970,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);
|
|
}
|
|
}
|
|
@@ -1788,10 +1991,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.
|
|
@@ -1817,6 +2029,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];
|
|
@@ -1838,8 +2054,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;
|
|
@@ -1859,12 +2082,25 @@
|
|
error(_("internal error - addtype called with bad ttisgmt"));
|
|
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])
|
|
@@ -1879,6 +2115,10 @@
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
gmtoffs[i] = gmtoff;
|
|
+#ifdef ICU
|
|
+ rawoffs[i] = rawoff;
|
|
+ dstoffs[i] = dstoff;
|
|
+#endif
|
|
isdsts[i] = isdst;
|
|
ttisstds[i] = ttisstd;
|
|
ttisgmts[i] = ttisgmt;
|