ICU-4716 initial checkin of zic utilities
X-SVN-Rev: 19969
This commit is contained in:
parent
411a74f3bf
commit
f946c487b7
51
icu4c/source/tools/tzcode/Makefile.in
Normal file
51
icu4c/source/tools/tzcode/Makefile.in
Normal file
@ -0,0 +1,51 @@
|
||||
# Some Portions Copyright (c) 2006 IBM and others. All Rights Reserved.
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
top_builddir = ../..
|
||||
|
||||
include ../../icudefs.mk
|
||||
|
||||
ZOBJS= zic.o localtime.o asctime.o scheck.o ialloc.o
|
||||
|
||||
CFLAGS+=-D_POSIX_C_SOURCE
|
||||
|
||||
PRIMARY_YDATA= africa antarctica asia australasia \
|
||||
europe northamerica southamerica
|
||||
YDATA= $(PRIMARY_YDATA) pacificnew etcetera factory backward
|
||||
NDATA= systemv
|
||||
SDATA= solar87 solar88 solar89
|
||||
TDATA= $(YDATA) $(NDATA) $(SDATA)
|
||||
|
||||
|
||||
all: tz2icu zic
|
||||
@echo use $(MAKE) icu_data to build icu data
|
||||
|
||||
|
||||
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
|
||||
|
||||
posix_only: zic $(TDATA)
|
||||
$(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L /dev/null $(TDATA)
|
||||
|
||||
|
||||
icu_data: tz2icu posix_only
|
||||
./tz2icu zoneinfo zone.tab `ls tzdata*.tar.gz | sed -e "s/^tzdata//;s/\.tar\.gz$$//"`
|
||||
|
||||
clean:
|
||||
rm -f core *.o *.out tzselect zdump zic yearistype date
|
||||
@echo ICU specific cleanup:
|
||||
-rm -f ZoneMetaData.java icu_zone.txt tz2icu zoneinfo.txt
|
||||
-rm -rf zoneinfo
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
138
icu4c/source/tools/tzcode/asctime.c
Normal file
138
icu4c/source/tools/tzcode/asctime.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Avoid the temptation to punt entirely to strftime;
|
||||
** the output of strftime is supposed to be locale specific
|
||||
** whereas the output of asctime is supposed to be constant.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)asctime.c 8.2";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "private.h"
|
||||
#include "tzfile.h"
|
||||
|
||||
/*
|
||||
** Some systems only handle "%.2d"; others only handle "%02d";
|
||||
** "%02.2d" makes (most) everybody happy.
|
||||
** At least some versions of gcc warn about the %02.2d;
|
||||
** we conditionalize below to avoid the warning.
|
||||
*/
|
||||
/*
|
||||
** All years associated with 32-bit time_t values are exactly four digits long;
|
||||
** some years associated with 64-bit time_t values are not.
|
||||
** Vintage programs are coded for years that are always four digits long
|
||||
** and may assume that the newline always lands in the same place.
|
||||
** For years that are less than four digits, we pad the output with
|
||||
** leading zeroes to get the newline in the traditional place.
|
||||
** The -4 ensures that we get four characters of output even if
|
||||
** we call a strftime variant that produces fewer characters for some years.
|
||||
** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year,
|
||||
** but many implementations pad anyway; most likely the standards are buggy.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n"
|
||||
#else /* !defined __GNUC__ */
|
||||
#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n"
|
||||
#endif /* !defined __GNUC__ */
|
||||
/*
|
||||
** For years that are more than four digits we put extra spaces before the year
|
||||
** so that code trying to overwrite the newline won't end up overwriting
|
||||
** a digit within a year and truncating the year (operating on the assumption
|
||||
** that no output is better than wrong output).
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n"
|
||||
#else /* !defined __GNUC__ */
|
||||
#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n"
|
||||
#endif /* !defined __GNUC__ */
|
||||
|
||||
#define STD_ASCTIME_BUF_SIZE 26
|
||||
/*
|
||||
** Big enough for something such as
|
||||
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
|
||||
** (two three-character abbreviations, five strings denoting integers,
|
||||
** seven explicit spaces, two explicit colons, a newline,
|
||||
** and a trailing ASCII nul).
|
||||
** The values above are for systems where an int is 32 bits and are provided
|
||||
** as an example; the define below calculates the maximum for the system at
|
||||
** hand.
|
||||
*/
|
||||
#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
|
||||
|
||||
static char buf_asctime[MAX_ASCTIME_BUF_SIZE];
|
||||
|
||||
/*
|
||||
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
|
||||
*/
|
||||
|
||||
char *
|
||||
asctime_r(timeptr, buf)
|
||||
register const struct tm * timeptr;
|
||||
char * buf;
|
||||
{
|
||||
static const char wday_name[][3] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
};
|
||||
static const char mon_name[][3] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
register const char * wn;
|
||||
register const char * mn;
|
||||
char year[INT_STRLEN_MAXIMUM(int) + 2];
|
||||
char result[MAX_ASCTIME_BUF_SIZE];
|
||||
|
||||
if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
|
||||
wn = "???";
|
||||
else wn = wday_name[timeptr->tm_wday];
|
||||
if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
|
||||
mn = "???";
|
||||
else mn = mon_name[timeptr->tm_mon];
|
||||
/*
|
||||
** Use strftime's %Y to generate the year, to avoid overflow problems
|
||||
** when computing timeptr->tm_year + TM_YEAR_BASE.
|
||||
** Assume that strftime is unaffected by other out-of-range members
|
||||
** (e.g., timeptr->tm_mday) when processing "%Y".
|
||||
*/
|
||||
(void) strftime(year, sizeof year, "%Y", timeptr);
|
||||
/*
|
||||
** We avoid using snprintf since it's not available on all systems.
|
||||
*/
|
||||
(void) sprintf(result,
|
||||
((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
|
||||
wn, mn,
|
||||
timeptr->tm_mday, timeptr->tm_hour,
|
||||
timeptr->tm_min, timeptr->tm_sec,
|
||||
year);
|
||||
if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) {
|
||||
(void) strcpy(buf, result);
|
||||
return buf;
|
||||
} else {
|
||||
#ifdef EOVERFLOW
|
||||
errno = EOVERFLOW;
|
||||
#else /* !defined EOVERFLOW */
|
||||
errno = EINVAL;
|
||||
#endif /* !defined EOVERFLOW */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
|
||||
*/
|
||||
|
||||
char *
|
||||
asctime(timeptr)
|
||||
register const struct tm * timeptr;
|
||||
{
|
||||
return asctime_r(timeptr, buf_asctime);
|
||||
}
|
86
icu4c/source/tools/tzcode/ialloc.c
Normal file
86
icu4c/source/tools/tzcode/ialloc.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2006-07-17 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)ialloc.c 8.30";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#define nonzero(n) (((n) == 0) ? 1 : (n))
|
||||
|
||||
char *
|
||||
imalloc(n)
|
||||
const int n;
|
||||
{
|
||||
return malloc((size_t) nonzero(n));
|
||||
}
|
||||
|
||||
char *
|
||||
icalloc(nelem, elsize)
|
||||
int nelem;
|
||||
int elsize;
|
||||
{
|
||||
if (nelem == 0 || elsize == 0)
|
||||
nelem = elsize = 1;
|
||||
return calloc((size_t) nelem, (size_t) elsize);
|
||||
}
|
||||
|
||||
void *
|
||||
irealloc(pointer, size)
|
||||
void * const pointer;
|
||||
const int size;
|
||||
{
|
||||
if (pointer == NULL)
|
||||
return imalloc(size);
|
||||
return realloc((void *) pointer, (size_t) nonzero(size));
|
||||
}
|
||||
|
||||
char *
|
||||
icatalloc(old, new)
|
||||
char * const old;
|
||||
const char * const new;
|
||||
{
|
||||
register char * result;
|
||||
register int oldsize, newsize;
|
||||
|
||||
newsize = (new == NULL) ? 0 : strlen(new);
|
||||
if (old == NULL)
|
||||
oldsize = 0;
|
||||
else if (newsize == 0)
|
||||
return old;
|
||||
else oldsize = strlen(old);
|
||||
if ((result = irealloc(old, oldsize + newsize + 1)) != NULL)
|
||||
if (new != NULL)
|
||||
(void) strcpy(result + oldsize, new);
|
||||
return result;
|
||||
}
|
||||
|
||||
char *
|
||||
icpyalloc(string)
|
||||
const char * const string;
|
||||
{
|
||||
return icatalloc((char *) NULL, string);
|
||||
}
|
||||
|
||||
void
|
||||
ifree(p)
|
||||
char * const p;
|
||||
{
|
||||
if (p != NULL)
|
||||
(void) free(p);
|
||||
}
|
||||
|
||||
void
|
||||
icfree(p)
|
||||
char * const p;
|
||||
{
|
||||
if (p != NULL)
|
||||
(void) free(p);
|
||||
}
|
2053
icu4c/source/tools/tzcode/localtime.c
Normal file
2053
icu4c/source/tools/tzcode/localtime.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,478 +0,0 @@
|
||||
diff -ur tzcode.orig/Makefile tzcode/Makefile
|
||||
--- tzcode.orig/Makefile 2006-03-14 06:42:05.000000000 -0800
|
||||
+++ tzcode/Makefile 2006-04-03 10:24:01.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. . .
|
||||
|
||||
@@ -241,9 +241,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
|
||||
@@ -277,7 +279,10 @@
|
||||
|
||||
SHELL= /bin/sh
|
||||
|
||||
-all: tzselect zic zdump $(LIBOBJS)
|
||||
+LS= /bin/ls
|
||||
+SED= /bin/sed
|
||||
+
|
||||
+all: tzselect zic zdump $(LIBOBJS) tz2icu
|
||||
|
||||
ALL: all date
|
||||
|
||||
@@ -310,9 +315,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
|
||||
@@ -323,6 +331,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 -ur tzcode.orig/zic.c tzcode/zic.c
|
||||
--- tzcode.orig/zic.c 2006-04-03 07:09:14.000000000 -0700
|
||||
+++ tzcode/zic.c 2006-04-03 11:31:13.000000000 -0700
|
||||
@@ -21,6 +21,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,
|
||||
@@ -101,8 +115,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));
|
||||
@@ -282,6 +302,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));
|
||||
|
||||
@@ -364,6 +396,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];
|
||||
@@ -475,6 +512,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;
|
||||
@@ -586,6 +679,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)
|
||||
@@ -605,6 +706,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,
|
||||
@@ -619,6 +723,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;
|
||||
}
|
||||
|
||||
@@ -684,7 +793,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);
|
||||
@@ -1650,7 +1761,12 @@
|
||||
#define DO(field) (void) fwrite((void *) tzh.field, \
|
||||
(size_t) sizeof tzh.field, (size_t) 1, fp)
|
||||
tzh = tzh0;
|
||||
+#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
|
||||
tzh.tzh_version[0] = ZIC_VERSION;
|
||||
convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt);
|
||||
convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt);
|
||||
@@ -1683,7 +1799,12 @@
|
||||
}
|
||||
for (i = 0; i < typecnt; ++i)
|
||||
if (writetype[i]) {
|
||||
- puttzcode(gmtoffs[i], fp);
|
||||
+#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((unsigned char) indmap[abbrinds[i]], fp);
|
||||
}
|
||||
@@ -1952,6 +2073,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;
|
||||
@@ -1974,6 +2113,11 @@
|
||||
register char * envvar;
|
||||
register int max_abbr_len;
|
||||
register int max_envvar_len;
|
||||
+#ifdef ICU
|
||||
+ int finalRuleYear, finalRuleIndex;
|
||||
+ const struct rule* finalRule1;
|
||||
+ const struct rule* finalRule2;
|
||||
+#endif
|
||||
|
||||
max_abbr_len = 2 + max_format_len + max_abbrvar_len;
|
||||
max_envvar_len = 2 * max_abbr_len + 5 * 9;
|
||||
@@ -2050,11 +2194,56 @@
|
||||
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, FALSE);
|
||||
type = addtype(oadd(zp->z_gmtoff, stdoff),
|
||||
+#ifdef ICU
|
||||
+ zp->z_gmtoff, stdoff,
|
||||
+#endif
|
||||
startbuf, stdoff != 0, startttisstd,
|
||||
startttisgmt);
|
||||
if (usestart) {
|
||||
@@ -2127,6 +2316,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;
|
||||
@@ -2158,8 +2356,14 @@
|
||||
doabbr(ab, zp->z_format, rp->r_abbrvar,
|
||||
rp->r_stdoff != 0, FALSE);
|
||||
offset = oadd(zp->z_gmtoff, rp->r_stdoff);
|
||||
+#ifdef ICU
|
||||
+ type = addtype(offset, zp->z_gmtoff, rp->r_stdoff,
|
||||
+ ab, rp->r_stdoff != 0,
|
||||
+ rp->r_todisstd, rp->r_todisgmt);
|
||||
+#else
|
||||
type = addtype(offset, ab, rp->r_stdoff != 0,
|
||||
rp->r_todisstd, rp->r_todisgmt);
|
||||
+#endif
|
||||
addtt(ktime, type);
|
||||
}
|
||||
}
|
||||
@@ -2173,10 +2377,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.
|
||||
@@ -2205,6 +2418,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];
|
||||
@@ -2226,8 +2443,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;
|
||||
@@ -2247,12 +2471,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])
|
||||
@@ -2267,6 +2504,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;
|
||||
|
368
icu4c/source/tools/tzcode/private.h
Normal file
368
icu4c/source/tools/tzcode/private.h
Normal file
@ -0,0 +1,368 @@
|
||||
#ifndef PRIVATE_H
|
||||
|
||||
#define PRIVATE_H
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is for use ONLY with the time conversion code.
|
||||
** There is no guarantee that it will remain unchanged,
|
||||
** or that it will remain at all.
|
||||
** Do NOT copy it to any system include directory.
|
||||
** Thank you!
|
||||
*/
|
||||
|
||||
/*
|
||||
** ID
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char privatehid[] = "@(#)private.h 8.2";
|
||||
#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'.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_ADJTIME
|
||||
#define HAVE_ADJTIME 1
|
||||
#endif /* !defined HAVE_ADJTIME */
|
||||
|
||||
#ifndef HAVE_GETTEXT
|
||||
#define HAVE_GETTEXT 0
|
||||
#endif /* !defined HAVE_GETTEXT */
|
||||
|
||||
#ifndef HAVE_INCOMPATIBLE_CTIME_R
|
||||
#define HAVE_INCOMPATIBLE_CTIME_R 0
|
||||
#endif /* !defined INCOMPATIBLE_CTIME_R */
|
||||
|
||||
#ifndef HAVE_SETTIMEOFDAY
|
||||
#define HAVE_SETTIMEOFDAY 3
|
||||
#endif /* !defined HAVE_SETTIMEOFDAY */
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
#define HAVE_STRERROR 1
|
||||
#endif /* !defined HAVE_STRERROR */
|
||||
|
||||
#ifndef HAVE_SYMLINK
|
||||
#define HAVE_SYMLINK 1
|
||||
#endif /* !defined HAVE_SYMLINK */
|
||||
|
||||
#ifndef HAVE_SYS_STAT_H
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#endif /* !defined HAVE_SYS_STAT_H */
|
||||
|
||||
#ifndef HAVE_SYS_WAIT_H
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
#endif /* !defined HAVE_SYS_WAIT_H */
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif /* !defined HAVE_UNISTD_H */
|
||||
|
||||
#ifndef HAVE_UTMPX_H
|
||||
#define HAVE_UTMPX_H 0
|
||||
#endif /* !defined HAVE_UTMPX_H */
|
||||
|
||||
#ifndef LOCALE_HOME
|
||||
#define LOCALE_HOME "/usr/lib/locale"
|
||||
#endif /* !defined LOCALE_HOME */
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#define asctime_r _incompatible_asctime_r
|
||||
#define ctime_r _incompatible_ctime_r
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
/*
|
||||
** Nested includes
|
||||
*/
|
||||
|
||||
#include "sys/types.h" /* for time_t */
|
||||
#include "stdio.h"
|
||||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "limits.h" /* for CHAR_BIT et al. */
|
||||
#include "time.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
#include "libintl.h"
|
||||
#endif /* HAVE_GETTEXT */
|
||||
|
||||
#if HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
|
||||
#endif /* HAVE_SYS_WAIT_H */
|
||||
|
||||
#ifndef WIFEXITED
|
||||
#define WIFEXITED(status) (((status) & 0xff) == 0)
|
||||
#endif /* !defined WIFEXITED */
|
||||
#ifndef WEXITSTATUS
|
||||
#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
|
||||
#endif /* !defined WEXITSTATUS */
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include "unistd.h" /* for F_OK and R_OK */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#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 */
|
||||
|
||||
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
|
||||
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
|
||||
|
||||
/*
|
||||
** Define HAVE_STDINT_H's default value here, rather than at the
|
||||
** start, since __GLIBC__'s value depends on previously-included
|
||||
** files.
|
||||
** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
|
||||
*/
|
||||
#ifndef HAVE_STDINT_H
|
||||
#define HAVE_STDINT_H \
|
||||
(199901 <= __STDC_VERSION__ || \
|
||||
2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
|
||||
#endif /* !defined HAVE_STDINT_H */
|
||||
|
||||
#if HAVE_STDINT_H
|
||||
#include "stdint.h"
|
||||
#endif /* !HAVE_STDINT_H */
|
||||
|
||||
#ifndef INT_FAST64_MAX
|
||||
/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
|
||||
#if defined LLONG_MAX || defined __LONG_LONG_MAX__
|
||||
typedef long long int_fast64_t;
|
||||
#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
|
||||
#if (LONG_MAX >> 31) < 0xffffffff
|
||||
Please use a compiler that supports a 64-bit integer type (or wider);
|
||||
you may need to compile with "-DHAVE_STDINT_H".
|
||||
#endif /* (LONG_MAX >> 31) < 0xffffffff */
|
||||
typedef long int_fast64_t;
|
||||
#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
|
||||
#endif /* !defined INT_FAST64_MAX */
|
||||
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX 0x7fffffff
|
||||
#endif /* !defined INT32_MAX */
|
||||
#ifndef INT32_MIN
|
||||
#define INT32_MIN (-1 - INT32_MAX)
|
||||
#endif /* !defined INT32_MIN */
|
||||
|
||||
/*
|
||||
** Workarounds for compilers/systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
** If your compiler lacks prototypes, "#define P(x) ()".
|
||||
*/
|
||||
|
||||
#ifndef P
|
||||
#define P(x) x
|
||||
#endif /* !defined P */
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 headers lack EXIT_SUCCESS.
|
||||
*/
|
||||
|
||||
#ifndef EXIT_SUCCESS
|
||||
#define EXIT_SUCCESS 0
|
||||
#endif /* !defined EXIT_SUCCESS */
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 headers lack EXIT_FAILURE.
|
||||
*/
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
#define EXIT_FAILURE 1
|
||||
#endif /* !defined EXIT_FAILURE */
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 headers lack FILENAME_MAX.
|
||||
*/
|
||||
|
||||
#ifndef FILENAME_MAX
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
#ifdef unix
|
||||
#include "sys/param.h"
|
||||
#endif /* defined unix */
|
||||
#endif /* !defined MAXPATHLEN */
|
||||
|
||||
#ifdef MAXPATHLEN
|
||||
#define FILENAME_MAX MAXPATHLEN
|
||||
#endif /* defined MAXPATHLEN */
|
||||
#ifndef MAXPATHLEN
|
||||
#define FILENAME_MAX 1024 /* Pure guesswork */
|
||||
#endif /* !defined MAXPATHLEN */
|
||||
|
||||
#endif /* !defined FILENAME_MAX */
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 libraries lack remove.
|
||||
*/
|
||||
|
||||
#ifndef remove
|
||||
extern int unlink P((const char * filename));
|
||||
#define remove unlink
|
||||
#endif /* !defined remove */
|
||||
|
||||
/*
|
||||
** Some ancient errno.h implementations don't declare errno.
|
||||
** But some newer errno.h implementations define it as a macro.
|
||||
** Fix the former without affecting the latter.
|
||||
*/
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif /* !defined errno */
|
||||
|
||||
/*
|
||||
** Some time.h implementations don't declare asctime_r.
|
||||
** Others might define it as a macro.
|
||||
** Fix the former without affecting the latter.
|
||||
*/
|
||||
|
||||
#ifndef asctime_r
|
||||
extern char * asctime_r();
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Private function declarations.
|
||||
*/
|
||||
|
||||
char * icalloc P((int nelem, int elsize));
|
||||
char * icatalloc P((char * old, const char * new));
|
||||
char * icpyalloc P((const char * string));
|
||||
char * imalloc P((int n));
|
||||
void * irealloc P((void * pointer, int size));
|
||||
void icfree P((char * pointer));
|
||||
void ifree P((char * pointer));
|
||||
const char * scheck P((const char * string, const char * format));
|
||||
|
||||
/*
|
||||
** Finally, some convenience items.
|
||||
*/
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* !defined TRUE */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* !defined FALSE */
|
||||
|
||||
#ifndef TYPE_BIT
|
||||
#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
|
||||
#endif /* !defined TYPE_BIT */
|
||||
|
||||
#ifndef TYPE_SIGNED
|
||||
#define TYPE_SIGNED(type) (((type) -1) < 0)
|
||||
#endif /* !defined TYPE_SIGNED */
|
||||
|
||||
/*
|
||||
** Since the definition of TYPE_INTEGRAL contains floating point numbers,
|
||||
** it cannot be used in preprocessor directives.
|
||||
*/
|
||||
|
||||
#ifndef TYPE_INTEGRAL
|
||||
#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
|
||||
#endif /* !defined TYPE_INTEGRAL */
|
||||
|
||||
#ifndef INT_STRLEN_MAXIMUM
|
||||
/*
|
||||
** 302 / 1000 is log10(2.0) rounded up.
|
||||
** Subtract one for the sign bit if the type is signed;
|
||||
** add one for integer division truncation;
|
||||
** 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))
|
||||
#endif /* !defined INT_STRLEN_MAXIMUM */
|
||||
|
||||
/*
|
||||
** INITIALIZE(x)
|
||||
*/
|
||||
|
||||
#ifndef GNUC_or_lint
|
||||
#ifdef lint
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined lint */
|
||||
#ifndef lint
|
||||
#ifdef __GNUC__
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined __GNUC__ */
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
|
||||
#ifndef INITIALIZE
|
||||
#ifdef GNUC_or_lint
|
||||
#define INITIALIZE(x) ((x) = 0)
|
||||
#endif /* defined GNUC_or_lint */
|
||||
#ifndef GNUC_or_lint
|
||||
#define INITIALIZE(x)
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
#endif /* !defined INITIALIZE */
|
||||
|
||||
/*
|
||||
** For the benefit of GNU folk...
|
||||
** `_(MSGID)' uses the current locale's message library string for MSGID.
|
||||
** The default is to use gettext if available, and use MSGID otherwise.
|
||||
*/
|
||||
|
||||
#ifndef _
|
||||
#if HAVE_GETTEXT
|
||||
#define _(msgid) gettext(msgid)
|
||||
#else /* !HAVE_GETTEXT */
|
||||
#define _(msgid) msgid
|
||||
#endif /* !HAVE_GETTEXT */
|
||||
#endif /* !defined _ */
|
||||
|
||||
#ifndef TZ_DOMAIN
|
||||
#define TZ_DOMAIN "tz"
|
||||
#endif /* !defined TZ_DOMAIN */
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#undef asctime_r
|
||||
#undef ctime_r
|
||||
char *asctime_r P((struct tm const *, char *));
|
||||
char *ctime_r P((time_t const *, char *));
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
#ifndef YEARSPERREPEAT
|
||||
#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
|
||||
#endif /* !defined YEARSPERREPEAT */
|
||||
|
||||
/*
|
||||
** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
|
||||
*/
|
||||
|
||||
#ifndef AVGSECSPERYEAR
|
||||
#define AVGSECSPERYEAR 31556952L
|
||||
#endif /* !defined AVGSECSPERYEAR */
|
||||
|
||||
#ifndef SECSPERREPEAT
|
||||
#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
|
||||
#endif /* !defined SECSPERREPEAT */
|
||||
|
||||
#ifndef SECSPERREPEAT_BITS
|
||||
#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
|
||||
#endif /* !defined SECSPERREPEAT_BITS */
|
||||
|
||||
/*
|
||||
** UNIX was a registered trademark of The Open Group in 2003.
|
||||
*/
|
||||
|
||||
#endif /* !defined PRIVATE_H */
|
@ -7,6 +7,9 @@
|
||||
* Since: ICU 2.8
|
||||
**********************************************************************
|
||||
|
||||
Note: this directory currently contains tzcode as of tzcode2006h.tar.gz
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
OVERVIEW
|
||||
|
||||
@ -62,16 +65,18 @@ where YYYY is the year and V is the version letter ('a'...'z').
|
||||
----------------------------------------------------------------------
|
||||
HOWTO
|
||||
|
||||
1. Obtain the current versions of tzcodeYYYYV.tar.gz (aka `tzcode')
|
||||
and tzdataYYYYV.tar.gz (aka `tzdata') from the FTP site given
|
||||
0. Generate Makefile
|
||||
|
||||
( cd ../.. ; CONFIG_FILES=tools/tzcode/Makefile CONFIG_HEADERS= sh config.status )
|
||||
|
||||
1. Obtain the current versions of tzdataYYYYV.tar.gz (aka `tzdata') from the FTP site given
|
||||
above. Either manually download or use wget:
|
||||
|
||||
$ cd {path_to}/icu/source/tools/tzcode
|
||||
$ wget "ftp://elsie.nci.nih.gov/pub/tz*.tar.gz"
|
||||
|
||||
2. Unpack tzcode and tzdata directly into the directory tzcode:
|
||||
2. Unpack tzdata directly into the directory tzcode:
|
||||
|
||||
$ tar xzvf tzcode*.tar.gz
|
||||
$ tar xzvf tzdata*.tar.gz
|
||||
|
||||
*** Make sure you only have ONE FILE named tzdata*.tar.gz in the
|
||||
@ -81,71 +86,20 @@ HOWTO
|
||||
The Makefile looks in the current directory to determine the
|
||||
version of Olson data it is building by looking for tzdata*.tar.gz.
|
||||
|
||||
3. Apply the ICU patch to zic.c:
|
||||
|
||||
$ patch < patch-icu-tzcode
|
||||
|
||||
If patch complains at this point, there is a mismatch that must be
|
||||
manually addressed. See the CVS log of `patch-icu-tzcode' for
|
||||
version details.
|
||||
|
||||
4. Build:
|
||||
3. Build:
|
||||
|
||||
$ make icu_data
|
||||
|
||||
5. Copy the data files to the correct location in the ICU4C/ICU4J
|
||||
4. Copy the data files to the correct location in the ICU4C/ICU4J
|
||||
source trees:
|
||||
|
||||
$ cp zoneinfo.txt ../../data/misc/
|
||||
$ cp ZoneMetaData.java {path_to}/icu4j/src/com/ibm/icu/impl
|
||||
|
||||
6. Rebuild ICU:
|
||||
5. Rebuild ICU:
|
||||
|
||||
$ cd ../..
|
||||
$ {*make}
|
||||
|
||||
7. Don't forget to check in the new zoneinfo.txt (from its location at
|
||||
6. Don't forget to check in the new zoneinfo.txt (from its location at
|
||||
{path_to}/icu/source/data/misc/zoneinfo.txt) into CVS.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
HOWTO platform issues
|
||||
00. On macosx, I had to do "sudo ln -s /usr/bin/sed /bin/" first
|
||||
00. On macosx, I had to build with "make CPPFLAGS=-DSTD_INSPIRED icu_data"
|
||||
|
||||
----------------------------------------------------------------------
|
||||
HOWTO regenerate patch-icu-tzcode
|
||||
|
||||
If you need to edit any of the tzcode* files, you will need to
|
||||
regenerate the patch file as follows.
|
||||
|
||||
1. Follow the above instructions to extract and patch the tzcode*
|
||||
files in {path_to}/icu/source/tools/tzcode. Modify any of the
|
||||
tzcode files.
|
||||
|
||||
2. Extract a clean set of the tzcode* files into a new directory,
|
||||
../tzcode.orig/:
|
||||
|
||||
$ mkdir ../tzcode.orig
|
||||
$ cd ../tzcode.orig
|
||||
$ tar xzf ../tzcode/tzcode*.tar.gz
|
||||
$ cd ../tzcode
|
||||
|
||||
3. Compute diffs, ignoring files that are in only one directory:
|
||||
|
||||
$ diff -ur ../tzcode.orig . | grep -vE -e "^Only in " > patch-icu-tzcode
|
||||
|
||||
4. Test the patch-icu-tzcode file by regenerating and diffing the
|
||||
files again in another directory. The expected output from the
|
||||
final diff command is *nothing*.
|
||||
|
||||
$ mkdir ../tzcode.new
|
||||
$ cd ../tzcode.new
|
||||
$ tar xzf ../tzcode/tzcode*.tar.gz
|
||||
$ patch < ../tzcode/patch-icu-tzcode
|
||||
$ cd ../tzcode
|
||||
$ diff -ur ../tzcode.new . | grep -vE -e "^Only in "
|
||||
|
||||
5. Check in the new patch-icu-tzcode file.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
eof
|
||||
|
63
icu4c/source/tools/tzcode/scheck.c
Normal file
63
icu4c/source/tools/tzcode/scheck.c
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2006-07-17 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)scheck.c 8.19";
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined NOID */
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
const char *
|
||||
scheck(string, format)
|
||||
const char * const string;
|
||||
const char * const format;
|
||||
{
|
||||
register char * fbuf;
|
||||
register const char * fp;
|
||||
register char * tp;
|
||||
register int c;
|
||||
register const char * result;
|
||||
char dummy;
|
||||
|
||||
result = "";
|
||||
if (string == NULL || format == NULL)
|
||||
return result;
|
||||
fbuf = imalloc((int) (2 * strlen(format) + 4));
|
||||
if (fbuf == NULL)
|
||||
return result;
|
||||
fp = format;
|
||||
tp = fbuf;
|
||||
while ((*tp++ = c = *fp++) != '\0') {
|
||||
if (c != '%')
|
||||
continue;
|
||||
if (*fp == '%') {
|
||||
*tp++ = *fp++;
|
||||
continue;
|
||||
}
|
||||
*tp++ = '*';
|
||||
if (*fp == '*')
|
||||
++fp;
|
||||
while (is_digit(*fp))
|
||||
*tp++ = *fp++;
|
||||
if (*fp == 'l' || *fp == 'h')
|
||||
*tp++ = *fp++;
|
||||
else if (*fp == '[')
|
||||
do *tp++ = *fp++;
|
||||
while (*fp != '\0' && *fp != ']');
|
||||
if ((*tp++ = *fp++) == '\0')
|
||||
break;
|
||||
}
|
||||
*(tp - 1) = '%';
|
||||
*tp++ = 'c';
|
||||
*tp = '\0';
|
||||
if (sscanf(string, fbuf, &dummy) != 1)
|
||||
result = (char *) format;
|
||||
ifree(fbuf);
|
||||
return result;
|
||||
}
|
180
icu4c/source/tools/tzcode/tzfile.h
Normal file
180
icu4c/source/tools/tzcode/tzfile.h
Normal file
@ -0,0 +1,180 @@
|
||||
#ifndef TZFILE_H
|
||||
|
||||
#define TZFILE_H
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is for use ONLY with the time conversion code.
|
||||
** There is no guarantee that it will remain unchanged,
|
||||
** or that it will remain at all.
|
||||
** Do NOT copy it to any system include directory.
|
||||
** Thank you!
|
||||
*/
|
||||
|
||||
/*
|
||||
** ID
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char tzfilehid[] = "@(#)tzfile.h 8.1";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*
|
||||
** Information about time zone files.
|
||||
*/
|
||||
|
||||
#ifndef TZDIR
|
||||
#define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */
|
||||
#endif /* !defined TZDIR */
|
||||
|
||||
#ifndef TZDEFAULT
|
||||
#define TZDEFAULT "localtime"
|
||||
#endif /* !defined TZDEFAULT */
|
||||
|
||||
#ifndef TZDEFRULES
|
||||
#define TZDEFRULES "posixrules"
|
||||
#endif /* !defined TZDEFRULES */
|
||||
|
||||
/*
|
||||
** Each file begins with. . .
|
||||
*/
|
||||
|
||||
#define TZ_MAGIC "TZif"
|
||||
|
||||
struct tzhead {
|
||||
char tzh_magic[4]; /* TZ_MAGIC */
|
||||
char tzh_version[1]; /* '\0' or '2' as of 2005 */
|
||||
char tzh_reserved[15]; /* reserved--must be zero */
|
||||
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
|
||||
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
|
||||
char tzh_leapcnt[4]; /* coded number of leap seconds */
|
||||
char tzh_timecnt[4]; /* coded number of transition times */
|
||||
char tzh_typecnt[4]; /* coded number of local time types */
|
||||
char tzh_charcnt[4]; /* coded number of abbr. chars */
|
||||
};
|
||||
|
||||
/*
|
||||
** . . .followed by. . .
|
||||
**
|
||||
** tzh_timecnt (char [4])s coded transition times a la time(2)
|
||||
** tzh_timecnt (unsigned char)s types of local time starting at above
|
||||
** tzh_typecnt repetitions of
|
||||
** one (char [4]) coded UTC offset in seconds
|
||||
** one (unsigned char) used to set tm_isdst
|
||||
** one (unsigned char) that's an abbreviation list index
|
||||
** tzh_charcnt (char)s '\0'-terminated zone abbreviations
|
||||
** tzh_leapcnt repetitions of
|
||||
** one (char [4]) coded leap second transition times
|
||||
** one (char [4]) total correction after above
|
||||
** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
|
||||
** time is standard time, if FALSE,
|
||||
** transition time is wall clock time
|
||||
** if absent, transition times are
|
||||
** assumed to be wall clock time
|
||||
** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition
|
||||
** time is UTC, if FALSE,
|
||||
** transition time is local time
|
||||
** if absent, transition times are
|
||||
** assumed to be local time
|
||||
*/
|
||||
|
||||
/*
|
||||
** If tzh_version is '2' or greater, the above is followed by a second instance
|
||||
** of tzhead and a second instance of the data in which each coded transition
|
||||
** time uses 8 rather than 4 chars,
|
||||
** then a POSIX-TZ-environment-variable-style string for use in handling
|
||||
** instants after the last transition time stored in the file
|
||||
** (with nothing between the newlines if there is no POSIX representation for
|
||||
** such instants).
|
||||
*/
|
||||
|
||||
/*
|
||||
** In the current implementation, "tzset()" refuses to deal with files that
|
||||
** exceed any of the limits below.
|
||||
*/
|
||||
|
||||
#ifndef TZ_MAX_TIMES
|
||||
#define TZ_MAX_TIMES 1200
|
||||
#endif /* !defined TZ_MAX_TIMES */
|
||||
|
||||
#ifndef TZ_MAX_TYPES
|
||||
#ifndef NOSOLAR
|
||||
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
|
||||
#endif /* !defined NOSOLAR */
|
||||
#ifdef NOSOLAR
|
||||
/*
|
||||
** Must be at least 14 for Europe/Riga as of Jan 12 1995,
|
||||
** as noted by Earl Chew.
|
||||
*/
|
||||
#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
|
||||
#endif /* !defined NOSOLAR */
|
||||
#endif /* !defined TZ_MAX_TYPES */
|
||||
|
||||
#ifndef TZ_MAX_CHARS
|
||||
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
|
||||
/* (limited by what unsigned chars can hold) */
|
||||
#endif /* !defined TZ_MAX_CHARS */
|
||||
|
||||
#ifndef TZ_MAX_LEAPS
|
||||
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
|
||||
#endif /* !defined TZ_MAX_LEAPS */
|
||||
|
||||
#define SECSPERMIN 60
|
||||
#define MINSPERHOUR 60
|
||||
#define HOURSPERDAY 24
|
||||
#define DAYSPERWEEK 7
|
||||
#define DAYSPERNYEAR 365
|
||||
#define DAYSPERLYEAR 366
|
||||
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
|
||||
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
|
||||
#define MONSPERYEAR 12
|
||||
|
||||
#define TM_SUNDAY 0
|
||||
#define TM_MONDAY 1
|
||||
#define TM_TUESDAY 2
|
||||
#define TM_WEDNESDAY 3
|
||||
#define TM_THURSDAY 4
|
||||
#define TM_FRIDAY 5
|
||||
#define TM_SATURDAY 6
|
||||
|
||||
#define TM_JANUARY 0
|
||||
#define TM_FEBRUARY 1
|
||||
#define TM_MARCH 2
|
||||
#define TM_APRIL 3
|
||||
#define TM_MAY 4
|
||||
#define TM_JUNE 5
|
||||
#define TM_JULY 6
|
||||
#define TM_AUGUST 7
|
||||
#define TM_SEPTEMBER 8
|
||||
#define TM_OCTOBER 9
|
||||
#define TM_NOVEMBER 10
|
||||
#define TM_DECEMBER 11
|
||||
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define EPOCH_WDAY TM_THURSDAY
|
||||
|
||||
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
||||
|
||||
/*
|
||||
** Since everything in isleap is modulo 400 (or a factor of 400), we know that
|
||||
** isleap(y) == isleap(y % 400)
|
||||
** and so
|
||||
** isleap(a + b) == isleap((a + b) % 400)
|
||||
** or
|
||||
** isleap(a + b) == isleap(a % 400 + b % 400)
|
||||
** This is true even if % means modulo rather than Fortran remainder
|
||||
** (which is allowed by C89 but not C99).
|
||||
** We use this to avoid addition overflow problems.
|
||||
*/
|
||||
|
||||
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
|
||||
|
||||
#endif /* !defined TZFILE_H */
|
308
icu4c/source/tools/tzcode/tzselect.ksh
Normal file
308
icu4c/source/tools/tzcode/tzselect.ksh
Normal file
@ -0,0 +1,308 @@
|
||||
#! /bin/ksh
|
||||
|
||||
# '@(#)tzselect.ksh 8.1'
|
||||
|
||||
# Ask the user about the time zone, and output the resulting TZ value to stdout.
|
||||
# Interact with the user via stderr and stdin.
|
||||
|
||||
# Contributed by Paul Eggert.
|
||||
|
||||
# Porting notes:
|
||||
#
|
||||
# This script requires several features of the Korn shell.
|
||||
# If your host lacks the Korn shell,
|
||||
# you can use either of the following free programs instead:
|
||||
#
|
||||
# <a href=ftp://ftp.gnu.org/pub/gnu/>
|
||||
# Bourne-Again shell (bash)
|
||||
# </a>
|
||||
#
|
||||
# <a href=ftp://ftp.cs.mun.ca/pub/pdksh/pdksh.tar.gz>
|
||||
# Public domain ksh
|
||||
# </a>
|
||||
#
|
||||
# This script also uses several features of modern awk programs.
|
||||
# If your host lacks awk, or has an old awk that does not conform to Posix.2,
|
||||
# you can use either of the following free programs instead:
|
||||
#
|
||||
# <a href=ftp://ftp.gnu.org/pub/gnu/>
|
||||
# GNU awk (gawk)
|
||||
# </a>
|
||||
#
|
||||
# <a href=ftp://ftp.whidbey.net/pub/brennan/>
|
||||
# mawk
|
||||
# </a>
|
||||
|
||||
|
||||
# Specify default values for environment variables if they are unset.
|
||||
: ${AWK=awk}
|
||||
: ${TZDIR=$(pwd)}
|
||||
|
||||
# Check for awk Posix compliance.
|
||||
($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
|
||||
[ $? = 123 ] || {
|
||||
echo >&2 "$0: Sorry, your \`$AWK' program is not Posix compatible."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Make sure the tables are readable.
|
||||
TZ_COUNTRY_TABLE=$TZDIR/iso3166.tab
|
||||
TZ_ZONE_TABLE=$TZDIR/zone.tab
|
||||
for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE
|
||||
do
|
||||
<$f || {
|
||||
echo >&2 "$0: time zone files are not set up correctly"
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
newline='
|
||||
'
|
||||
IFS=$newline
|
||||
|
||||
|
||||
# Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout.
|
||||
case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in
|
||||
?*) PS3=
|
||||
esac
|
||||
|
||||
|
||||
# Begin the main loop. We come back here if the user wants to retry.
|
||||
while
|
||||
|
||||
echo >&2 'Please identify a location' \
|
||||
'so that time zone rules can be set correctly.'
|
||||
|
||||
continent=
|
||||
country=
|
||||
region=
|
||||
|
||||
|
||||
# Ask the user for continent or ocean.
|
||||
|
||||
echo >&2 'Please select a continent or ocean.'
|
||||
|
||||
select continent in \
|
||||
Africa \
|
||||
Americas \
|
||||
Antarctica \
|
||||
'Arctic Ocean' \
|
||||
Asia \
|
||||
'Atlantic Ocean' \
|
||||
Australia \
|
||||
Europe \
|
||||
'Indian Ocean' \
|
||||
'Pacific Ocean' \
|
||||
'none - I want to specify the time zone using the Posix TZ format.'
|
||||
do
|
||||
case $continent in
|
||||
'')
|
||||
echo >&2 'Please enter a number in range.';;
|
||||
?*)
|
||||
case $continent in
|
||||
Americas) continent=America;;
|
||||
*' '*) continent=$(expr "$continent" : '\([^ ]*\)')
|
||||
esac
|
||||
break
|
||||
esac
|
||||
done
|
||||
case $continent in
|
||||
'')
|
||||
exit 1;;
|
||||
none)
|
||||
# Ask the user for a Posix TZ string. Check that it conforms.
|
||||
while
|
||||
echo >&2 'Please enter the desired value' \
|
||||
'of the TZ environment variable.'
|
||||
echo >&2 'For example, GST-10 is a zone named GST' \
|
||||
'that is 10 hours ahead (east) of UTC.'
|
||||
read TZ
|
||||
$AWK -v TZ="$TZ" 'BEGIN {
|
||||
tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+"
|
||||
time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?"
|
||||
offset = "[-+]?" time
|
||||
date = "(J?[0-9]+|M[0-9]+\.[0-9]+\.[0-9]+)"
|
||||
datetime = "," date "(/" time ")?"
|
||||
tzpattern = "^(:.*|" tzname offset "(" tzname \
|
||||
"(" offset ")?(" datetime datetime ")?)?)$"
|
||||
if (TZ ~ tzpattern) exit 1
|
||||
exit 0
|
||||
}'
|
||||
do
|
||||
echo >&2 "\`$TZ' is not a conforming" \
|
||||
'Posix time zone string.'
|
||||
done
|
||||
TZ_for_date=$TZ;;
|
||||
*)
|
||||
# Get list of names of countries in the continent or ocean.
|
||||
countries=$($AWK -F'\t' \
|
||||
-v continent="$continent" \
|
||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
'
|
||||
/^#/ { next }
|
||||
$3 ~ ("^" continent "/") {
|
||||
if (!cc_seen[$1]++) cc_list[++ccs] = $1
|
||||
}
|
||||
END {
|
||||
while (getline <TZ_COUNTRY_TABLE) {
|
||||
if ($0 !~ /^#/) cc_name[$1] = $2
|
||||
}
|
||||
for (i = 1; i <= ccs; i++) {
|
||||
country = cc_list[i]
|
||||
if (cc_name[country]) {
|
||||
country = cc_name[country]
|
||||
}
|
||||
print country
|
||||
}
|
||||
}
|
||||
' <$TZ_ZONE_TABLE | sort -f)
|
||||
|
||||
|
||||
# If there's more than one country, ask the user which one.
|
||||
case $countries in
|
||||
*"$newline"*)
|
||||
echo >&2 'Please select a country.'
|
||||
select country in $countries
|
||||
do
|
||||
case $country in
|
||||
'') echo >&2 'Please enter a number in range.';;
|
||||
?*) break
|
||||
esac
|
||||
done
|
||||
|
||||
case $country in
|
||||
'') exit 1
|
||||
esac;;
|
||||
*)
|
||||
country=$countries
|
||||
esac
|
||||
|
||||
|
||||
# Get list of names of time zone rule regions in the country.
|
||||
regions=$($AWK -F'\t' \
|
||||
-v country="$country" \
|
||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
'
|
||||
BEGIN {
|
||||
cc = country
|
||||
while (getline <TZ_COUNTRY_TABLE) {
|
||||
if ($0 !~ /^#/ && country == $2) {
|
||||
cc = $1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
$1 == cc { print $4 }
|
||||
' <$TZ_ZONE_TABLE)
|
||||
|
||||
|
||||
# If there's more than one region, ask the user which one.
|
||||
case $regions in
|
||||
*"$newline"*)
|
||||
echo >&2 'Please select one of the following' \
|
||||
'time zone regions.'
|
||||
select region in $regions
|
||||
do
|
||||
case $region in
|
||||
'') echo >&2 'Please enter a number in range.';;
|
||||
?*) break
|
||||
esac
|
||||
done
|
||||
case $region in
|
||||
'') exit 1
|
||||
esac;;
|
||||
*)
|
||||
region=$regions
|
||||
esac
|
||||
|
||||
# Determine TZ from country and region.
|
||||
TZ=$($AWK -F'\t' \
|
||||
-v country="$country" \
|
||||
-v region="$region" \
|
||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
'
|
||||
BEGIN {
|
||||
cc = country
|
||||
while (getline <TZ_COUNTRY_TABLE) {
|
||||
if ($0 !~ /^#/ && country == $2) {
|
||||
cc = $1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
$1 == cc && $4 == region { print $3 }
|
||||
' <$TZ_ZONE_TABLE)
|
||||
|
||||
# Make sure the corresponding zoneinfo file exists.
|
||||
TZ_for_date=$TZDIR/$TZ
|
||||
<$TZ_for_date || {
|
||||
echo >&2 "$0: time zone files are not set up correctly"
|
||||
exit 1
|
||||
}
|
||||
esac
|
||||
|
||||
|
||||
# Use the proposed TZ to output the current date relative to UTC.
|
||||
# Loop until they agree in seconds.
|
||||
# Give up after 8 unsuccessful tries.
|
||||
|
||||
extra_info=
|
||||
for i in 1 2 3 4 5 6 7 8
|
||||
do
|
||||
TZdate=$(LANG=C TZ="$TZ_for_date" date)
|
||||
UTdate=$(LANG=C TZ=UTC0 date)
|
||||
TZsec=$(expr "$TZdate" : '.*:\([0-5][0-9]\)')
|
||||
UTsec=$(expr "$UTdate" : '.*:\([0-5][0-9]\)')
|
||||
case $TZsec in
|
||||
$UTsec)
|
||||
extra_info="
|
||||
Local time is now: $TZdate.
|
||||
Universal Time is now: $UTdate."
|
||||
break
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
# Output TZ info and ask the user to confirm.
|
||||
|
||||
echo >&2 ""
|
||||
echo >&2 "The following information has been given:"
|
||||
echo >&2 ""
|
||||
case $country+$region in
|
||||
?*+?*) echo >&2 " $country$newline $region";;
|
||||
?*+) echo >&2 " $country";;
|
||||
+) echo >&2 " TZ='$TZ'"
|
||||
esac
|
||||
echo >&2 ""
|
||||
echo >&2 "Therefore TZ='$TZ' will be used.$extra_info"
|
||||
echo >&2 "Is the above information OK?"
|
||||
|
||||
ok=
|
||||
select ok in Yes No
|
||||
do
|
||||
case $ok in
|
||||
'') echo >&2 'Please enter 1 for Yes, or 2 for No.';;
|
||||
?*) break
|
||||
esac
|
||||
done
|
||||
case $ok in
|
||||
'') exit 1;;
|
||||
Yes) break
|
||||
esac
|
||||
do :
|
||||
done
|
||||
|
||||
case $SHELL in
|
||||
*csh) file=.login line="setenv TZ '$TZ'";;
|
||||
*) file=.profile line="TZ='$TZ'; export TZ"
|
||||
esac
|
||||
|
||||
echo >&2 "
|
||||
You can make this change permanent for yourself by appending the line
|
||||
$line
|
||||
to the file '$file' in your home directory; then log out and log in again.
|
||||
|
||||
Here is that TZ value again, this time on standard output so that you
|
||||
can use the $0 command in shell scripts:"
|
||||
|
||||
echo "$TZ"
|
2948
icu4c/source/tools/tzcode/zic.c
Normal file
2948
icu4c/source/tools/tzcode/zic.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user