1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** This file is in the public domain, so clarified as of 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** 2006-07-17 by Arthur David Olson. 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 6b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic char elsieid[] = "@(#)zic.c 8.18"; 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "private.h" 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "locale.h" 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "tzfile.h" 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZIC_VERSION '2' 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef int_fast64_t zic_t; 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef ZIC_MAX_ABBR_LEN_WO_WARN 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZIC_MAX_ABBR_LEN_WO_WARN 6 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */ 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if HAVE_SYS_STAT_H 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "sys/stat.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef S_IRUSR 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define MKDIR_UMASK 0755 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Enable extensions and modifications for ICU. */ 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ICU 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Continue executing after link failure. Even if ICU is undefined 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * (for vanilla zic behavior), ICU_LINKS should be defined, since zic 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * appears to fail on the 2003 data the first time through during the 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * linking phase. Running zic twice, with ICU_LINKS defined, causes 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * links to be handled correctly. */ 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ICU_LINKS 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "tz2icu.h" 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** On some ancient hosts, predicates like `isspace(C)' are defined 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** which says they are defined only if C == ((unsigned char) C) || C == EOF. 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Neither the C Standard nor Posix require that `isascii' exist. 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** For portability, we check both ancient and modern requirements. 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** If isascii is not defined, the isascii check succeeds trivially. 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ctype.h" 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef isascii 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define isascii(x) 1 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long)) 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */ 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define end(cp) (strchr((cp), '\0')) 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct rule { 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * r_filename; 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_linenum; 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * r_name; 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_loyear; /* for example, 1986 */ 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_hiyear; /* for example, 1986 */ 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * r_yrtype; 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_lowasnum; 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_hiwasnum; 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_month; /* 0..11 */ 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_dycode; /* see below */ 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_dayofmonth; 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_wday; 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru long r_tod; /* time from midnight */ 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_todisstd; /* above is standard time if TRUE */ 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* or wall clock time if FALSE */ 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_todisgmt; /* above is GMT if TRUE */ 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* or local time if FALSE */ 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru long r_stdoff; /* offset from standard time */ 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * r_abbrvar; /* variable part of abbreviation */ 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int r_todo; /* a rule to do (used in outzone) */ 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zic_t r_temp; /* used in outzone */ 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** r_dycode r_dayofmonth r_wday 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DC_DOM 0 /* 1..31 */ /* unused */ 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */ 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DC_DOWLEQ 2 /* 1..31 */ /* 0..6 (Sun..Sat) */ 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct zone { 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * z_filename; 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int z_linenum; 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * z_name; 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru long z_gmtoff; 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * z_rule; 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * z_format; 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru long z_stdoff; 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct rule * z_rules; 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int z_nrules; 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct rule z_untilrule; 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zic_t z_untiltime; 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 116b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruextern int getopt(int argc, char * const argv[], 117b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char * options); 118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruextern int link(const char * fromname, const char * toname); 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruextern char * optarg; 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruextern int optind; 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void addtt(zic_t starttime, int type); 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int addtype(long gmtoff, long rawoff, long dstoff, 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * abbr, int isdst, 126b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int ttisstd, int ttisgmt); 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int addtype(long gmtoff, const char * abbr, int isdst, 129b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int ttisstd, int ttisgmt); 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 131b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void leapadd(zic_t t, int positive, int rolling, int count); 132b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void adjleap(void); 133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void associate(void); 134b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int ciequal(const char * ap, const char * bp); 135b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void convert(long val, char * buf); 136b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void convert64(zic_t val, char * buf); 137b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void dolink(const char * fromfield, const char * tofield); 138b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void doabbr(char * abbr, const char * format, 139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char * letters, int isdst, int doquotes); 140b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void eat(const char * name, int num); 141b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void eats(const char * name, int num, 142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char * rname, int rnum); 143b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic long eitol(int i); 144b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void error(const char * message); 145b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic char ** getfields(char * buf); 146b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic long gethms(const char * string, const char * errstrng, 147b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int signable); 148b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void infile(const char * filename); 149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void inleap(char ** fields, int nfields); 150b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void inlink(char ** fields, int nfields); 151b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void inrule(char ** fields, int nfields); 152b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int inzcont(char ** fields, int nfields); 153b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int inzone(char ** fields, int nfields); 154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int inzsub(char ** fields, int nfields, int iscont); 155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int is32(zic_t x); 156b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int itsabbr(const char * abbr, const char * word); 157b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int itsdir(const char * name); 158b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int lowerit(int c); 159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic char * memcheck(char * tocheck); 160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int mkdirs(char * filename); 161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void newabbr(const char * abbr); 162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic long oadd(long t1, long t2); 163b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void outzone(const struct zone * zp, int ntzones); 164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void puttzcode(long code, FILE * fp); 165b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void puttzcode64(zic_t code, FILE * fp); 166b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int rcomp(const void * leftp, const void * rightp); 167b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic zic_t rpytime(const struct rule * rp, int wantedy); 168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void rulesub(struct rule * rp, 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * loyearp, const char * hiyearp, 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * typep, const char * monthp, 171b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char * dayp, const char * timep); 172b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int stringoffset(char * result, long offset); 173b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int stringrule(char * result, const struct rule * rp, 174b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru long dstoff, long gmtoff); 175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void stringzone(char * result, 176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct zone * zp, int ntzones); 177b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void setboundaries(void); 178b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic zic_t tadd(zic_t t1, long t2); 179b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void usage(FILE *stream, int status); 180b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void writezone(const char * name, const char * string); 181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int yearistype(int year, const char * type); 182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef ICU 183b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void emit_icu_zone(FILE* f, const char* zoneName, int zoneOffset, 184b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct rule* rule, 185b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int ruleIndex, int startYear); 186b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void emit_icu_link(FILE* f, const char* from, const char* to); 187b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void emit_icu_rule(FILE* f, const struct rule* r, int ruleIndex); 188b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int add_icu_final_rules(const struct rule* r1, const struct rule* r2); 189b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int charcnt; 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int errors; 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * filename; 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int leapcnt; 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int leapseen; 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int leapminyear; 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int leapmaxyear; 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int linenum; 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int max_abbrvar_len; 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int max_format_len; 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic zic_t max_time; 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int max_year; 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic zic_t min_time; 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int min_year; 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int noise; 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * rfilename; 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int rlinenum; 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * progname; 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int timecnt; 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int typecnt; 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Line codes. 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LC_RULE 0 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LC_ZONE 1 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LC_LINK 2 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LC_LEAP 3 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Which fields are which on a Zone line. 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZF_NAME 1 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZF_GMTOFF 2 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZF_RULE 3 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZF_FORMAT 4 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZF_TILYEAR 5 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZF_TILMONTH 6 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZF_TILDAY 7 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZF_TILTIME 8 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZONE_MINFIELDS 5 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZONE_MAXFIELDS 9 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Which fields are which on a Zone continuation line. 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZFC_GMTOFF 0 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZFC_RULE 1 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZFC_FORMAT 2 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZFC_TILYEAR 3 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZFC_TILMONTH 4 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZFC_TILDAY 5 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZFC_TILTIME 6 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZONEC_MINFIELDS 3 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZONEC_MAXFIELDS 7 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Which files are which on a Rule line. 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RF_NAME 1 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RF_LOYEAR 2 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RF_HIYEAR 3 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RF_COMMAND 4 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RF_MONTH 5 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RF_DAY 6 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RF_TOD 7 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RF_STDOFF 8 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RF_ABBRVAR 9 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RULE_FIELDS 10 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Which fields are which on a Link line. 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LF_FROM 1 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LF_TO 2 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LINK_FIELDS 3 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Which fields are which on a Leap line. 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LP_YEAR 1 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LP_MONTH 2 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LP_DAY 3 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LP_TIME 4 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LP_CORR 5 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LP_ROLL 6 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LEAP_FIELDS 7 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Year synonyms. 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define YR_MINIMUM 0 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define YR_MAXIMUM 1 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define YR_ONLY 2 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct rule * rules; 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int nrules; /* number of rules */ 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct zone * zones; 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int nzones; /* number of zones */ 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct link { 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * l_filename; 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int l_linenum; 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * l_from; 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * l_to; 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct link * links; 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int nlinks; 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct lookup { 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * l_word; 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int l_value; 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Indices into rules[] for final rules. They will occur in pairs, 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * with finalRules[i] occurring before finalRules[i+1] in the year. 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Each zone need only store a start year, a standard offset, and an 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * index into finalRules[]. FinalRules[] are aliases into rules[]. */ 319b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const struct rule ** finalRules; 320b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int finalRulesCount; 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 323b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic struct lookup const * byword(const char * string, 324b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct lookup * lp); 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct lookup const line_codes[] = { 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Rule", LC_RULE }, 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Zone", LC_ZONE }, 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Link", LC_LINK }, 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Leap", LC_LEAP }, 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { NULL, 0} 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct lookup const mon_names[] = { 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "January", TM_JANUARY }, 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "February", TM_FEBRUARY }, 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "March", TM_MARCH }, 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "April", TM_APRIL }, 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "May", TM_MAY }, 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "June", TM_JUNE }, 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "July", TM_JULY }, 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "August", TM_AUGUST }, 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "September", TM_SEPTEMBER }, 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "October", TM_OCTOBER }, 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "November", TM_NOVEMBER }, 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "December", TM_DECEMBER }, 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { NULL, 0 } 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct lookup const wday_names[] = { 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Sunday", TM_SUNDAY }, 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Monday", TM_MONDAY }, 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Tuesday", TM_TUESDAY }, 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Wednesday", TM_WEDNESDAY }, 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Thursday", TM_THURSDAY }, 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Friday", TM_FRIDAY }, 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Saturday", TM_SATURDAY }, 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { NULL, 0 } 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct lookup const lasts[] = { 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "last-Sunday", TM_SUNDAY }, 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "last-Monday", TM_MONDAY }, 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "last-Tuesday", TM_TUESDAY }, 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "last-Wednesday", TM_WEDNESDAY }, 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "last-Thursday", TM_THURSDAY }, 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "last-Friday", TM_FRIDAY }, 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "last-Saturday", TM_SATURDAY }, 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { NULL, 0 } 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct lookup const begin_years[] = { 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "minimum", YR_MINIMUM }, 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "maximum", YR_MAXIMUM }, 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { NULL, 0 } 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct lookup const end_years[] = { 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "minimum", YR_MINIMUM }, 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "maximum", YR_MAXIMUM }, 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "only", YR_ONLY }, 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { NULL, 0 } 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct lookup const leap_types[] = { 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Rolling", TRUE }, 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "Stationary", FALSE }, 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { NULL, 0 } 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const int len_months[2][MONSPERYEAR] = { 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const int len_years[2] = { 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DAYSPERNYEAR, DAYSPERLYEAR 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct attype { 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zic_t at; 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned char type; 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} attypes[TZ_MAX_TIMES]; 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic long gmtoffs[TZ_MAX_TYPES]; 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* gmtoffs[i] = rawoffs[i] + dstoffs[i] */ 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic long rawoffs[TZ_MAX_TYPES]; 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic long dstoffs[TZ_MAX_TYPES]; 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char isdsts[TZ_MAX_TYPES]; 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic unsigned char abbrinds[TZ_MAX_TYPES]; 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char ttisstds[TZ_MAX_TYPES]; 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char ttisgmts[TZ_MAX_TYPES]; 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char chars[TZ_MAX_CHARS]; 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic zic_t trans[TZ_MAX_LEAPS]; 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic long corr[TZ_MAX_LEAPS]; 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char roll[TZ_MAX_LEAPS]; 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Memory allocation. 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char * 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querumemcheck(ptr) 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruchar * const ptr; 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ptr == NULL) { 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *e = strerror(errno); 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _("%s: Memory exhausted: %s\n"), 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, e); 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ptr; 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define emalloc(size) memcheck(imalloc(size)) 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define erealloc(ptr, size) memcheck(irealloc((ptr), (size))) 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ecpyalloc(ptr) memcheck(icpyalloc(ptr)) 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ecatalloc(oldp, newp) memcheck(icatalloc((oldp), (newp))) 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Error handling. 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querueats(name, num, rname, rnum) 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const name; 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int num; 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const rname; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int rnum; 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru filename = name; 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru linenum = num; 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rfilename = rname; 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rlinenum = rnum; 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querueat(name, num) 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const name; 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int num; 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eats(name, num, (char *) NULL, -1); 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruerror(string) 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const string; 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Match the format of "cc" to allow sh users to 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** zic ... 2>&1 | error -t "*" -v 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** on BSD systems. 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _("\"%s\", line %d: %s"), 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru filename, linenum, string); 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rfilename != NULL) 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _(" (rule from \"%s\", line %d)"), 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rfilename, rlinenum); 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, "\n"); 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++errors; 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwarning(string) 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const string; 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char * cp; 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = ecpyalloc(_("warning: ")); 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = ecatalloc(cp, string); 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(cp); 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(cp); 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --errors; 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 499b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruusage(FILE *stream, int status) 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 501b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (void) fprintf(stream, _("%s: usage is %s \ 502b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru[ --version ] [ --help ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\ 503b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\ 504b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru\n\ 505b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruReport bugs to tz@elsie.nci.nih.gov.\n"), 506b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru progname, progname); 507b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru exit(status); 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* File into which we will write supplemental ICU data. */ 512b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic FILE * icuFile; 513b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 514b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 515b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruemit_icu_zone(FILE* f, const char* zoneName, int zoneOffset, 516b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct rule* rule, 517b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int ruleIndex, int startYear) { 518b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* machine-readable section */ 519b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, "zone %s %d %d %s", zoneName, zoneOffset, startYear, rule->r_name); 520b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 521b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* human-readable section */ 522b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, " # zone %s, offset %d, year >= %d, rule %s (%d)\n", 523b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru zoneName, zoneOffset, startYear, 524b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru rule->r_name, ruleIndex); 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 527b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 528b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruemit_icu_link(FILE* f, const char* from, const char* to) { 529b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* machine-readable section */ 530b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, "link %s %s\n", from, to); 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* DYCODE[] = {"DOM", "DOWGEQ", "DOWLEQ"}; 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 535b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 536b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruemit_icu_rule(FILE* f, const struct rule* r, int ruleIndex) { 537b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (r->r_yrtype != NULL) { 538b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru warning("year types not supported by ICU"); 539b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(stderr, "rule %s, file %s, line %d\n", 540b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru r->r_name, r->r_filename, r->r_linenum); 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* machine-readable section */ 544b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, "rule %s %s %d %d %d %ld %d %d %ld", 545b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru r->r_name, DYCODE[r->r_dycode], 546b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru r->r_month, r->r_dayofmonth, 547b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (r->r_dycode == DC_DOM ? -1 : r->r_wday), 548b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru r->r_tod, r->r_todisstd, r->r_todisgmt, r->r_stdoff 549b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ); 550b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 551b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* human-readable section */ 552b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, " # %d: %s, file %s, line %d", 553b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ruleIndex, r->r_name, r->r_filename, r->r_linenum); 554b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, ", mode %s", DYCODE[r->r_dycode]); 555b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, ", %s, dom %d", mon_names[r->r_month].l_word, r->r_dayofmonth); 556b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (r->r_dycode != DC_DOM) { 557b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, ", %s", wday_names[r->r_wday].l_word); 558b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 559b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, ", time %ld", r->r_tod); 560b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, ", isstd %d", r->r_todisstd); 561b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, ", isgmt %d", r->r_todisgmt); 562b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, ", offset %ld", r->r_stdoff); 563b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fprintf(f, "\n"); 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 566b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int 567b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruadd_icu_final_rules(const struct rule* r1, const struct rule* r2) { 568b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int i; 569b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 570b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (i=0; i<finalRulesCount; ++i) { /* i+=2 should work too */ 571b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (r1==finalRules[i]) return i; /* [sic] pointer comparison */ 572b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 573b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 574b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru finalRules = (const struct rule**) (void*) erealloc((char *) finalRules, 575b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (finalRulesCount + 2) * sizeof(*finalRules)); 576b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru finalRules[finalRulesCount++] = r1; 577b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru finalRules[finalRulesCount++] = r2; 578b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return finalRulesCount - 2; 579b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * psxrules; 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * lcltime; 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * directory; 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * leapsec; 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * yitcommand; 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querumain(argc, argv) 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint argc; 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruchar * argv[]; 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i; 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int j; 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int c; 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef unix 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* defined unix */ 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if HAVE_GETTEXT 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) setlocale(LC_ALL, ""); 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef TZ_DOMAINDIR 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* defined TEXTDOMAINDIR */ 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) textdomain(TZ_DOMAIN); 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* HAVE_GETTEXT */ 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname = argv[0]; 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (TYPE_BIT(zic_t) < 64) { 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, "%s: %s\n", progname, 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru _("wild compilation-time specification of zic_t")); 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 1; i < argc; ++i) 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(argv[i], "--version") == 0) { 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) printf("%s\n", elsieid); 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_SUCCESS); 617b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if (strcmp(argv[i], "--help") == 0) { 618b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru usage(stdout, EXIT_SUCCESS); 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF && c != -1) 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (c) { 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 623b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru usage(stderr, EXIT_FAILURE); 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'd': 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (directory == NULL) 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru directory = optarg; 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("%s: More than one -d option specified\n"), 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname); 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'l': 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lcltime == NULL) 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lcltime = optarg; 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("%s: More than one -l option specified\n"), 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname); 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'p': 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (psxrules == NULL) 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru psxrules = optarg; 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("%s: More than one -p option specified\n"), 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname); 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'y': 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (yitcommand == NULL) 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru yitcommand = optarg; 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("%s: More than one -y option specified\n"), 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname); 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'L': 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (leapsec == NULL) 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leapsec = optarg; 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("%s: More than one -L option specified\n"), 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname); 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'v': 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru noise = TRUE; 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 's': 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) printf("%s: -s ignored\n", progname); 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (optind == argc - 1 && strcmp(argv[optind], "=") == 0) 682b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru usage(stderr, EXIT_FAILURE); /* usage message by request */ 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (directory == NULL) 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru directory = TZDIR; 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (yitcommand == NULL) 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru yitcommand = "yearistype"; 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setboundaries(); 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (optind < argc && leapsec != NULL) { 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru infile(leapsec); 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru adjleap(); 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((icuFile = fopen(ICU_ZONE_FILE, "w")) == NULL) { 697b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char *e = strerror(errno); 698b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (void) fprintf(stderr, _("%s: Can't open %s: %s\n"), 699b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru progname, ICU_ZONE_FILE, e); 700b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (void) exit(EXIT_FAILURE); 701b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = optind; i < argc; ++i) 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru infile(argv[i]); 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (errors) 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru associate(); 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < nzones; i = j) { 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Find the next non-continuation zone entry. 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j) 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outzone(&zones[i], j - i); 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Make links. 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < nlinks; ++i) { 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eat(links[i].l_filename, links[i].l_linenum); 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dolink(links[i].l_from, links[i].l_to); 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 723b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru emit_icu_link(icuFile, links[i].l_from, links[i].l_to); 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (noise) 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = 0; j < nlinks; ++j) 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(links[i].l_to, 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru links[j].l_from) == 0) 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(_("link to link")); 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lcltime != NULL) { 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eat("command line", 1); 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dolink(lcltime, TZDEFAULT); 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (psxrules != NULL) { 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eat("command line", 1); 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dolink(psxrules, TZDEFRULES); 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 740b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (i=0; i<finalRulesCount; ++i) { 741b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru emit_icu_rule(icuFile, finalRules[i], i); 742b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /*ICU*/ 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 748b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querudolink(fromfield, tofield) 749b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruconst char * const fromfield; 750b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruconst char * const tofield; 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * fromname; 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * toname; 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 755b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (fromfield[0] == '/') 756b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fromname = ecpyalloc(fromfield); 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fromname = ecpyalloc(directory); 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fromname = ecatalloc(fromname, "/"); 760b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fromname = ecatalloc(fromname, fromfield); 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 762b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (tofield[0] == '/') 763b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toname = ecpyalloc(tofield); 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru toname = ecpyalloc(directory); 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru toname = ecatalloc(toname, "/"); 767b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toname = ecatalloc(toname, tofield); 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** We get to be careful here since 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** there's a fair chance of root running us. 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!itsdir(toname)) 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) remove(toname); 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (link(fromname, toname) != 0) { 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int result; 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (mkdirs(toname) != 0) 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = link(fromname, toname); 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if HAVE_SYMLINK 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result != 0 && 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru access(fromname, F_OK) == 0 && 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru !itsdir(fromname)) { 786b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char *s = tofield; 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * symlinkcontents = NULL; 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while ((s = strchr(s+1, '/')) != NULL) 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru symlinkcontents = 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ecatalloc(symlinkcontents, 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "../"); 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru symlinkcontents = 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ecatalloc(symlinkcontents, 795b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fromname); 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = symlink(symlinkcontents, 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru toname); 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == 0) 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwarning(_("hard link failed, symbolic link used")); 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(symlinkcontents); 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* HAVE_SYMLINK */ 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result != 0) { 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *e = strerror(errno); 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru _("%s: Can't link from %s to %s: %s\n"), 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, fromname, toname, e); 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef ICU_LINKS 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(fromname); 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(toname); 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define TIME_T_BITS_IN_FILE 64 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 821b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querusetboundaries(void) 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i; 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru min_time = -1; 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i) 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru min_time *= 2; 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max_time = -(min_time + 1); 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruitsdir(name) 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const name; 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * myname; 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int accres; 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru myname = ecpyalloc(name); 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru myname = ecatalloc(myname, "/."); 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru accres = access(myname, F_OK); 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(myname); 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return accres == 0; 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Associate sets of rules with zones. 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Sort by rule name. 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querurcomp(cp1, cp2) 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst void * cp1; 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst void * cp2; 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return strcmp(((const struct rule *) cp1)->r_name, 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((const struct rule *) cp2)->r_name); 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 863b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruassociate(void) 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register struct zone * zp; 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register struct rule * rp; 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int base, out; 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i, j; 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nrules != 0) { 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) qsort((void *) rules, (size_t) nrules, 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (size_t) sizeof *rules, rcomp); 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < nrules - 1; ++i) { 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(rules[i].r_name, 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rules[i + 1].r_name) != 0) 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(rules[i].r_filename, 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rules[i + 1].r_filename) == 0) 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eat(rules[i].r_filename, rules[i].r_linenum); 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(_("same rule name in multiple files")); 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eat(rules[i + 1].r_filename, rules[i + 1].r_linenum); 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(_("same rule name in multiple files")); 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = i + 2; j < nrules; ++j) { 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(rules[i].r_name, 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rules[j].r_name) != 0) 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(rules[i].r_filename, 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rules[j].r_filename) == 0) 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(rules[i + 1].r_filename, 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rules[j].r_filename) == 0) 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = j - 1; 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < nzones; ++i) { 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp = &zones[i]; 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp->z_rules = NULL; 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp->z_nrules = 0; 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (base = 0; base < nrules; base = out) { 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp = &rules[base]; 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (out = base + 1; out < nrules; ++out) 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(rp->r_name, rules[out].r_name) != 0) 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < nzones; ++i) { 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp = &zones[i]; 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(zp->z_rule, rp->r_name) != 0) 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp->z_rules = rp; 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp->z_nrules = out - base; 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < nzones; ++i) { 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp = &zones[i]; 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (zp->z_nrules == 0) { 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Maybe we have a local standard time offset. 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eat(zp->z_filename, zp->z_linenum); 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE); 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Note, though, that if there's no rule, 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** a '%s' in the format is a bad thing. 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strchr(zp->z_format, '%') != 0) 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("%s in ruleless zone")); 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (errors) 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinfile(name) 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * name; 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register FILE * fp; 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char ** fields; 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * cp; 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const struct lookup * lp; 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int nfields; 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int wantcont; 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int num; 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buf[BUFSIZ]; 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(name, "-") == 0) { 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = _("standard input"); 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fp = stdin; 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if ((fp = fopen(name, "r")) == NULL) { 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *e = strerror(errno); 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _("%s: Can't open %s: %s\n"), 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, name, e); 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wantcont = FALSE; 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (num = 1; ; ++num) { 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eat(name, num); 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fgets(buf, (int) sizeof buf, fp) != buf) 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = strchr(buf, '\n'); 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cp == NULL) { 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("line too long")); 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *cp = '\0'; 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fields = getfields(buf); 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nfields = 0; 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (fields[nfields] != NULL) { 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static char nada; 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(fields[nfields], "-") == 0) 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fields[nfields] = &nada; 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++nfields; 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nfields == 0) { 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* nothing to do */ 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (wantcont) { 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wantcont = inzcont(fields, nfields); 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lp = byword(fields[0], line_codes); 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lp == NULL) 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("input line of unknown type")); 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else switch ((int) (lp->l_value)) { 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case LC_RULE: 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inrule(fields, nfields); 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wantcont = FALSE; 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case LC_ZONE: 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wantcont = inzone(fields, nfields); 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case LC_LINK: 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inlink(fields, nfields); 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wantcont = FALSE; 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case LC_LEAP: 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (name != leapsec) 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("%s: Leap line in non leap seconds file %s\n"), 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, name); 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else inleap(fields, nfields); 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wantcont = FALSE; 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: /* "cannot happen" */ 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("%s: panic: Invalid l_value %d\n"), 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, lp->l_value); 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree((char *) fields); 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ferror(fp)) { 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _("%s: Error reading %s\n"), 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, filename); 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fp != stdin && fclose(fp)) { 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *e = strerror(errno); 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _("%s: Error closing %s: %s\n"), 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, filename, e); 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (wantcont) 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("expected continuation line not found")); 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Convert a string of one of the forms 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** h -h hh:mm -hh:mm hh:mm:ss -hh:mm:ss 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** into a number of seconds. 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** A null string maps to zero. 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Call error with errstring and return zero on errors. 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic long 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querugethms(string, errstring, signable) 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * string; 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const errstring; 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int signable; 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1048b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru long hh; 1049b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int mm, ss, sign; 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (string == NULL || *string == '\0') 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!signable) 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sign = 1; 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (*string == '-') { 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sign = -1; 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++string; 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else sign = 1; 1059b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (sscanf(string, scheck(string, "%ld"), &hh) == 1) 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mm = ss = 0; 1061b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else if (sscanf(string, scheck(string, "%ld:%d"), &hh, &mm) == 2) 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ss = 0; 1063b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else if (sscanf(string, scheck(string, "%ld:%d:%d"), 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &hh, &mm, &ss) != 3) { 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(errstring); 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1068b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (hh < 0 || 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mm < 0 || mm >= MINSPERHOUR || 1070b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ss < 0 || ss > SECSPERMIN) { 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(errstring); 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1074b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LONG_MAX / SECSPERHOUR < hh) { 1075b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error(_("time overflow")); 1076b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 1077b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1078b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (noise && hh == HOURSPERDAY && mm == 0 && ss == 0) 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(_("24:00 not handled by pre-1998 versions of zic")); 1080b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (noise && (hh > HOURSPERDAY || 1081b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (hh == HOURSPERDAY && (mm != 0 || ss != 0)))) 1082b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruwarning(_("values over 24 hours not handled by pre-2007 versions of zic")); 1083b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return oadd(eitol(sign) * hh * eitol(SECSPERHOUR), 1084b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss))); 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinrule(fields, nfields) 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister char ** const fields; 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int nfields; 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static struct rule r; 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nfields != RULE_FIELDS) { 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("wrong number of fields on Rule line")); 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*fields[RF_NAME] == '\0') { 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("nameless rule")); 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru r.r_filename = filename; 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru r.r_linenum = linenum; 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), TRUE); 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND], 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru r.r_name = ecpyalloc(fields[RF_NAME]); 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]); 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (max_abbrvar_len < strlen(r.r_abbrvar)) 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max_abbrvar_len = strlen(r.r_abbrvar); 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rules = (struct rule *) (void *) erealloc((char *) rules, 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (int) ((nrules + 1) * sizeof *rules)); 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rules[nrules++] = r; 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinzone(fields, nfields) 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister char ** const fields; 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int nfields; 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i; 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static char * buf; 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) { 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("wrong number of fields on Zone line")); 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) { 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT))); 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(buf, 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("\"Zone %s\" line and -l option are mutually exclusive"), 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TZDEFAULT); 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(buf); 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) { 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES))); 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(buf, 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("\"Zone %s\" line and -p option are mutually exclusive"), 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TZDEFRULES); 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(buf); 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < nzones; ++i) 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (zones[i].z_name != NULL && 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) { 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf = erealloc(buf, (int) (132 + 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strlen(fields[ZF_NAME]) + 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strlen(zones[i].z_filename))); 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(buf, 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("duplicate zone name %s (file \"%s\", line %d)"), 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fields[ZF_NAME], 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zones[i].z_filename, 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zones[i].z_linenum); 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(buf); 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return inzsub(fields, nfields, FALSE); 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinzcont(fields, nfields) 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister char ** const fields; 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int nfields; 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) { 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("wrong number of fields on Zone continuation line")); 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return inzsub(fields, nfields, TRUE); 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinzsub(fields, nfields, iscont) 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister char ** const fields; 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int nfields; 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int iscont; 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * cp; 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static struct zone z; 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i_gmtoff, i_rule, i_format; 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i_untilyear, i_untilmonth; 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i_untilday, i_untiltime; 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int hasuntil; 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (iscont) { 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_gmtoff = ZFC_GMTOFF; 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_rule = ZFC_RULE; 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_format = ZFC_FORMAT; 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_untilyear = ZFC_TILYEAR; 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_untilmonth = ZFC_TILMONTH; 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_untilday = ZFC_TILDAY; 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_untiltime = ZFC_TILTIME; 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_name = NULL; 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_gmtoff = ZF_GMTOFF; 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_rule = ZF_RULE; 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_format = ZF_FORMAT; 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_untilyear = ZF_TILYEAR; 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_untilmonth = ZF_TILMONTH; 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_untilday = ZF_TILDAY; 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i_untiltime = ZF_TILTIME; 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_name = ecpyalloc(fields[ZF_NAME]); 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_filename = filename; 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_linenum = linenum; 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UTC offset"), TRUE); 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((cp = strchr(fields[i_format], '%')) != 0) { 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*++cp != 's' || strchr(cp, '%') != 0) { 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid abbreviation format")); 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_rule = ecpyalloc(fields[i_rule]); 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_format = ecpyalloc(fields[i_format]); 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (max_format_len < strlen(z.z_format)) 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max_format_len = strlen(z.z_format); 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hasuntil = nfields > i_untilyear; 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (hasuntil) { 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_untilrule.r_filename = filename; 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_untilrule.r_linenum = linenum; 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rulesub(&z.z_untilrule, 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fields[i_untilyear], 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "only", 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "", 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (nfields > i_untilmonth) ? 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fields[i_untilmonth] : "Jan", 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (nfields > i_untilday) ? fields[i_untilday] : "1", 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (nfields > i_untiltime) ? fields[i_untiltime] : "0"); 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_untiltime = rpytime(&z.z_untilrule, 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_untilrule.r_loyear); 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (iscont && nzones > 0 && 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_untiltime > min_time && 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru z.z_untiltime < max_time && 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zones[nzones - 1].z_untiltime > min_time && 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zones[nzones - 1].z_untiltime < max_time && 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zones[nzones - 1].z_untiltime >= z.z_untiltime) { 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_( 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru"Zone continuation line end time is not after end time of previous line" 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru )); 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zones = (struct zone *) (void *) erealloc((char *) zones, 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (int) ((nzones + 1) * sizeof *zones)); 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zones[nzones++] = z; 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** If there was an UNTIL field on this line, 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** there's more information about the zone on the next line. 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return hasuntil; 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinleap(fields, nfields) 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister char ** const fields; 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int nfields; 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const char * cp; 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const struct lookup * lp; 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i, j; 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int year, month, day; 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru long dayoff, tod; 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zic_t t; 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nfields != LEAP_FIELDS) { 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("wrong number of fields on Leap line")); 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = 0; 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = fields[LP_YEAR]; 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (sscanf(cp, scheck(cp, "%d"), &year) != 1) { 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Leapin' Lizards! 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid leaping year")); 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!leapseen || leapmaxyear < year) 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leapmaxyear = year; 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!leapseen || leapminyear > year) 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leapminyear = year; 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leapseen = TRUE; 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j = EPOCH_YEAR; 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (j != year) { 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (year > j) { 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = len_years[isleap(j)]; 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++j; 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --j; 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = -len_years[isleap(j)]; 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = oadd(dayoff, eitol(i)); 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) { 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid month name")); 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru month = lp->l_value; 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j = TM_JANUARY; 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (j != month) { 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = len_months[isleap(year)][j]; 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = oadd(dayoff, eitol(i)); 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++j; 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = fields[LP_DAY]; 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (sscanf(cp, scheck(cp, "%d"), &day) != 1 || 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru day <= 0 || day > len_months[isleap(year)][month]) { 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid day of month")); 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = oadd(dayoff, eitol(day - 1)); 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dayoff < 0 && !TYPE_SIGNED(zic_t)) { 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("time before zero")); 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dayoff < min_time / SECSPERDAY) { 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("time too small")); 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dayoff > max_time / SECSPERDAY) { 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("time too large")); 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t = (zic_t) dayoff * SECSPERDAY; 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE); 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = fields[LP_CORR]; 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int positive; 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int count; 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */ 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru positive = FALSE; 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count = 1; 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (strcmp(cp, "--") == 0) { 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru positive = FALSE; 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count = 2; 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (strcmp(cp, "+") == 0) { 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru positive = TRUE; 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count = 1; 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (strcmp(cp, "++") == 0) { 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru positive = TRUE; 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count = 2; 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("illegal CORRECTION field on Leap line")); 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) { 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_( 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "illegal Rolling/Stationary field on Leap line" 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru )); 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leapadd(tadd(t, tod), positive, lp->l_value, count); 1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinlink(fields, nfields) 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister char ** const fields; 1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int nfields; 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct link l; 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nfields != LINK_FIELDS) { 1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("wrong number of fields on Link line")); 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*fields[LF_FROM] == '\0') { 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("blank FROM field on Link line")); 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*fields[LF_TO] == '\0') { 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("blank TO field on Link line")); 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru l.l_filename = filename; 1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru l.l_linenum = linenum; 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru l.l_from = ecpyalloc(fields[LF_FROM]); 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru l.l_to = ecpyalloc(fields[LF_TO]); 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru links = (struct link *) (void *) erealloc((char *) links, 1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (int) ((nlinks + 1) * sizeof *links)); 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru links[nlinks++] = l; 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querurulesub(rp, loyearp, hiyearp, typep, monthp, dayp, timep) 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister struct rule * const rp; 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const loyearp; 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const hiyearp; 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const typep; 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const monthp; 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const dayp; 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const timep; 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const struct lookup * lp; 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const char * cp; 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * dp; 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * ep; 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((lp = byword(monthp, mon_names)) == NULL) { 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid month name")); 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_month = lp->l_value; 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisstd = FALSE; 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisgmt = FALSE; 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dp = ecpyalloc(timep); 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*dp != '\0') { 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ep = dp + strlen(dp) - 1; 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (lowerit(*ep)) { 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 's': /* Standard */ 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisstd = TRUE; 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisgmt = FALSE; 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ep = '\0'; 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'w': /* Wall */ 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisstd = FALSE; 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisgmt = FALSE; 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ep = '\0'; 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'g': /* Greenwich */ 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'u': /* Universal */ 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 'z': /* Zulu */ 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisstd = TRUE; 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisgmt = TRUE; 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ep = '\0'; 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_tod = gethms(dp, _("invalid time of day"), FALSE); 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(dp); 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Year work. 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = loyearp; 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lp = byword(cp, begin_years); 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_lowasnum = lp == NULL; 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!rp->r_lowasnum) switch ((int) lp->l_value) { 1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case YR_MINIMUM: 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_loyear = INT_MIN; 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case YR_MAXIMUM: 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_loyear = INT_MAX; 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: /* "cannot happen" */ 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru _("%s: panic: Invalid l_value %d\n"), 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, lp->l_value); 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) { 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid starting year")); 1453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = hiyearp; 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lp = byword(cp, end_years); 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_hiwasnum = lp == NULL; 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!rp->r_hiwasnum) switch ((int) lp->l_value) { 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case YR_MINIMUM: 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_hiyear = INT_MIN; 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case YR_MAXIMUM: 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_hiyear = INT_MAX; 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case YR_ONLY: 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_hiyear = rp->r_loyear; 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: /* "cannot happen" */ 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru _("%s: panic: Invalid l_value %d\n"), 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, lp->l_value); 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) { 1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid ending year")); 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_loyear > rp->r_hiyear) { 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("starting year greater than ending year")); 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*typep == '\0') 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_yrtype = NULL; 1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_loyear == rp->r_hiyear) { 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("typed single year")); 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_yrtype = ecpyalloc(typep); 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Day work. 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Accept things such as: 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** 1 1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** last-Sunday 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Sun<=20 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Sun>=7 1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dp = ecpyalloc(dayp); 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((lp = byword(dp, lasts)) != NULL) { 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_dycode = DC_DOWLEQ; 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_wday = lp->l_value; 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_dayofmonth = len_months[1][rp->r_month]; 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((ep = strchr(dp, '<')) != 0) 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_dycode = DC_DOWLEQ; 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if ((ep = strchr(dp, '>')) != 0) 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_dycode = DC_DOWGEQ; 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ep = dp; 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_dycode = DC_DOM; 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_dycode != DC_DOM) { 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ep++ = 0; 1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*ep++ != '=') { 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid day of month")); 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(dp); 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((lp = byword(dp, wday_names)) == NULL) { 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid weekday name")); 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(dp); 1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_wday = lp->l_value; 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (sscanf(ep, scheck(ep, "%d"), &rp->r_dayofmonth) != 1 || 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_dayofmonth <= 0 || 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (rp->r_dayofmonth > len_months[1][rp->r_month])) { 1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("invalid day of month")); 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(dp); 1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(dp); 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconvert(val, buf) 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long val; 1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruchar * const buf; 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i; 1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int shift; 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0, shift = 24; i < 4; ++i, shift -= 8) 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf[i] = val >> shift; 1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconvert64(val, buf) 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst zic_t val; 1552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruchar * const buf; 1553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i; 1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int shift; 1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0, shift = 56; i < 8; ++i, shift -= 8) 1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf[i] = val >> shift; 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruputtzcode(val, fp) 1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long val; 1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruFILE * const fp; 1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buf[4]; 1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru convert(val, buf); 1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); 1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruputtzcode64(val, fp) 1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst zic_t val; 1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruFILE * const fp; 1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buf[8]; 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru convert64(val, buf); 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruatcomp(avp, bvp) 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst void * avp; 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst void * bvp; 1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const zic_t a = ((const struct attype *) avp)->at; 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const zic_t b = ((const struct attype *) bvp)->at; 1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (a < b) ? -1 : (a > b); 1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruis32(x) 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst zic_t x; 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return INT32_MIN <= x && x <= INT32_MAX; 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwritezone(name, string) 1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const name; 1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const string; 1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register FILE * fp; 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i, j; 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int leapcnt32, leapi32; 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int timecnt32, timei32; 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int pass; 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static char * fullname; 1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static const struct tzhead tzh0; 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static struct tzhead tzh; 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zic_t ats[TZ_MAX_TIMES]; 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned char types[TZ_MAX_TIMES]; 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Sort. 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (timecnt > 1) 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) qsort((void *) attypes, (size_t) timecnt, 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (size_t) sizeof *attypes, atcomp); 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Optimize. 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int fromi; 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int toi; 1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru toi = 0; 1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fromi = 0; 1632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (fromi < timecnt && attypes[fromi].at < min_time) 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fromi; 1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isdsts[0] == 0) 1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (fromi < timecnt && attypes[fromi].type == 0) 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fromi; /* handled by default rule */ 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for ( ; fromi < timecnt; ++fromi) { 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (toi != 0 && ((attypes[fromi].at + 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gmtoffs[attypes[toi - 1].type]) <= 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (attypes[toi - 1].at + gmtoffs[toi == 1 ? 0 1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : attypes[toi - 2].type]))) { 1642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru attypes[toi - 1].type = 1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru attypes[fromi].type; 1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (toi == 0 || 1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru attypes[toi - 1].type != attypes[fromi].type) 1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru attypes[toi++] = attypes[fromi]; 1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru timecnt = toi; 1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Transfer. 1654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < timecnt; ++i) { 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ats[i] = attypes[i].at; 1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru types[i] = attypes[i].type; 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Correct for leap seconds. 1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < timecnt; ++i) { 1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j = leapcnt; 1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (--j >= 0) 1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ats[i] > trans[j] - corr[j]) { 1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ats[i] = tadd(ats[i], corr[j]); 1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Figure out 32-bit-limited starts and counts. 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru timecnt32 = timecnt; 1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru timei32 = 0; 1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leapcnt32 = leapcnt; 1676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leapi32 = 0; 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (timecnt32 > 0 && !is32(ats[timecnt32 - 1])) 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --timecnt32; 1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (timecnt32 > 0 && !is32(ats[timei32])) { 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --timecnt32; 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++timei32; 1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1])) 1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --leapcnt32; 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (leapcnt32 > 0 && !is32(trans[leapi32])) { 1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --leapcnt32; 1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++leapi32; 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fullname = erealloc(fullname, 1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (int) (strlen(directory) + 1 + strlen(name) + 1)); 1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(fullname, "%s/%s", directory, name); 1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Remove old file, if any, to snap links. 1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!itsdir(fullname) && remove(fullname) != 0 && errno != ENOENT) { 1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *e = strerror(errno); 1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _("%s: Can't remove %s: %s\n"), 1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, fullname, e); 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((fp = fopen(fullname, "wb")) == NULL) { 1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (mkdirs(fullname) != 0) 1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((fp = fopen(fullname, "wb")) == NULL) { 1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *e = strerror(errno); 1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _("%s: Can't create %s: %s\n"), 1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, fullname, e); 1710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (pass = 1; pass <= 2; ++pass) { 1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int thistimei, thistimecnt; 1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int thisleapi, thisleapcnt; 1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int thistimelim, thisleaplim; 1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int writetype[TZ_MAX_TIMES]; 1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int typemap[TZ_MAX_TYPES]; 1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int thistypecnt; 1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char thischars[TZ_MAX_CHARS]; 1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char thischarcnt; 1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int indmap[TZ_MAX_CHARS]; 1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pass == 1) { 1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thistimei = timei32; 1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thistimecnt = timecnt32; 1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thisleapi = leapi32; 1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thisleapcnt = leapcnt32; 1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thistimei = 0; 1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thistimecnt = timecnt; 1732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thisleapi = 0; 1733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thisleapcnt = leapcnt; 1734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thistimelim = thistimei + thistimecnt; 1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thisleaplim = thisleapi + thisleapcnt; 1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < typecnt; ++i) 1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru writetype[i] = thistimecnt == timecnt; 1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (thistimecnt == 0) { 1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** No transition times fall in the current 1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** (32- or 64-bit) window. 1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (typecnt != 0) 1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru writetype[typecnt - 1] = TRUE; 1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = thistimei - 1; i < thistimelim; ++i) 1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i >= 0) 1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru writetype[types[i]] = TRUE; 1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** For America/Godthab and Antarctica/Palmer 1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (thistimei == 0) 1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru writetype[0] = TRUE; 1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thistypecnt = 0; 1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < typecnt; ++i) 1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru typemap[i] = writetype[i] ? thistypecnt++ : -1; 1759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i) 1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indmap[i] = -1; 1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thischarcnt = 0; 1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < typecnt; ++i) { 1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * thisabbr; 1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!writetype[i]) 1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (indmap[abbrinds[i]] >= 0) 1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thisabbr = &chars[abbrinds[i]]; 1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = 0; j < thischarcnt; ++j) 1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(&thischars[j], thisabbr) == 0) 1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (j == thischarcnt) { 1774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcpy(&thischars[(int) thischarcnt], 1775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thisabbr); 1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru thischarcnt += strlen(thisabbr) + 1; 1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indmap[abbrinds[i]] = j; 1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DO(field) (void) fwrite((void *) tzh.field, \ 1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (size_t) sizeof tzh.field, (size_t) 1, fp) 1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tzh = tzh0; 1783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 1784b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * (ICUZoneinfoVersion*) &tzh.tzh_reserved = TZ_ICU_VERSION; 1785b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (void) strncpy(tzh.tzh_magic, TZ_ICU_MAGIC, sizeof tzh.tzh_magic); 1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 1787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); 1788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tzh.tzh_version[0] = ZIC_VERSION; 1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt); 1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt); 1792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru convert(eitol(thisleapcnt), tzh.tzh_leapcnt); 1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru convert(eitol(thistimecnt), tzh.tzh_timecnt); 1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru convert(eitol(thistypecnt), tzh.tzh_typecnt); 1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru convert(eitol(thischarcnt), tzh.tzh_charcnt); 1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DO(tzh_magic); 1797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DO(tzh_version); 1798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DO(tzh_reserved); 1799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DO(tzh_ttisgmtcnt); 1800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DO(tzh_ttisstdcnt); 1801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DO(tzh_leapcnt); 1802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DO(tzh_timecnt); 1803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DO(tzh_typecnt); 1804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DO(tzh_charcnt); 1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#undef DO 1806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = thistimei; i < thistimelim; ++i) 1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pass == 1) 1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru puttzcode((long) ats[i], fp); 1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else puttzcode64(ats[i], fp); 1810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = thistimei; i < thistimelim; ++i) { 1811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned char uc; 1812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uc = typemap[types[i]]; 1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fwrite((void *) &uc, 1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (size_t) sizeof uc, 1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (size_t) 1, 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fp); 1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < typecnt; ++i) 1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (writetype[i]) { 1821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 1822b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru puttzcode((long) rawoffs[i], fp); 1823b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru puttzcode((long) dstoffs[i], fp); 1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 1825b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru puttzcode(gmtoffs[i], fp); 1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) putc(isdsts[i], fp); 1828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) putc((unsigned char) indmap[abbrinds[i]], fp); 1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (thischarcnt != 0) 1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fwrite((void *) thischars, 1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (size_t) sizeof thischars[0], 1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (size_t) thischarcnt, fp); 1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = thisleapi; i < thisleaplim; ++i) { 1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register zic_t todo; 1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (roll[i]) { 1838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (timecnt == 0 || trans[i] < ats[0]) { 1839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j = 0; 1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (isdsts[j]) 1841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (++j >= typecnt) { 1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j = 0; 1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j = 1; 1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (j < timecnt && 1848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru trans[i] >= ats[j]) 1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++j; 1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j = types[j - 1]; 1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru todo = tadd(trans[i], -gmtoffs[j]); 1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else todo = trans[i]; 1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pass == 1) 1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru puttzcode((long) todo, fp); 1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else puttzcode64(todo, fp); 1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru puttzcode(corr[i], fp); 1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < typecnt; ++i) 1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (writetype[i]) 1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) putc(ttisstds[i], fp); 1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < typecnt; ++i) 1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (writetype[i]) 1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) putc(ttisgmts[i], fp); 1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(fp, "\n%s\n", string); 1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ferror(fp) || fclose(fp)) { 1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _("%s: Error writing %s\n"), 1869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, fullname); 1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querudoabbr(abbr, format, letters, isdst, doquotes) 1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruchar * const abbr; 1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const format; 1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const letters; 1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int isdst; 1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int doquotes; 1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * cp; 1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * slashp; 1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int len; 1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru slashp = strchr(format, '/'); 1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (slashp == NULL) { 1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (letters == NULL) 1889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcpy(abbr, format); 1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else (void) sprintf(abbr, format, letters); 1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (isdst) { 1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcpy(abbr, slashp + 1); 1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (slashp > format) 1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strncpy(abbr, format, 1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (unsigned) (slashp - format)); 1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru abbr[slashp - format] = '\0'; 1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!doquotes) 1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (cp = abbr; *cp != '\0'; ++cp) 1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL && 1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL) 1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = strlen(abbr); 1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len > 0 && *cp == '\0') 1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru abbr[len + 2] = '\0'; 1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru abbr[len + 1] = '>'; 1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for ( ; len > 0; --len) 1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru abbr[len] = abbr[len - 1]; 1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru abbr[0] = '<'; 1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruupdateminmax(x) 1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int x; 1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (min_year > x) 1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru min_year = x; 1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (max_year < x) 1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max_year = x; 1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustringoffset(result, offset) 1927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruchar * result; 1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulong offset; 1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int hours; 1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int minutes; 1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int seconds; 1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result[0] = '\0'; 1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (offset < 0) { 1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcpy(result, "-"); 1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = -offset; 1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru seconds = offset % SECSPERMIN; 1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset /= SECSPERMIN; 1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minutes = offset % MINSPERHOUR; 1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset /= MINSPERHOUR; 1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hours = offset; 1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (hours >= HOURSPERDAY) { 1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result[0] = '\0'; 1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(end(result), "%d", hours); 1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (minutes != 0 || seconds != 0) { 1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(end(result), ":%02d", minutes); 1951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (seconds != 0) 1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(end(result), ":%02d", seconds); 1953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustringrule(result, rp, dstoff, gmtoff) 1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruchar * result; 1960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst struct rule * const rp; 1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long dstoff; 1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long gmtoff; 1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register long tod; 1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = end(result); 1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_dycode == DC_DOM) { 1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int month, total; 1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY) 1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru total = 0; 1973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (month = 0; month < rp->r_month; ++month) 1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru total += len_months[0][month]; 1975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(result, "J%d", total + rp->r_dayofmonth); 1976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int week; 1978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_dycode == DC_DOWGEQ) { 1980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru week = 1 + rp->r_dayofmonth / DAYSPERWEEK; 1981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((week - 1) * DAYSPERWEEK + 1 != rp->r_dayofmonth) 1982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (rp->r_dycode == DC_DOWLEQ) { 1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_dayofmonth == len_months[1][rp->r_month]) 1985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru week = 5; 1986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru week = 1 + rp->r_dayofmonth / DAYSPERWEEK; 1988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (week * DAYSPERWEEK - 1 != rp->r_dayofmonth) 1989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else return -1; /* "cannot happen" */ 1992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(result, "M%d.%d.%d", 1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_month + 1, week, rp->r_wday); 1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tod = rp->r_tod; 1996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_todisgmt) 1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tod += gmtoff; 1998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_todisstd && rp->r_stdoff == 0) 1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tod += dstoff; 2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tod < 0) { 2001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result[0] = '\0'; 2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tod != 2 * SECSPERMIN * MINSPERHOUR) { 2005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcat(result, "/"); 2006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stringoffset(end(result), tod) != 0) 2007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustringzone(result, zpfirst, zonecount) 2014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruchar * result; 2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst struct zone * const zpfirst; 2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int zonecount; 2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const struct zone * zp; 2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register struct rule * rp; 2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register struct rule * stdrp; 2021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register struct rule * dstrp; 2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i; 2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const char * abbrvar; 2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result[0] = '\0'; 2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp = zpfirst + zonecount - 1; 2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stdrp = dstrp = NULL; 2028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < zp->z_nrules; ++i) { 2029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp = &zp->z_rules[i]; 2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX) 2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_yrtype != NULL) 2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 2034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_stdoff == 0) { 2035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stdrp == NULL) 2036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stdrp = rp; 2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else return; 2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dstrp == NULL) 2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dstrp = rp; 2041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else return; 2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stdrp == NULL && dstrp == NULL) { 2045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** There are no rules running through "max". 2047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Let's find the latest rule. 2048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < zp->z_nrules; ++i) { 2050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp = &zp->z_rules[i]; 2051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear || 2052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (rp->r_hiyear == stdrp->r_hiyear && 2053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_month > stdrp->r_month)) 2054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stdrp = rp; 2055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stdrp != NULL && stdrp->r_stdoff != 0) 2057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; /* We end up in DST (a POSIX no-no). */ 2058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Horrid special case: if year is 2037, 2060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** presume this is a zone handled on a year-by-year basis; 2061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** do not try to apply a rule to the zone. 2062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stdrp != NULL && stdrp->r_hiyear == 2037) 2064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stdrp == NULL && zp->z_nrules != 0) 2067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar; 2069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doabbr(result, zp->z_format, abbrvar, FALSE, TRUE); 2070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stringoffset(end(result), -zp->z_gmtoff) != 0) { 2071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result[0] = '\0'; 2072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dstrp == NULL) 2075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE); 2077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR) 2078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stringoffset(end(result), 2079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) { 2080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result[0] = '\0'; 2081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcat(result, ","); 2084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { 2085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result[0] = '\0'; 2086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcat(result, ","); 2089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { 2090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result[0] = '\0'; 2091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 2096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruoutzone(zpfirst, zonecount) 2097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst struct zone * const zpfirst; 2098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int zonecount; 2099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const struct zone * zp; 2101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register struct rule * rp; 2102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i, j; 2103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int usestart, useuntil; 2104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register zic_t starttime, untiltime; 2105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register long gmtoff; 2106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register long stdoff; 2107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int year; 2108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register long startoff; 2109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int startttisstd; 2110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int startttisgmt; 2111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int type; 2112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * startbuf; 2113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * ab; 2114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * envvar; 2115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int max_abbr_len; 2116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int max_envvar_len; 2117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int finalRuleYear, finalRuleIndex; 2119b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct rule* finalRule1; 2120b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct rule* finalRule2; 2121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max_abbr_len = 2 + max_format_len + max_abbrvar_len; 2124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max_envvar_len = 2 * max_abbr_len + 5 * 9; 2125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startbuf = emalloc(max_abbr_len + 1); 2126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ab = emalloc(max_abbr_len + 1); 2127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru envvar = emalloc(max_envvar_len + 1); 2128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru INITIALIZE(untiltime); 2129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru INITIALIZE(starttime); 2130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Now. . .finally. . .generate some useful data! 2132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru timecnt = 0; 2134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru typecnt = 0; 2135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charcnt = 0; 2136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Thanks to Earl Chew 2138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** for noting the need to unconditionally initialize startttisstd. 2139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startttisstd = FALSE; 2141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startttisgmt = FALSE; 2142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru min_year = max_year = EPOCH_YEAR; 2143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (leapseen) { 2144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru updateminmax(leapminyear); 2145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru updateminmax(leapmaxyear); 2146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < zonecount; ++i) { 2148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp = &zpfirst[i]; 2149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (i < zonecount - 1) 2150b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru updateminmax(zp->z_untilrule.r_loyear); 2151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = 0; j < zp->z_nrules; ++j) { 2152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp = &zp->z_rules[j]; 2153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_lowasnum) 2154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru updateminmax(rp->r_loyear); 2155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_hiwasnum) 2156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru updateminmax(rp->r_hiyear); 2157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Generate lots of data if a rule can't cover all future times. 2161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stringzone(envvar, zpfirst, zonecount); 2163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (noise && envvar[0] == '\0') { 2164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * wp; 2165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwp = ecpyalloc(_("no POSIX environment variable for zone")); 2167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wp = ecatalloc(wp, " "); 2168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru wp = ecatalloc(wp, zpfirst->z_name); 2169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(wp); 2170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(wp); 2171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (envvar[0] == '\0') { 2173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (min_year >= INT_MIN + YEARSPERREPEAT) 2174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru min_year -= YEARSPERREPEAT; 2175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else min_year = INT_MIN; 2176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (max_year <= INT_MAX - YEARSPERREPEAT) 2177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max_year += YEARSPERREPEAT; 2178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else max_year = INT_MAX; 2179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ** For the benefit of older systems, 2182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ** generate data from 1900 through 2037. 2183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2184b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (min_year > 1900) 2185b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru min_year = 1900; 2186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (max_year < 2037) 2187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max_year = 2037; 2188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < zonecount; ++i) { 2189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** A guess that may well be corrected later. 2191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stdoff = 0; 2193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp = &zpfirst[i]; 2194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru usestart = i > 0 && (zp - 1)->z_untiltime > min_time; 2195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru useuntil = i < (zonecount - 1); 2196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (useuntil && zp->z_untiltime <= min_time) 2197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 2198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gmtoff = zp->z_gmtoff; 2199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eat(zp->z_filename, zp->z_linenum); 2200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *startbuf = '\0'; 2201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startoff = zp->z_gmtoff; 2202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2203b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru finalRuleYear = finalRuleIndex = -1; 2204b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru finalRule1 = finalRule2 = NULL; 2205b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (i == (zonecount - 1)) { /* !useuntil */ 2206b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Look for exactly 2 rules that end at 'max' and 2207b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * note them. Determine max(r_loyear) for the 2 of 2208b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * them. */ 2209b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (j=0; j<zp->z_nrules; ++j) { 2210b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru rp = &zp->z_rules[j]; 2211b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (rp->r_hiyear == INT_MAX) { 22128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (rp->r_loyear > finalRuleYear) { 22138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius finalRuleYear = rp->r_loyear; 22148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 2215b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (finalRule1 == NULL) { 2216b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru finalRule1 = rp; 22178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (finalRule2 == NULL) { 2218b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru finalRule2 = rp; 2219b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 2220b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error("more than two max rules found (ICU)"); 2221b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru exit(EXIT_FAILURE); 2222b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 22238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (rp->r_hiyear >= finalRuleYear) { 22248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius /* There might be an overriding non-max rule 222559d709d503bab6e2b61931737e662dd293b40578ccornelius * to be applied to a specific year after one of 222659d709d503bab6e2b61931737e662dd293b40578ccornelius * max rule's start year. For example, 222759d709d503bab6e2b61931737e662dd293b40578ccornelius * 222859d709d503bab6e2b61931737e662dd293b40578ccornelius * Rule Foo 2010 max ... 222959d709d503bab6e2b61931737e662dd293b40578ccornelius * Rule Foo 2015 only ... 223059d709d503bab6e2b61931737e662dd293b40578ccornelius * 223159d709d503bab6e2b61931737e662dd293b40578ccornelius * In this case, we need to change the start year of 223259d709d503bab6e2b61931737e662dd293b40578ccornelius * the final (max) rules to the next year. */ 22338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius finalRuleYear = rp->r_hiyear + 1; 223459d709d503bab6e2b61931737e662dd293b40578ccornelius 223559d709d503bab6e2b61931737e662dd293b40578ccornelius /* When above adjustment is done, max_year might need 223659d709d503bab6e2b61931737e662dd293b40578ccornelius * to be adjusted, so the final rule will be properly 223759d709d503bab6e2b61931737e662dd293b40578ccornelius * evaluated and emitted by the later code block. 223859d709d503bab6e2b61931737e662dd293b40578ccornelius * 223959d709d503bab6e2b61931737e662dd293b40578ccornelius * Note: This may push the start year of the final 224059d709d503bab6e2b61931737e662dd293b40578ccornelius * rules ahead by 1 year unnecessarily. For example, 224159d709d503bab6e2b61931737e662dd293b40578ccornelius * If there are two rules, non-max rule and max rule 224259d709d503bab6e2b61931737e662dd293b40578ccornelius * starting in the same year, such as 224359d709d503bab6e2b61931737e662dd293b40578ccornelius * 224459d709d503bab6e2b61931737e662dd293b40578ccornelius * Rule Foo 2010 only .... 224559d709d503bab6e2b61931737e662dd293b40578ccornelius * Rule Foo 2010 max .... 224659d709d503bab6e2b61931737e662dd293b40578ccornelius * 224759d709d503bab6e2b61931737e662dd293b40578ccornelius * In this case, the final (max) rule actually starts 224859d709d503bab6e2b61931737e662dd293b40578ccornelius * in 2010, instead of 2010. We could make this tool 224959d709d503bab6e2b61931737e662dd293b40578ccornelius * more intelligent to detect such situation. But pushing 225059d709d503bab6e2b61931737e662dd293b40578ccornelius * final rule start year to 1 year ahead (in the worst case) 225159d709d503bab6e2b61931737e662dd293b40578ccornelius * will just populate a few extra transitions, and it still 225259d709d503bab6e2b61931737e662dd293b40578ccornelius * works fine. So for now, we're not trying to put additional 225359d709d503bab6e2b61931737e662dd293b40578ccornelius * logic to optimize the case. 225459d709d503bab6e2b61931737e662dd293b40578ccornelius */ 225559d709d503bab6e2b61931737e662dd293b40578ccornelius if (max_year < finalRuleYear) { 225659d709d503bab6e2b61931737e662dd293b40578ccornelius max_year = finalRuleYear; 225759d709d503bab6e2b61931737e662dd293b40578ccornelius } 2258b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2259b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2260b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (finalRule1 != NULL) { 226159d709d503bab6e2b61931737e662dd293b40578ccornelius if (finalRule2 == NULL) { 226259d709d503bab6e2b61931737e662dd293b40578ccornelius warning("only one max rule found (ICU)"); 2263b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru finalRuleYear = finalRuleIndex = -1; 226459d709d503bab6e2b61931737e662dd293b40578ccornelius finalRule1 = NULL; 2265b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 226659d709d503bab6e2b61931737e662dd293b40578ccornelius if (finalRule1->r_stdoff == finalRule2->r_stdoff) { 226759d709d503bab6e2b61931737e662dd293b40578ccornelius /* America/Resolute in 2009a uses a pair of rules 226859d709d503bab6e2b61931737e662dd293b40578ccornelius * which does not change the offset. ICU ignores 226959d709d503bab6e2b61931737e662dd293b40578ccornelius * such rules without actual time transitions. */ 227059d709d503bab6e2b61931737e662dd293b40578ccornelius finalRuleYear = finalRuleIndex = -1; 227159d709d503bab6e2b61931737e662dd293b40578ccornelius finalRule1 = finalRule2 = NULL; 227259d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 227359d709d503bab6e2b61931737e662dd293b40578ccornelius /* Swap if necessary so finalRule1 occurs before 227459d709d503bab6e2b61931737e662dd293b40578ccornelius * finalRule2 */ 227559d709d503bab6e2b61931737e662dd293b40578ccornelius if (finalRule1->r_month > finalRule2->r_month) { 227659d709d503bab6e2b61931737e662dd293b40578ccornelius const struct rule* t = finalRule1; 227759d709d503bab6e2b61931737e662dd293b40578ccornelius finalRule1 = finalRule2; 227859d709d503bab6e2b61931737e662dd293b40578ccornelius finalRule2 = t; 227959d709d503bab6e2b61931737e662dd293b40578ccornelius } 228059d709d503bab6e2b61931737e662dd293b40578ccornelius /* Add final rule to our list */ 228159d709d503bab6e2b61931737e662dd293b40578ccornelius finalRuleIndex = add_icu_final_rules(finalRule1, finalRule2); 2282b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2283b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2284b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2285b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (zp->z_nrules == 0) { 2289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stdoff = zp->z_stdoff; 2290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doabbr(startbuf, zp->z_format, 2291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (char *) NULL, stdoff != 0, FALSE); 2292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = addtype(oadd(zp->z_gmtoff, stdoff), 2293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2294b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru zp->z_gmtoff, stdoff, 2295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startbuf, stdoff != 0, startttisstd, 2297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startttisgmt); 2298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (usestart) { 2299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addtt(starttime, type); 2300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru usestart = FALSE; 2301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (stdoff != 0) 2302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addtt(min_time, type); 2303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else for (year = min_year; year <= max_year; ++year) { 2304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (useuntil && year > zp->z_untilrule.r_hiyear) 2305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Mark which rules to do in the current year. 2308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** For those to do, calculate rpytime(rp, year); 2309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = 0; j < zp->z_nrules; ++j) { 2311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp = &zp->z_rules[j]; 2312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eats(zp->z_filename, zp->z_linenum, 2313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_filename, rp->r_linenum); 2314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todo = year >= rp->r_loyear && 2315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year <= rp->r_hiyear && 2316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru yearistype(year, rp->r_yrtype); 2317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_todo) 2318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_temp = rpytime(rp, year); 2319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for ( ; ; ) { 2321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int k; 2322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register zic_t jtime, ktime; 2323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register long offset; 2324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru INITIALIZE(ktime); 2326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (useuntil) { 2327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Turn untiltime into UTC 2329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** assuming the current gmtoff and 2330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** stdoff values. 2331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru untiltime = zp->z_untiltime; 2333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!zp->z_untilrule.r_todisgmt) 2334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru untiltime = tadd(untiltime, 2335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru -gmtoff); 2336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!zp->z_untilrule.r_todisstd) 2337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru untiltime = tadd(untiltime, 2338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru -stdoff); 2339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Find the rule (of those to do, if any) 2342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** that takes effect earliest in the year. 2343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru k = -1; 2345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = 0; j < zp->z_nrules; ++j) { 2346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp = &zp->z_rules[j]; 2347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!rp->r_todo) 2348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 2349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eats(zp->z_filename, zp->z_linenum, 2350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_filename, rp->r_linenum); 2351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = rp->r_todisgmt ? 0 : gmtoff; 2352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!rp->r_todisstd) 2353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = oadd(offset, stdoff); 2354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jtime = rp->r_temp; 2355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (jtime == min_time || 2356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jtime == max_time) 2357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 2358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jtime = tadd(jtime, -offset); 2359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (k < 0 || jtime < ktime) { 2360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru k = j; 2361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ktime = jtime; 2362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (k < 0) 2365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* go on to next year */ 2366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp = &zp->z_rules[k]; 2367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todo = FALSE; 2368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (useuntil && ktime >= untiltime) 2369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stdoff = rp->r_stdoff; 2371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (usestart && ktime == starttime) 2372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru usestart = FALSE; 2373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (usestart) { 2374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ktime < starttime) { 2375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startoff = oadd(zp->z_gmtoff, 2376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stdoff); 2377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doabbr(startbuf, zp->z_format, 2378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_abbrvar, 2379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_stdoff != 0, 2380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE); 2381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 2382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*startbuf == '\0' && 2384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startoff == oadd(zp->z_gmtoff, 2385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stdoff)) { 2386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doabbr(startbuf, 2387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp->z_format, 2388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_abbrvar, 2389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_stdoff != 2390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0, 2391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE); 2392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (year >= finalRuleYear && rp == finalRule1) { 2396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* We want to shift final year 1 year after 2397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * the actual final rule takes effect (year + 1), 2398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * because the previous type is valid until the first 2399b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * transition defined by the final rule. Otherwise 2400b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * we may see unexpected offset shift at the 2401b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * begining of the year when the final rule takes 240259d709d503bab6e2b61931737e662dd293b40578ccornelius * effect. 240359d709d503bab6e2b61931737e662dd293b40578ccornelius * 240459d709d503bab6e2b61931737e662dd293b40578ccornelius * Note: This may results some 64bit second transitions 240559d709d503bab6e2b61931737e662dd293b40578ccornelius * at the very end (year 2038). ICU 4.2 or older releases 240659d709d503bab6e2b61931737e662dd293b40578ccornelius * cannot handle 64bit second transitions and they are 240759d709d503bab6e2b61931737e662dd293b40578ccornelius * dropped from zoneinfo.txt. */ 2408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru emit_icu_zone(icuFile, 2409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru zpfirst->z_name, zp->z_gmtoff, 241050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho rp, finalRuleIndex, year + 1); 2411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* only emit this for the first year */ 2412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru finalRule1 = NULL; 2413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eats(zp->z_filename, zp->z_linenum, 2416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_filename, rp->r_linenum); 2417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doabbr(ab, zp->z_format, rp->r_abbrvar, 2418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_stdoff != 0, FALSE); 2419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = oadd(zp->z_gmtoff, rp->r_stdoff); 2420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = addtype(offset, zp->z_gmtoff, rp->r_stdoff, 2422b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ab, rp->r_stdoff != 0, 2423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisstd, rp->r_todisgmt); 2424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 2425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = addtype(offset, ab, rp->r_stdoff != 0, 2426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rp->r_todisstd, rp->r_todisgmt); 2427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addtt(ktime, type); 2429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (usestart) { 2432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*startbuf == '\0' && 2433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru zp->z_format != NULL && 2434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strchr(zp->z_format, '%') == NULL && 2435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strchr(zp->z_format, '/') == NULL) 2436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcpy(startbuf, zp->z_format); 2437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eat(zp->z_filename, zp->z_linenum); 2438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*startbuf == '\0') 2439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruerror(_("can't determine time zone abbreviation to use just after until time")); 2440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else addtt(starttime, 2441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addtype(startoff, 2443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru zp->z_gmtoff, startoff - zp->z_gmtoff, 2444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru startbuf, 2445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startoff != zp->z_gmtoff, 2446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startttisstd, 2447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startttisgmt)); 2448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 2449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addtype(startoff, startbuf, 2450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startoff != zp->z_gmtoff, 2451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startttisstd, 2452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startttisgmt)); 2453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Now we may get to set starttime for the next zone line. 2457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (useuntil) { 2459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startttisstd = zp->z_untilrule.r_todisstd; 2460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startttisgmt = zp->z_untilrule.r_todisgmt; 2461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru starttime = zp->z_untiltime; 2462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!startttisstd) 2463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru starttime = tadd(starttime, -stdoff); 2464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!startttisgmt) 2465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru starttime = tadd(starttime, -gmtoff); 2466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru writezone(zpfirst->z_name, envvar); 2469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(startbuf); 2470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(ab); 2471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(envvar); 2472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 2475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruaddtt(starttime, type) 2476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst zic_t starttime; 2477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint type; 2478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (starttime <= min_time || 2480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (timecnt == 1 && attypes[0].at < min_time)) { 2481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gmtoffs[0] = gmtoffs[type]; 2482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rawoffs[0] = rawoffs[type]; 2484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dstoffs[0] = dstoffs[type]; 2485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isdsts[0] = isdsts[type]; 2487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ttisstds[0] = ttisstds[type]; 2488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ttisgmts[0] = ttisgmts[type]; 2489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (abbrinds[type] != 0) 2490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcpy(chars, &chars[abbrinds[type]]); 2491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru abbrinds[0] = 0; 2492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charcnt = strlen(chars) + 1; 2493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru typecnt = 1; 2494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru timecnt = 0; 2495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = 0; 2496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (timecnt >= TZ_MAX_TIMES) { 2498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("too many transitions?!")); 2499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru attypes[timecnt].at = starttime; 2502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru attypes[timecnt].type = type; 2503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++timecnt; 2504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 2507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruaddtype(gmtoff, rawoff, dstoff, abbr, isdst, ttisstd, ttisgmt) 2509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long gmtoff; 2510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long rawoff; 2511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long dstoff; 2512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 2513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruaddtype(gmtoff, abbr, isdst, ttisstd, ttisgmt) 2514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long gmtoff; 2515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const abbr; 2517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int isdst; 2518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int ttisstd; 2519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int ttisgmt; 2520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i, j; 2522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isdst != TRUE && isdst != FALSE) { 2524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("internal error - addtype called with bad isdst")); 2525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ttisstd != TRUE && ttisstd != FALSE) { 2528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("internal error - addtype called with bad ttisstd")); 2529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ttisgmt != TRUE && ttisgmt != FALSE) { 2532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("internal error - addtype called with bad ttisgmt")); 2533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isdst != (dstoff != 0)) { 2537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("internal error - addtype called with bad isdst/dstoff")); 2538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) exit(EXIT_FAILURE); 2539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2540b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (gmtoff != (rawoff + dstoff)) { 2541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("internal error - addtype called with bad gmt/raw/dstoff")); 2542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) exit(EXIT_FAILURE); 2543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** See if there's already an entry for this zone type. 2547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** If so, just return its index. 2548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < typecnt; ++i) { 2550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (gmtoff == gmtoffs[i] && isdst == isdsts[i] && 2551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2552b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru rawoff == rawoffs[i] && dstoff == dstoffs[i] && 2553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcmp(abbr, &chars[abbrinds[i]]) == 0 && 2555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ttisstd == ttisstds[i] && 2556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ttisgmt == ttisgmts[i]) 2557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return i; 2558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** There isn't one; add a new one, unless there are already too 2561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** many. 2562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (typecnt >= TZ_MAX_TYPES) { 2564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("too many local time types")); 2565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2567b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) { 2568b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error(_("UTC offset out of range")); 2569b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru exit(EXIT_FAILURE); 2570b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gmtoffs[i] = gmtoff; 2572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ICU 2573b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru rawoffs[i] = rawoff; 2574b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dstoffs[i] = dstoff; 2575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isdsts[i] = isdst; 2577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ttisstds[i] = ttisstd; 2578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ttisgmts[i] = ttisgmt; 2579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = 0; j < charcnt; ++j) 2581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(&chars[j], abbr) == 0) 2582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (j == charcnt) 2584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newabbr(abbr); 2585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru abbrinds[i] = j; 2586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++typecnt; 2587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return i; 2588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 2591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruleapadd(t, positive, rolling, count) 2592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst zic_t t; 2593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int positive; 2594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int rolling; 2595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint count; 2596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i, j; 2598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) { 2600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("too many leap seconds")); 2601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < leapcnt; ++i) 2604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (t <= trans[i]) { 2605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (t == trans[i]) { 2606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("repeated leap second moment")); 2607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 2612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = leapcnt; j > i; --j) { 2613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru trans[j] = trans[j - 1]; 2614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru corr[j] = corr[j - 1]; 2615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru roll[j] = roll[j - 1]; 2616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru trans[i] = t; 2618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru corr[i] = positive ? 1L : eitol(-count); 2619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru roll[i] = rolling; 2620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++leapcnt; 2621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while (positive && --count != 0); 2622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 2625b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruadjleap(void) 2626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i; 2628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register long last = 0; 2629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** propagate leap seconds forward 2632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < leapcnt; ++i) { 2634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru trans[i] = tadd(trans[i], last); 2635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru last = corr[i] += last; 2636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 2640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruyearistype(year, type) 2641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int year; 2642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const type; 2643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static char * buf; 2645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int result; 2646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (type == NULL || *type == '\0') 2648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 2649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type))); 2650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) sprintf(buf, "%s %d %s", yitcommand, year, type); 2651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = system(buf); 2652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (WIFEXITED(result)) switch (WEXITSTATUS(result)) { 2653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: 2654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 2655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: 2656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 2657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("Wild result from command execution")); 2659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, _("%s: command was '%s', result was %d\n"), 2660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, buf, result); 2661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for ( ; ; ) 2662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 2666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulowerit(a) 2667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint a; 2668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru a = (unsigned char) a; 2670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (isascii(a) && isupper(a)) ? tolower(a) : a; 2671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 2674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruciequal(ap, bp) /* case-insensitive equality */ 2675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister const char * ap; 2676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister const char * bp; 2677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (lowerit(*ap) == lowerit(*bp++)) 2679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*ap++ == '\0') 2680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 2681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 2682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 2685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruitsabbr(abbr, word) 2686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister const char * abbr; 2687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister const char * word; 2688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lowerit(*abbr) != lowerit(*word)) 2690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 2691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++word; 2692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (*++abbr != '\0') 2693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 2694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*word == '\0') 2695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 2696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while (lowerit(*word++) != lowerit(*abbr)); 2697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 2698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const struct lookup * 2701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubyword(word, table) 2702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister const char * const word; 2703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister const struct lookup * const table; 2704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const struct lookup * foundlp; 2706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const struct lookup * lp; 2707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (word == NULL || table == NULL) 2709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Look for exact match. 2712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (lp = table; lp->l_word != NULL; ++lp) 2714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ciequal(word, lp->l_word)) 2715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return lp; 2716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Look for inexact match. 2718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru foundlp = NULL; 2720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (lp = table; lp->l_word != NULL; ++lp) 2721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (itsabbr(word, lp->l_word)) { 2722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (foundlp == NULL) 2723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru foundlp = lp; 2724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else return NULL; /* multiple inexact matches */ 2725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return foundlp; 2727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char ** 2730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querugetfields(cp) 2731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister char * cp; 2732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * dp; 2734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char ** array; 2735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int nsubs; 2736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cp == NULL) 2738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru array = (char **) (void *) 2740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru emalloc((int) ((strlen(cp) + 1) * sizeof *array)); 2741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nsubs = 0; 2742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for ( ; ; ) { 2743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (isascii((unsigned char) *cp) && 2744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isspace((unsigned char) *cp)) 2745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++cp; 2746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*cp == '\0' || *cp == '#') 2747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru array[nsubs++] = dp = cp; 2749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 2750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((*dp = *cp++) != '"') 2751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++dp; 2752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else while ((*dp = *cp++) != '"') 2753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*dp != '\0') 2754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++dp; 2755b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else { 2756b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error(_( 2757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "Odd number of quotation marks" 2758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru )); 2759b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru exit(1); 2760b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while (*cp != '\0' && *cp != '#' && 2762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (!isascii(*cp) || !isspace((unsigned char) *cp))); 2763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isascii(*cp) && isspace((unsigned char) *cp)) 2764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++cp; 2765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *dp = '\0'; 2766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru array[nsubs] = NULL; 2768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return array; 2769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic long 2772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruoadd(t1, t2) 2773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long t1; 2774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long t2; 2775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register long t; 2777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t = t1 + t2; 2779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { 2780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("time overflow")); 2781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return t; 2784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic zic_t 2787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutadd(t1, t2) 2788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst zic_t t1; 2789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst long t2; 2790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register zic_t t; 2792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (t1 == max_time && t2 > 0) 2794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return max_time; 2795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (t1 == min_time && t2 < 0) 2796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return min_time; 2797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t = t1 + t2; 2798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { 2799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("time overflow")); 2800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return t; 2803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** Given a rule, and a year, compute the date - in seconds since January 1, 2807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** 1970, 00:00 LOCAL time - in that year that the rule refers to. 2808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic zic_t 2811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querurpytime(rp, wantedy) 2812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister const struct rule * const rp; 2813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruregister const int wantedy; 2814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int y, m, i; 2816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register long dayoff; /* with a nod to Margaret O. */ 2817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register zic_t t; 2818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (wantedy == INT_MIN) 2820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return min_time; 2821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (wantedy == INT_MAX) 2822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return max_time; 2823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = 0; 2824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru m = TM_JANUARY; 2825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru y = EPOCH_YEAR; 2826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (wantedy != y) { 2827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (wantedy > y) { 2828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = len_years[isleap(y)]; 2829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++y; 2830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --y; 2832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = -len_years[isleap(y)]; 2833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = oadd(dayoff, eitol(i)); 2835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (m != rp->r_month) { 2837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = len_months[isleap(y)][m]; 2838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = oadd(dayoff, eitol(i)); 2839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++m; 2840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = rp->r_dayofmonth; 2842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (m == TM_FEBRUARY && i == 29 && !isleap(y)) { 2843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_dycode == DC_DOWLEQ) 2844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --i; 2845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 2846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("use of 2/29 in non leap-year")); 2847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --i; 2851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = oadd(dayoff, eitol(i)); 2852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) { 2853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register long wday; 2854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LDAYSPERWEEK ((long) DAYSPERWEEK) 2856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wday = eitol(EPOCH_WDAY); 2857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Don't trust mod of negative numbers. 2859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dayoff >= 0) 2861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wday = (wday + dayoff) % LDAYSPERWEEK; 2862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 2863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wday -= ((-dayoff) % LDAYSPERWEEK); 2864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (wday < 0) 2865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wday += LDAYSPERWEEK; 2866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (wday != eitol(rp->r_wday)) 2868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rp->r_dycode == DC_DOWGEQ) { 2869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = oadd(dayoff, (long) 1); 2870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (++wday >= LDAYSPERWEEK) 2871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wday = 0; 2872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 2873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayoff = oadd(dayoff, (long) -1); 2875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (--wday < 0) 2876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wday = LDAYSPERWEEK - 1; 2877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --i; 2878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i < 0 || i >= len_months[isleap(y)][m]) { 2880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (noise) 2881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(_("rule goes past start/end of month--\ 2882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwill not work with pre-2004 versions of zic")); 2883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dayoff < min_time / SECSPERDAY) 2886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return min_time; 2887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dayoff > max_time / SECSPERDAY) 2888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return max_time; 2889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t = (zic_t) dayoff * SECSPERDAY; 2890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return tadd(t, rp->r_tod); 2891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 2894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querunewabbr(string) 2895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * const string; 2896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register int i; 2898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (strcmp(string, GRANDPARENTED) != 0) { 2900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register const char * cp; 2901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * wp; 2902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics 2905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** optionally followed by a + or - and a number from 1 to 14. 2906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = string; 2908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wp = NULL; 2909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (isascii((unsigned char) *cp) && 2910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isalpha((unsigned char) *cp)) 2911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++cp; 2912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cp - string == 0) 2913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwp = _("time zone abbreviation lacks alphabetic at start"); 2914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (noise && cp - string > 3) 2915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwp = _("time zone abbreviation has more than 3 alphabetics"); 2916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN) 2917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwp = _("time zone abbreviation has too many alphabetics"); 2918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (wp == NULL && (*cp == '+' || *cp == '-')) { 2919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++cp; 2920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isascii((unsigned char) *cp) && 2921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isdigit((unsigned char) *cp)) 2922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*cp++ == '1' && 2923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *cp >= '0' && *cp <= '4') 2924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++cp; 2925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*cp != '\0') 2927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwp = _("time zone abbreviation differs from POSIX standard"); 2928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (wp != NULL) { 2929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wp = ecpyalloc(wp); 2930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wp = ecatalloc(wp, " ("); 2931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wp = ecatalloc(wp, string); 2932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wp = ecatalloc(wp, ")"); 2933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(wp); 2934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(wp); 2935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = strlen(string) + 1; 2938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (charcnt + i > TZ_MAX_CHARS) { 2939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(_("too many, or too long, time zone abbreviations")); 2940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 2941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) strcpy(&chars[charcnt], string); 2943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charcnt += eitol(i); 2944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int 2947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querumkdirs(argname) 2948b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruchar * argname; 2949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * name; 2951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru register char * cp; 2952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (argname == NULL || *argname == '\0') 2954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = name = ecpyalloc(argname); 2956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while ((cp = strchr(cp + 1, '/')) != 0) { 2957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *cp = '\0'; 2958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef unix 2959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** DOS drive specifier? 2961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isalpha((unsigned char) name[0]) && 2963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[1] == ':' && name[2] == '\0') { 2964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *cp = '/'; 2965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 2966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* !defined unix */ 2968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!itsdir(name)) { 2969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** It doesn't seem to exist, so we try to create it. 2971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** Creation may fail because of the directory being 2972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** created by some other multiprocessor, so we get 2973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ** to do extra checking. 2974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (mkdir(name, MKDIR_UMASK) != 0) { 2976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *e = strerror(errno); 2977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (errno != EEXIST || !itsdir(name)) { 2979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 2980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_("%s: Can't create directory %s: %s\n"), 2981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, name, e); 2982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(name); 2983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *cp = '/'; 2988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ifree(name); 2990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic long 2994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querueitol(i) 2995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int i; 2996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru long l; 2998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru l = i; 3000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((i < 0 && l >= 0) || (i == 0 && l != 0) || (i > 0 && l <= 0)) { 3001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (void) fprintf(stderr, 3002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru _("%s: %d did not sign extend correctly\n"), 3003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru progname, i); 3004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(EXIT_FAILURE); 3005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 3006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return l; 3007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 3008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 3010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru** UNIX was a registered trademark of The Open Group in 2003. 3011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 3012