PostgreSQL Source Code  git master
zic.c File Reference
#include "postgres_fe.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include "pg_getopt.h"
#include "private.h"
#include "tzfile.h"
Include dependency graph for zic.c:

Go to the source code of this file.

Data Structures

struct  rule
 
struct  zone
 
struct  link
 
struct  lookup
 
struct  attype
 

Macros

#define ZIC_VERSION_PRE_2013   '2'
 
#define ZIC_VERSION   '3'
 
#define ZIC_MIN   PG_INT64_MIN
 
#define ZIC_MAX   PG_INT64_MAX
 
#define ZIC_MAX_ABBR_LEN_WO_WARN   6
 
#define MKDIR_UMASK   0755
 
#define linkat(fromdir, from, todir, to, flag)   (itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to))
 
#define DC_DOM   0 /* 1..31 */ /* unused */
 
#define DC_DOWGEQ   1 /* 1..31 */ /* 0..6 (Sun..Sat) */
 
#define DC_DOWLEQ   2 /* 1..31 */ /* 0..6 (Sun..Sat) */
 
#define LC_RULE   0
 
#define LC_ZONE   1
 
#define LC_LINK   2
 
#define LC_LEAP   3
 
#define ZF_NAME   1
 
#define ZF_GMTOFF   2
 
#define ZF_RULE   3
 
#define ZF_FORMAT   4
 
#define ZF_TILYEAR   5
 
#define ZF_TILMONTH   6
 
#define ZF_TILDAY   7
 
#define ZF_TILTIME   8
 
#define ZONE_MINFIELDS   5
 
#define ZONE_MAXFIELDS   9
 
#define ZFC_GMTOFF   0
 
#define ZFC_RULE   1
 
#define ZFC_FORMAT   2
 
#define ZFC_TILYEAR   3
 
#define ZFC_TILMONTH   4
 
#define ZFC_TILDAY   5
 
#define ZFC_TILTIME   6
 
#define ZONEC_MINFIELDS   3
 
#define ZONEC_MAXFIELDS   7
 
#define RF_NAME   1
 
#define RF_LOYEAR   2
 
#define RF_HIYEAR   3
 
#define RF_COMMAND   4
 
#define RF_MONTH   5
 
#define RF_DAY   6
 
#define RF_TOD   7
 
#define RF_STDOFF   8
 
#define RF_ABBRVAR   9
 
#define RULE_FIELDS   10
 
#define LF_FROM   1
 
#define LF_TO   2
 
#define LINK_FIELDS   3
 
#define LP_YEAR   1
 
#define LP_MONTH   2
 
#define LP_DAY   3
 
#define LP_TIME   4
 
#define LP_CORR   5
 
#define LP_ROLL   6
 
#define LEAP_FIELDS   7
 
#define YR_MINIMUM   0
 
#define YR_MAXIMUM   1
 
#define YR_ONLY   2
 
#define TIME_T_BITS_IN_FILE   64
 
#define BIG_BANG   (- (((zic_t) 1) << 59))
 
#define DO(field)   fwrite(tzh.field, sizeof tzh.field, 1, fp)
 
#define LDAYSPERWEEK   ((zic_t) DAYSPERWEEK)
 

Typedefs

typedef int64 zic_t
 
typedef int lineno_t
 

Enumerations

enum  { PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1 }
 
enum  { WORK_AROUND_QTBUG_53071 = true }
 
enum  { WORK_AROUND_GNOME_BUG_730332 = true }
 
enum  { YEAR_BY_YEAR_ZONE = 1 }
 

Functions

int link (const char *fromname, const char *toname)
 
static void memory_exhausted (const char *msg) pg_attribute_noreturn()
 
static void verror (const char *string, va_list args) pg_attribute_printf(1
 
static void static void error (const char *string,...) pg_attribute_printf(1
 
static void static void static void warning (const char *string,...) pg_attribute_printf(1
 
static void static void static void static void usage (FILE *stream, int status) pg_attribute_noreturn()
 
static void addtt (zic_t starttime, int type)
 
static int addtype (zic_t, char const *, bool, bool, bool)
 
static void leapadd (zic_t, bool, int, int)
 
static void adjleap (void)
 
static void associate (void)
 
static void dolink (const char *, const char *, bool)
 
static char ** getfields (char *buf)
 
static zic_t gethms (const char *string, const char *errstring, bool)
 
static zic_t getstdoff (char *, bool *)
 
static void infile (const char *filename)
 
static void inleap (char **fields, int nfields)
 
static void inlink (char **fields, int nfields)
 
static void inrule (char **fields, int nfields)
 
static bool inzcont (char **fields, int nfields)
 
static bool inzone (char **fields, int nfields)
 
static bool inzsub (char **, int, bool)
 
static bool itsdir (char const *)
 
static bool itssymlink (char const *)
 
static bool is_alpha (char a)
 
static char lowerit (char)
 
static void mkdirs (char const *, bool)
 
static void newabbr (const char *abbr)
 
static zic_t oadd (zic_t t1, zic_t t2)
 
static void outzone (const struct zone *zp, ptrdiff_t ntzones)
 
static zic_t rpytime (const struct rule *rp, zic_t wantedy)
 
static void rulesub (struct rule *rp, const char *loyearp, const char *hiyearp, const char *typep, const char *monthp, const char *dayp, const char *timep)
 
static zic_t tadd (zic_t t1, zic_t t2)
 
static bool yearistype (zic_t year, const char *type)
 
static struct lookup const * byword (const char *string, const struct lookup *lp)
 
static size_t size_product (size_t nitems, size_t itemsize)
 
static void * memcheck (void *ptr)
 
static void * emalloc (size_t size)
 
static void * erealloc (void *ptr, size_t size)
 
static char * ecpyalloc (char const *str)
 
static void * growalloc (void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
 
static void eats (char const *name, lineno_t num, char const *rname, lineno_t rnum)
 
static void eat (char const *name, lineno_t num)
 
static void close_file (FILE *stream, char const *dir, char const *name)
 
static void change_directory (char const *dir)
 
int main (int argc, char **argv)
 
static bool componentcheck (char const *name, char const *component, char const *component_end)
 
static bool namecheck (const char *name)
 
static int hardlinkerr (char const *from, char const *to)
 
static int rcomp (const void *cp1, const void *cp2)
 
static void convert (const int32 val, char *const buf)
 
static void convert64 (const zic_t val, char *const buf)
 
static void puttzcode (const int32 val, FILE *const fp)
 
static void puttzcode64 (const zic_t val, FILE *const fp)
 
static int atcomp (const void *avp, const void *bvp)
 
static bool is32 (const zic_t x)
 
static void writezone (const char *const name, const char *const string, char version)
 
static char const * abbroffset (char *buf, zic_t offset)
 
static size_t doabbr (char *abbr, struct zone const *zp, char const *letters, bool isdst, zic_t stdoff, bool doquotes)
 
static void updateminmax (const zic_t x)
 
static int stringoffset (char *result, zic_t offset)
 
static int stringrule (char *result, const struct rule *const rp, const zic_t dstoff, const zic_t gmtoff)
 
static int rule_cmp (struct rule const *a, struct rule const *b)
 
static int stringzone (char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
 
static char * shellquote (char *b, char const *s)
 
static bool is_space (char a)
 
static bool ciequal (const char *ap, const char *bp)
 
static bool itsabbr (const char *abbr, const char *word)
 
static bool ciprefix (char const *abbr, char const *word)
 
static void time_overflow (void)
 

Variables

static ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t))
 
static int charcnt
 
static bool errors
 
static bool warnings
 
static const char * filename
 
static int leapcnt
 
static bool leapseen
 
static zic_t leapminyear
 
static zic_t leapmaxyear
 
static lineno_t linenum
 
static int max_abbrvar_len = PERCENT_Z_LEN_BOUND
 
static int max_format_len
 
static zic_t max_year
 
static zic_t min_year
 
static bool noise
 
static bool print_abbrevs
 
static zic_t print_cutoff
 
static const char * rfilename
 
static lineno_t rlinenum
 
static const char * progname
 
static ptrdiff_t timecnt
 
static ptrdiff_t timecnt_alloc
 
static int typecnt
 
static struct rulerules
 
static ptrdiff_t nrules
 
static ptrdiff_t nrules_alloc
 
static struct zonezones
 
static ptrdiff_t nzones
 
static ptrdiff_t nzones_alloc
 
static struct linklinks
 
static ptrdiff_t nlinks
 
static ptrdiff_t nlinks_alloc
 
static struct lookup const zi_line_codes []
 
static struct lookup const leap_line_codes []
 
static struct lookup const mon_names []
 
static struct lookup const wday_names []
 
static struct lookup const lasts []
 
static struct lookup const begin_years []
 
static struct lookup const end_years []
 
static struct lookup const leap_types []
 
static const int len_months [2][MONSPERYEAR]
 
static const int len_years [2]
 
static struct attypeattypes
 
static zic_t gmtoffs [TZ_MAX_TYPES]
 
static char isdsts [TZ_MAX_TYPES]
 
static unsigned char abbrinds [TZ_MAX_TYPES]
 
static bool ttisstds [TZ_MAX_TYPES]
 
static bool ttisgmts [TZ_MAX_TYPES]
 
static char chars [TZ_MAX_CHARS]
 
static zic_t trans [TZ_MAX_LEAPS]
 
static zic_t corr [TZ_MAX_LEAPS]
 
static char roll [TZ_MAX_LEAPS]
 
static const char * psxrules
 
static const char * lcltime
 
static const char * directory
 
static const char * leapsec
 
static const char * tzdefault
 
static const char * yitcommand
 
static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE)
 
static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE)
 
static const zic_t early_time
 

Macro Definition Documentation

◆ BIG_BANG

#define BIG_BANG   (- (((zic_t) 1) << 59))

Definition at line 1024 of file zic.c.

◆ DC_DOM

#define DC_DOM   0 /* 1..31 */ /* unused */

Definition at line 94 of file zic.c.

Referenced by outzone(), rulesub(), stringrule(), and stringzone().

◆ DC_DOWGEQ

#define DC_DOWGEQ   1 /* 1..31 */ /* 0..6 (Sun..Sat) */

Definition at line 95 of file zic.c.

Referenced by rpytime(), rulesub(), and stringrule().

◆ DC_DOWLEQ

#define DC_DOWLEQ   2 /* 1..31 */ /* 0..6 (Sun..Sat) */

Definition at line 96 of file zic.c.

Referenced by rpytime(), rulesub(), and stringrule().

◆ DO

#define DO (   field)    fwrite(tzh.field, sizeof tzh.field, 1, fp)

Referenced by writezone().

◆ LC_LEAP

#define LC_LEAP   3

Definition at line 203 of file zic.c.

Referenced by infile().

◆ LC_LINK

#define LC_LINK   2

Definition at line 202 of file zic.c.

Referenced by infile().

◆ LC_RULE

#define LC_RULE   0

Definition at line 200 of file zic.c.

Referenced by infile().

◆ LC_ZONE

#define LC_ZONE   1

Definition at line 201 of file zic.c.

Referenced by infile().

◆ LDAYSPERWEEK

#define LDAYSPERWEEK   ((zic_t) DAYSPERWEEK)

Referenced by rpytime().

◆ LEAP_FIELDS

#define LEAP_FIELDS   7

Definition at line 267 of file zic.c.

Referenced by inleap().

◆ LF_FROM

#define LF_FROM   1

Definition at line 253 of file zic.c.

Referenced by inlink().

◆ LF_TO

#define LF_TO   2

Definition at line 254 of file zic.c.

Referenced by inlink().

◆ LINK_FIELDS

#define LINK_FIELDS   3

Definition at line 255 of file zic.c.

Referenced by inlink().

◆ linkat

#define linkat (   fromdir,
  from,
  todir,
  to,
  flag 
)    (itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to))

Definition at line 39 of file zic.c.

Referenced by hardlinkerr().

◆ LP_CORR

#define LP_CORR   5

Definition at line 265 of file zic.c.

Referenced by inleap().

◆ LP_DAY

#define LP_DAY   3

Definition at line 263 of file zic.c.

Referenced by inleap().

◆ LP_MONTH

#define LP_MONTH   2

Definition at line 262 of file zic.c.

Referenced by inleap().

◆ LP_ROLL

#define LP_ROLL   6

Definition at line 266 of file zic.c.

Referenced by inleap().

◆ LP_TIME

#define LP_TIME   4

Definition at line 264 of file zic.c.

Referenced by inleap().

◆ LP_YEAR

#define LP_YEAR   1

Definition at line 261 of file zic.c.

Referenced by inleap().

◆ MKDIR_UMASK

#define MKDIR_UMASK   0755

Definition at line 35 of file zic.c.

Referenced by mkdirs().

◆ RF_ABBRVAR

#define RF_ABBRVAR   9

Definition at line 246 of file zic.c.

Referenced by inrule().

◆ RF_COMMAND

#define RF_COMMAND   4

Definition at line 241 of file zic.c.

Referenced by inrule().

◆ RF_DAY

#define RF_DAY   6

Definition at line 243 of file zic.c.

Referenced by inrule().

◆ RF_HIYEAR

#define RF_HIYEAR   3

Definition at line 240 of file zic.c.

Referenced by inrule().

◆ RF_LOYEAR

#define RF_LOYEAR   2

Definition at line 239 of file zic.c.

Referenced by inrule().

◆ RF_MONTH

#define RF_MONTH   5

Definition at line 242 of file zic.c.

Referenced by inrule().

◆ RF_NAME

#define RF_NAME   1

Definition at line 238 of file zic.c.

Referenced by inrule().

◆ RF_STDOFF

#define RF_STDOFF   8

Definition at line 245 of file zic.c.

Referenced by inrule().

◆ RF_TOD

#define RF_TOD   7

Definition at line 244 of file zic.c.

Referenced by inrule().

◆ RULE_FIELDS

#define RULE_FIELDS   10

Definition at line 247 of file zic.c.

Referenced by inrule().

◆ TIME_T_BITS_IN_FILE

#define TIME_T_BITS_IN_FILE   64

Definition at line 996 of file zic.c.

◆ YR_MAXIMUM

#define YR_MAXIMUM   1

Definition at line 274 of file zic.c.

Referenced by rulesub().

◆ YR_MINIMUM

#define YR_MINIMUM   0

Definition at line 273 of file zic.c.

Referenced by rulesub().

◆ YR_ONLY

#define YR_ONLY   2

Definition at line 275 of file zic.c.

Referenced by rulesub().

◆ ZF_FORMAT

#define ZF_FORMAT   4

Definition at line 212 of file zic.c.

Referenced by inzsub().

◆ ZF_GMTOFF

#define ZF_GMTOFF   2

Definition at line 210 of file zic.c.

Referenced by inzsub().

◆ ZF_NAME

#define ZF_NAME   1

Definition at line 209 of file zic.c.

Referenced by inzone(), and inzsub().

◆ ZF_RULE

#define ZF_RULE   3

Definition at line 211 of file zic.c.

Referenced by inzsub().

◆ ZF_TILDAY

#define ZF_TILDAY   7

Definition at line 215 of file zic.c.

Referenced by inzsub().

◆ ZF_TILMONTH

#define ZF_TILMONTH   6

Definition at line 214 of file zic.c.

Referenced by inzsub().

◆ ZF_TILTIME

#define ZF_TILTIME   8

Definition at line 216 of file zic.c.

Referenced by inzsub().

◆ ZF_TILYEAR

#define ZF_TILYEAR   5

Definition at line 213 of file zic.c.

Referenced by inzsub().

◆ ZFC_FORMAT

#define ZFC_FORMAT   2

Definition at line 226 of file zic.c.

Referenced by inzsub().

◆ ZFC_GMTOFF

#define ZFC_GMTOFF   0

Definition at line 224 of file zic.c.

Referenced by inzsub().

◆ ZFC_RULE

#define ZFC_RULE   1

Definition at line 225 of file zic.c.

Referenced by inzsub().

◆ ZFC_TILDAY

#define ZFC_TILDAY   5

Definition at line 229 of file zic.c.

Referenced by inzsub().

◆ ZFC_TILMONTH

#define ZFC_TILMONTH   4

Definition at line 228 of file zic.c.

Referenced by inzsub().

◆ ZFC_TILTIME

#define ZFC_TILTIME   6

Definition at line 230 of file zic.c.

Referenced by inzsub().

◆ ZFC_TILYEAR

#define ZFC_TILYEAR   3

Definition at line 227 of file zic.c.

Referenced by inzsub().

◆ ZIC_MAX

#define ZIC_MAX   PG_INT64_MAX

Definition at line 25 of file zic.c.

Referenced by gethms(), oadd(), outzone(), rpytime(), rulesub(), and stringzone().

◆ ZIC_MAX_ABBR_LEN_WO_WARN

#define ZIC_MAX_ABBR_LEN_WO_WARN   6

Definition at line 28 of file zic.c.

Referenced by newabbr().

◆ ZIC_MIN

#define ZIC_MIN   PG_INT64_MIN

Definition at line 24 of file zic.c.

Referenced by oadd(), outzone(), rpytime(), and rulesub().

◆ ZIC_VERSION

#define ZIC_VERSION   '3'

Definition at line 21 of file zic.c.

Referenced by outzone().

◆ ZIC_VERSION_PRE_2013

#define ZIC_VERSION_PRE_2013   '2'

Definition at line 20 of file zic.c.

Referenced by outzone().

◆ ZONE_MAXFIELDS

#define ZONE_MAXFIELDS   9

Definition at line 218 of file zic.c.

Referenced by inzone().

◆ ZONE_MINFIELDS

#define ZONE_MINFIELDS   5

Definition at line 217 of file zic.c.

◆ ZONEC_MAXFIELDS

#define ZONEC_MAXFIELDS   7

Definition at line 232 of file zic.c.

Referenced by inzcont().

◆ ZONEC_MINFIELDS

#define ZONEC_MINFIELDS   3

Definition at line 231 of file zic.c.

Typedef Documentation

◆ lineno_t

Definition at line 57 of file zic.c.

◆ zic_t

typedef int64 zic_t

Definition at line 23 of file zic.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
PERCENT_Z_LEN_BOUND 

Definition at line 160 of file zic.c.

161 {
162 PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1};

◆ anonymous enum

anonymous enum
Enumerator
WORK_AROUND_QTBUG_53071 

Definition at line 169 of file zic.c.

◆ anonymous enum

anonymous enum
Enumerator
WORK_AROUND_GNOME_BUG_730332 

Definition at line 1035 of file zic.c.

◆ anonymous enum

anonymous enum
Enumerator
YEAR_BY_YEAR_ZONE 

Definition at line 2587 of file zic.c.

2588 {
2589 YEAR_BY_YEAR_ZONE = 1};

Function Documentation

◆ abbroffset()

static char const* abbroffset ( char *  buf,
zic_t  offset 
)
static

Definition at line 2362 of file zic.c.

References _, buf, error(), MINSPERHOUR, SECSPERMIN, and sign.

Referenced by doabbr().

2363 {
2364  char sign = '+';
2365  int seconds,
2366  minutes;
2367 
2368  if (offset < 0)
2369  {
2370  offset = -offset;
2371  sign = '-';
2372  }
2373 
2374  seconds = offset % SECSPERMIN;
2375  offset /= SECSPERMIN;
2376  minutes = offset % MINSPERHOUR;
2377  offset /= MINSPERHOUR;
2378  if (100 <= offset)
2379  {
2380  error(_("%%z UT offset magnitude exceeds 99:59:59"));
2381  return "%z";
2382  }
2383  else
2384  {
2385  char *p = buf;
2386 
2387  *p++ = sign;
2388  *p++ = '0' + offset / 10;
2389  *p++ = '0' + offset % 10;
2390  if (minutes | seconds)
2391  {
2392  *p++ = '0' + minutes / 10;
2393  *p++ = '0' + minutes % 10;
2394  if (seconds)
2395  {
2396  *p++ = '0' + seconds / 10;
2397  *p++ = '0' + seconds % 10;
2398  }
2399  }
2400  *p = '\0';
2401  return buf;
2402  }
2403 }
#define SECSPERMIN
Definition: private.h:90
char sign
Definition: informix.c:693
static char * buf
Definition: pg_test_fsync.c:67
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84
#define MINSPERHOUR
Definition: private.h:91

◆ addtt()

static void addtt ( zic_t  starttime,
int  type 
)
static

Definition at line 3110 of file zic.c.

References attype::at, attypes, attype::dontmerge, growalloc(), timecnt, generate_unaccent_rules::type, and attype::type.

Referenced by outzone().

3111 {
3112  if (starttime <= early_time
3113  || (timecnt == 1 && attypes[0].at < early_time))
3114  {
3115  gmtoffs[0] = gmtoffs[type];
3116  isdsts[0] = isdsts[type];
3117  ttisstds[0] = ttisstds[type];
3118  ttisgmts[0] = ttisgmts[type];
3119  if (abbrinds[type] != 0)
3120  strcpy(chars, &chars[abbrinds[type]]);
3121  abbrinds[0] = 0;
3122  charcnt = strlen(chars) + 1;
3123  typecnt = 1;
3124  timecnt = 0;
3125  type = 0;
3126  }
3128  attypes[timecnt].at = starttime;
3129  attypes[timecnt].dontmerge = false;
3130  attypes[timecnt].type = type;
3131  ++timecnt;
3132 }
static bool ttisstds[TZ_MAX_TYPES]
Definition: zic.c:392
static int typecnt
Definition: zic.c:194
static zic_t gmtoffs[TZ_MAX_TYPES]
Definition: zic.c:389
static unsigned char abbrinds[TZ_MAX_TYPES]
Definition: zic.c:391
unsigned char type
Definition: zic.c:387
static char isdsts[TZ_MAX_TYPES]
Definition: zic.c:390
static bool ttisgmts[TZ_MAX_TYPES]
Definition: zic.c:393
static const zic_t early_time
Definition: zic.c:1039
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
Definition: zic.c:445
zic_t at
Definition: zic.c:385
static ptrdiff_t timecnt_alloc
Definition: zic.c:193
static struct attype * attypes
static ptrdiff_t timecnt
Definition: zic.c:192
static int charcnt
Definition: zic.c:173
bool dontmerge
Definition: zic.c:386
static char chars[TZ_MAX_CHARS]
Definition: zic.c:394

◆ addtype()

static int addtype ( zic_t  gmtoff,
char const *  abbr,
bool  isdst,
bool  ttisstd,
bool  ttisgmt 
)
static

Definition at line 3135 of file zic.c.

References _, charcnt, error(), EXIT_FAILURE, i, newabbr(), typecnt, and TZ_MAX_TYPES.

Referenced by outzone(), and writezone().

3136 {
3137  int i,
3138  j;
3139 
3140  /*
3141  * See if there's already an entry for this zone type. If so, just return
3142  * its index.
3143  */
3144  for (i = 0; i < typecnt; ++i)
3145  {
3146  if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
3147  strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
3148  ttisstd == ttisstds[i] &&
3149  ttisgmt == ttisgmts[i])
3150  return i;
3151  }
3152 
3153  /*
3154  * There isn't one; add a new one, unless there are already too many.
3155  */
3156  if (typecnt >= TZ_MAX_TYPES)
3157  {
3158  error(_("too many local time types"));
3159  exit(EXIT_FAILURE);
3160  }
3161  if (!(-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L))
3162  {
3163  error(_("UT offset out of range"));
3164  exit(EXIT_FAILURE);
3165  }
3166  gmtoffs[i] = gmtoff;
3167  isdsts[i] = isdst;
3168  ttisstds[i] = ttisstd;
3169  ttisgmts[i] = ttisgmt;
3170 
3171  for (j = 0; j < charcnt; ++j)
3172  if (strcmp(&chars[j], abbr) == 0)
3173  break;
3174  if (j == charcnt)
3175  newabbr(abbr);
3176  abbrinds[i] = j;
3177  ++typecnt;
3178  return i;
3179 }
static bool ttisstds[TZ_MAX_TYPES]
Definition: zic.c:392
static int typecnt
Definition: zic.c:194
static zic_t gmtoffs[TZ_MAX_TYPES]
Definition: zic.c:389
static unsigned char abbrinds[TZ_MAX_TYPES]
Definition: zic.c:391
static char isdsts[TZ_MAX_TYPES]
Definition: zic.c:390
static bool ttisgmts[TZ_MAX_TYPES]
Definition: zic.c:393
static int charcnt
Definition: zic.c:173
#define TZ_MAX_TYPES
Definition: tzfile.h:96
static void newabbr(const char *abbr)
Definition: zic.c:3714
int i
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
static char chars[TZ_MAX_CHARS]
Definition: zic.c:394
#define _(x)
Definition: elog.c:84

◆ adjleap()

static void adjleap ( void  )
static

Definition at line 3211 of file zic.c.

References _, error(), EXIT_FAILURE, i, leapcnt, SECSPERDAY, and tadd().

Referenced by main().

3212 {
3213  int i;
3214  zic_t last = 0;
3215  zic_t prevtrans = 0;
3216 
3217  /*
3218  * propagate leap seconds forward
3219  */
3220  for (i = 0; i < leapcnt; ++i)
3221  {
3222  if (trans[i] - prevtrans < 28 * SECSPERDAY)
3223  {
3224  error(_("Leap seconds too close together"));
3225  exit(EXIT_FAILURE);
3226  }
3227  prevtrans = trans[i];
3228  trans[i] = tadd(trans[i], last);
3229  last = corr[i] += last;
3230  }
3231 }
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:396
#define SECSPERDAY
Definition: private.h:97
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3587
static int leapcnt
Definition: zic.c:177
int64 zic_t
Definition: zic.c:23
static zic_t trans[TZ_MAX_LEAPS]
Definition: zic.c:395
int i
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84

◆ associate()

static void associate ( void  )
static

Definition at line 1097 of file zic.c.

References _, eat(), error(), EXIT_FAILURE, getstdoff(), i, nrules, nzones, qsort, rule::r_filename, rule::r_linenum, rule::r_name, rcomp(), warning(), zone::z_filename, zone::z_format_specifier, zone::z_isdst, zone::z_linenum, zone::z_nrules, zone::z_rule, zone::z_rules, and zone::z_stdoff.

Referenced by main().

1098 {
1099  struct zone *zp;
1100  struct rule *rp;
1101  ptrdiff_t i,
1102  j,
1103  base,
1104  out;
1105 
1106  if (nrules != 0)
1107  {
1108  qsort(rules, nrules, sizeof *rules, rcomp);
1109  for (i = 0; i < nrules - 1; ++i)
1110  {
1111  if (strcmp(rules[i].r_name,
1112  rules[i + 1].r_name) != 0)
1113  continue;
1114  if (strcmp(rules[i].r_filename,
1115  rules[i + 1].r_filename) == 0)
1116  continue;
1117  eat(rules[i].r_filename, rules[i].r_linenum);
1118  warning(_("same rule name in multiple files"));
1119  eat(rules[i + 1].r_filename, rules[i + 1].r_linenum);
1120  warning(_("same rule name in multiple files"));
1121  for (j = i + 2; j < nrules; ++j)
1122  {
1123  if (strcmp(rules[i].r_name,
1124  rules[j].r_name) != 0)
1125  break;
1126  if (strcmp(rules[i].r_filename,
1127  rules[j].r_filename) == 0)
1128  continue;
1129  if (strcmp(rules[i + 1].r_filename,
1130  rules[j].r_filename) == 0)
1131  continue;
1132  break;
1133  }
1134  i = j - 1;
1135  }
1136  }
1137  for (i = 0; i < nzones; ++i)
1138  {
1139  zp = &zones[i];
1140  zp->z_rules = NULL;
1141  zp->z_nrules = 0;
1142  }
1143  for (base = 0; base < nrules; base = out)
1144  {
1145  rp = &rules[base];
1146  for (out = base + 1; out < nrules; ++out)
1147  if (strcmp(rp->r_name, rules[out].r_name) != 0)
1148  break;
1149  for (i = 0; i < nzones; ++i)
1150  {
1151  zp = &zones[i];
1152  if (strcmp(zp->z_rule, rp->r_name) != 0)
1153  continue;
1154  zp->z_rules = rp;
1155  zp->z_nrules = out - base;
1156  }
1157  }
1158  for (i = 0; i < nzones; ++i)
1159  {
1160  zp = &zones[i];
1161  if (zp->z_nrules == 0)
1162  {
1163  /*
1164  * Maybe we have a local standard time offset.
1165  */
1166  eat(zp->z_filename, zp->z_linenum);
1167  zp->z_stdoff = getstdoff(zp->z_rule, &zp->z_isdst);
1168 
1169  /*
1170  * Note, though, that if there's no rule, a '%s' in the format is
1171  * a bad thing.
1172  */
1173  if (zp->z_format_specifier == 's')
1174  error("%s", _("%s in ruleless zone"));
1175  }
1176  }
1177  if (errors)
1178  exit(EXIT_FAILURE);
1179 }
lineno_t r_linenum
Definition: zic.c:62
static int rcomp(const void *cp1, const void *cp2)
Definition: zic.c:1090
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
static bool errors
Definition: zic.c:174
static zic_t getstdoff(char *, bool *)
Definition: zic.c:1365
static ptrdiff_t nzones
Definition: zic.c:282
bool z_isdst
Definition: zic.c:109
Definition: localtime.c:77
char z_format_specifier
Definition: zic.c:107
char * z_rule
Definition: zic.c:105
const char * r_name
Definition: zic.c:63
const char * z_filename
Definition: zic.c:100
static struct rule * rules
Definition: zic.c:277
const char * r_filename
Definition: zic.c:61
static void eat(char const *name, lineno_t num)
Definition: zic.c:475
ptrdiff_t z_nrules
Definition: zic.c:113
lineno_t z_linenum
Definition: zic.c:101
static ptrdiff_t nrules
Definition: zic.c:278
static struct zone * zones
Definition: zic.c:281
struct rule * z_rules
Definition: zic.c:112
Definition: zic.c:98
int i
#define EXIT_FAILURE
Definition: settings.h:152
#define qsort(a, b, c, d)
Definition: port.h:421
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84
zic_t z_stdoff
Definition: zic.c:110

◆ atcomp()

static int atcomp ( const void *  avp,
const void *  bvp 
)
static

Definition at line 1930 of file zic.c.

Referenced by writezone().

1931 {
1932  const zic_t a = ((const struct attype *) avp)->at;
1933  const zic_t b = ((const struct attype *) bvp)->at;
1934 
1935  return (a < b) ? -1 : (a > b);
1936 }
Definition: zic.c:383
int64 zic_t
Definition: zic.c:23

◆ byword()

static const struct lookup * byword ( const char *  string,
const struct lookup lp 
)
static

Definition at line 3466 of file zic.c.

References _, ciequal(), ciprefix(), itsabbr(), lookup::l_word, warning(), and wday_names.

Referenced by infile(), inleap(), and rulesub().

3467 {
3468  const struct lookup *foundlp;
3469  const struct lookup *lp;
3470 
3471  if (word == NULL || table == NULL)
3472  return NULL;
3473 
3474  /*
3475  * If TABLE is LASTS and the word starts with "last" followed by a
3476  * non-'-', skip the "last" and look in WDAY_NAMES instead. Warn about any
3477  * usage of the undocumented prefix "last-".
3478  */
3479  if (table == lasts && ciprefix("last", word) && word[4])
3480  {
3481  if (word[4] == '-')
3482  warning(_("\"%s\" is undocumented; use \"last%s\" instead"),
3483  word, word + 5);
3484  else
3485  {
3486  word += 4;
3487  table = wday_names;
3488  }
3489  }
3490 
3491  /*
3492  * Look for exact match.
3493  */
3494  for (lp = table; lp->l_word != NULL; ++lp)
3495  if (ciequal(word, lp->l_word))
3496  return lp;
3497 
3498  /*
3499  * Look for inexact match.
3500  */
3501  foundlp = NULL;
3502  for (lp = table; lp->l_word != NULL; ++lp)
3503  if (ciprefix(word, lp->l_word))
3504  {
3505  if (foundlp == NULL)
3506  foundlp = lp;
3507  else
3508  return NULL; /* multiple inexact matches */
3509  }
3510 
3511  /* Warn about any backward-compatibility issue with pre-2017c zic. */
3512  if (foundlp)
3513  {
3514  bool pre_2017c_match = false;
3515 
3516  for (lp = table; lp->l_word; lp++)
3517  if (itsabbr(word, lp->l_word))
3518  {
3519  if (pre_2017c_match)
3520  {
3521  warning(_("\"%s\" is ambiguous in pre-2017c zic"), word);
3522  break;
3523  }
3524  pre_2017c_match = true;
3525  }
3526  }
3527 
3528  return foundlp;
3529 }
static bool ciprefix(char const *abbr, char const *word)
Definition: zic.c:3455
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
Definition: zic.c:297
static bool ciequal(const char *ap, const char *bp)
Definition: zic.c:3429
const char * l_word
Definition: zic.c:299
static void word(struct vars *, int, struct state *, struct state *)
Definition: regcomp.c:1244
static struct lookup const lasts[]
Definition: zic.c:344
static struct lookup const wday_names[]
Definition: zic.c:333
#define _(x)
Definition: elog.c:84
static bool itsabbr(const char *abbr, const char *word)
Definition: zic.c:3438

◆ change_directory()

static void change_directory ( char const *  dir)
static

Definition at line 553 of file zic.c.

References _, EXIT_FAILURE, mkdirs(), and strerror().

Referenced by main().

554 {
555  if (chdir(dir) != 0)
556  {
557  int chdir_errno = errno;
558 
559  if (chdir_errno == ENOENT)
560  {
561  mkdirs(dir, false);
562  chdir_errno = chdir(dir) == 0 ? 0 : errno;
563  }
564  if (chdir_errno != 0)
565  {
566  fprintf(stderr, _("%s: Can't chdir to %s: %s\n"),
567  progname, dir, strerror(chdir_errno));
568  exit(EXIT_FAILURE);
569  }
570  }
571 }
static void mkdirs(char const *, bool)
Definition: zic.c:3752
static const char * progname
Definition: zic.c:191
const char * strerror(int errnum)
Definition: strerror.c:19
#define EXIT_FAILURE
Definition: settings.h:152
#define _(x)
Definition: elog.c:84

◆ ciequal()

static bool ciequal ( const char *  ap,
const char *  bp 
)
static

Definition at line 3429 of file zic.c.

References lowerit().

Referenced by byword().

3430 {
3431  while (lowerit(*ap) == lowerit(*bp++))
3432  if (*ap++ == '\0')
3433  return true;
3434  return false;
3435 }
static char lowerit(char)
Definition: zic.c:3366

◆ ciprefix()

static bool ciprefix ( char const *  abbr,
char const *  word 
)
static

Definition at line 3455 of file zic.c.

References lowerit().

Referenced by byword().

3456 {
3457  do
3458  if (!*abbr)
3459  return true;
3460  while (lowerit(*abbr++) == lowerit(*word++));
3461 
3462  return false;
3463 }
static char lowerit(char)
Definition: zic.c:3366
static void word(struct vars *, int, struct state *, struct state *)
Definition: regcomp.c:1244

◆ close_file()

static void close_file ( FILE *  stream,
char const *  dir,
char const *  name 
)
static

Definition at line 520 of file zic.c.

References _, EXIT_FAILURE, and strerror().

Referenced by dolink(), infile(), main(), usage(), and writezone().

521 {
522  char const *e = (ferror(stream) ? _("I/O error")
523  : fclose(stream) != 0 ? strerror(errno) : NULL);
524 
525  if (e)
526  {
527  fprintf(stderr, "%s: %s%s%s%s%s\n", progname,
528  dir ? dir : "", dir ? "/" : "",
529  name ? name : "", name ? ": " : "",
530  e);
531  exit(EXIT_FAILURE);
532  }
533 }
static const char * progname
Definition: zic.c:191
const char * name
Definition: encode.c:521
e
Definition: preproc-init.c:82
const char * strerror(int errnum)
Definition: strerror.c:19
#define EXIT_FAILURE
Definition: settings.h:152
#define _(x)
Definition: elog.c:84

◆ componentcheck()

static bool componentcheck ( char const *  name,
char const *  component,
char const *  component_end 
)
static

Definition at line 754 of file zic.c.

References _, error(), and warning().

Referenced by namecheck().

756 {
757  enum
758  {
759  component_len_max = 14};
760  ptrdiff_t component_len = component_end - component;
761 
762  if (component_len == 0)
763  {
764  if (!*name)
765  error(_("empty file name"));
766  else
767  error(_(component == name
768  ? "file name '%s' begins with '/'"
769  : *component_end
770  ? "file name '%s' contains '//'"
771  : "file name '%s' ends with '/'"),
772  name);
773  return false;
774  }
775  if (0 < component_len && component_len <= 2
776  && component[0] == '.' && component_end[-1] == '.')
777  {
778  int len = component_len;
779 
780  error(_("file name '%s' contains '%.*s' component"),
781  name, len, component);
782  return false;
783  }
784  if (noise)
785  {
786  if (0 < component_len && component[0] == '-')
787  warning(_("file name '%s' component contains leading '-'"),
788  name);
789  if (component_len_max < component_len)
790  warning(_("file name '%s' contains overlength component"
791  " '%.*s...'"),
792  name, component_len_max, component);
793  }
794  return true;
795 }
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
static bool noise
Definition: zic.c:186
const char * name
Definition: encode.c:521
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84

◆ convert()

static void convert ( const int32  val,
char *const  buf 
)
static

Definition at line 1890 of file zic.c.

References i.

Referenced by ExecEvalConvertRowtype(), ExecInitExprRec(), fmtfloat(), fmtint(), fmtptr(), get_rule_expr(), puttzcode(), and writezone().

1891 {
1892  int i;
1893  int shift;
1894  unsigned char *const b = (unsigned char *) buf;
1895 
1896  for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
1897  b[i] = val >> shift;
1898 }
static char * buf
Definition: pg_test_fsync.c:67
int i
long val
Definition: informix.c:689

◆ convert64()

static void convert64 ( const zic_t  val,
char *const  buf 
)
static

Definition at line 1901 of file zic.c.

References i.

Referenced by puttzcode64().

1902 {
1903  int i;
1904  int shift;
1905  unsigned char *const b = (unsigned char *) buf;
1906 
1907  for (i = 0, shift = 56; i < 8; ++i, shift -= 8)
1908  b[i] = val >> shift;
1909 }
static char * buf
Definition: pg_test_fsync.c:67
int i
long val
Definition: informix.c:689

◆ doabbr()

static size_t doabbr ( char *  abbr,
struct zone const *  zp,
char const *  letters,
bool  isdst,
zic_t  stdoff,
bool  doquotes 
)
static

Definition at line 2406 of file zic.c.

References abbroffset(), format, is_alpha(), memmove, PERCENT_Z_LEN_BOUND, zone::z_format, zone::z_format_specifier, and zone::z_gmtoff.

Referenced by outzone(), and stringzone().

2408 {
2409  char *cp;
2410  char *slashp;
2411  size_t len;
2412  char const *format = zp->z_format;
2413 
2414  slashp = strchr(format, '/');
2415  if (slashp == NULL)
2416  {
2417  char letterbuf[PERCENT_Z_LEN_BOUND + 1];
2418 
2419  if (zp->z_format_specifier == 'z')
2420  letters = abbroffset(letterbuf, zp->z_gmtoff + stdoff);
2421  else if (!letters)
2422  letters = "%s";
2423  sprintf(abbr, format, letters);
2424  }
2425  else if (isdst)
2426  {
2427  strcpy(abbr, slashp + 1);
2428  }
2429  else
2430  {
2431  memcpy(abbr, format, slashp - format);
2432  abbr[slashp - format] = '\0';
2433  }
2434  len = strlen(abbr);
2435  if (!doquotes)
2436  return len;
2437  for (cp = abbr; is_alpha(*cp); cp++)
2438  continue;
2439  if (len > 0 && *cp == '\0')
2440  return len;
2441  abbr[len + 2] = '\0';
2442  abbr[len + 1] = '>';
2443  memmove(abbr + 1, abbr, len);
2444  abbr[0] = '<';
2445  return len + 2;
2446 }
static char const * abbroffset(char *buf, zic_t offset)
Definition: zic.c:2362
static bool is_alpha(char a)
Definition: zic.c:3301
#define memmove(d, s, c)
Definition: c.h:1135
static char format
Definition: pg_basebackup.c:83

◆ dolink()

static void dolink ( const char *  fromfield,
const char *  tofield,
bool  staysymlink 
)
static

Definition at line 899 of file zic.c.

References _, close_file(), ENOTSUP, EXIT_FAILURE, free, hardlinkerr(), itsdir(), itssymlink(), mkdirs(), strerror(), symlink, and warning().

Referenced by main().

900 {
901  bool todirs_made = false;
902  int link_errno;
903 
904  /*
905  * We get to be careful here since there's a fair chance of root running
906  * us.
907  */
908  if (itsdir(fromfield))
909  {
910  fprintf(stderr, _("%s: link from %s/%s failed: %s\n"),
911  progname, directory, fromfield, strerror(EPERM));
912  exit(EXIT_FAILURE);
913  }
914  if (staysymlink)
915  staysymlink = itssymlink(tofield);
916  if (remove(tofield) == 0)
917  todirs_made = true;
918  else if (errno != ENOENT)
919  {
920  char const *e = strerror(errno);
921 
922  fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
923  progname, directory, tofield, e);
924  exit(EXIT_FAILURE);
925  }
926  link_errno = staysymlink ? ENOTSUP : hardlinkerr(fromfield, tofield);
927  if (link_errno == ENOENT && !todirs_made)
928  {
929  mkdirs(tofield, true);
930  todirs_made = true;
931  link_errno = hardlinkerr(fromfield, tofield);
932  }
933  if (link_errno != 0)
934  {
935 #ifdef HAVE_SYMLINK
936  bool absolute = *fromfield == '/';
937  char *linkalloc = absolute ? NULL : relname(fromfield, tofield);
938  char const *contents = absolute ? fromfield : linkalloc;
939  int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
940 
941  if (!todirs_made
942  && (symlink_errno == ENOENT || symlink_errno == ENOTSUP))
943  {
944  mkdirs(tofield, true);
945  if (symlink_errno == ENOENT)
946  symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
947  }
948  free(linkalloc);
949  if (symlink_errno == 0)
950  {
951  if (link_errno != ENOTSUP)
952  warning(_("symbolic link used because hard link failed: %s"),
953  strerror(link_errno));
954  }
955  else
956 #endif /* HAVE_SYMLINK */
957  {
958  FILE *fp,
959  *tp;
960  int c;
961 
962  fp = fopen(fromfield, "rb");
963  if (!fp)
964  {
965  char const *e = strerror(errno);
966 
967  fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
968  progname, directory, fromfield, e);
969  exit(EXIT_FAILURE);
970  }
971  tp = fopen(tofield, "wb");
972  if (!tp)
973  {
974  char const *e = strerror(errno);
975 
976  fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
977  progname, directory, tofield, e);
978  exit(EXIT_FAILURE);
979  }
980  while ((c = getc(fp)) != EOF)
981  putc(c, tp);
982  close_file(fp, directory, fromfield);
983  close_file(tp, directory, tofield);
984  if (link_errno != ENOTSUP)
985  warning(_("copy used because hard link failed: %s"),
986  strerror(link_errno));
987 #ifdef HAVE_SYMLINK
988  else if (symlink_errno != ENOTSUP)
989  warning(_("copy used because symbolic link failed: %s"),
990  strerror(symlink_errno));
991 #endif
992  }
993  }
994 }
static int hardlinkerr(char const *from, char const *to)
Definition: zic.c:891
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
#define ENOTSUP
Definition: private.h:35
static void mkdirs(char const *, bool)
Definition: zic.c:3752
static bool itsdir(char const *)
Definition: zic.c:1045
char * c
#define symlink(oldpath, newpath)
Definition: win32_port.h:232
static bool itssymlink(char const *)
Definition: zic.c:1070
static const char * progname
Definition: zic.c:191
#define free(a)
Definition: header.h:65
static const char * directory
Definition: zic.c:575
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:520
e
Definition: preproc-init.c:82
const char * strerror(int errnum)
Definition: strerror.c:19
#define EXIT_FAILURE
Definition: settings.h:152
#define _(x)
Definition: elog.c:84

◆ eat()

static void eat ( char const *  name,
lineno_t  num 
)
static

Definition at line 475 of file zic.c.

References eats().

Referenced by associate(), infile(), main(), and outzone().

476 {
477  eats(name, num, NULL, -1);
478 }
const char * name
Definition: encode.c:521
static void eats(char const *name, lineno_t num, char const *rname, lineno_t rnum)
Definition: zic.c:466

◆ eats()

static void eats ( char const *  name,
lineno_t  num,
char const *  rname,
lineno_t  rnum 
)
static

Definition at line 466 of file zic.c.

References name.

Referenced by eat(), and outzone().

467 {
468  filename = name;
469  linenum = num;
470  rfilename = rname;
471  rlinenum = rnum;
472 }
static lineno_t rlinenum
Definition: zic.c:190
static const char * filename
Definition: zic.c:176
static lineno_t linenum
Definition: zic.c:181
static const char * rfilename
Definition: zic.c:189
const char * name
Definition: encode.c:521

◆ ecpyalloc()

static char* ecpyalloc ( char const *  str)
static

Definition at line 439 of file zic.c.

References memcheck().

Referenced by inlink(), inrule(), inzsub(), mkdirs(), and rulesub().

440 {
441  return memcheck(strdup(str));
442 }
static void * memcheck(void *ptr)
Definition: zic.c:419

◆ emalloc()

static void* emalloc ( size_t  size)
static

Definition at line 427 of file zic.c.

References malloc, and memcheck().

Referenced by getfields(), itsdir(), namecheck(), outzone(), writezone(), and yearistype().

428 {
429  return memcheck(malloc(size));
430 }
#define malloc(a)
Definition: header.h:50
static void * memcheck(void *ptr)
Definition: zic.c:419

◆ erealloc()

static void* erealloc ( void *  ptr,
size_t  size 
)
static

Definition at line 433 of file zic.c.

References memcheck(), and realloc.

Referenced by growalloc().

434 {
435  return memcheck(realloc(ptr, size));
436 }
#define realloc(a, b)
Definition: header.h:60
static void * memcheck(void *ptr)
Definition: zic.c:419

◆ error()

static void error ( const char *  string,
  ... 
)
static

Definition at line 497 of file zic.c.

References generate_unaccent_rules::args, and verror().

Referenced by abbroffset(), addtype(), adjleap(), associate(), componentcheck(), getfields(), gethms(), infile(), inleap(), inlink(), inrule(), inzcont(), inzone(), inzsub(), leapadd(), mkdirs(), newabbr(), outzone(), rpytime(), rulesub(), time_overflow(), writezone(), and yearistype().

498 {
499  va_list args;
500 
501  va_start(args, string);
502  verror(string, args);
503  va_end(args);
504  errors = true;
505 }
static bool errors
Definition: zic.c:174
static void verror(const char *string, va_list args) pg_attribute_printf(1
Definition: zic.c:481

◆ getfields()

static char ** getfields ( char *  buf)
static

Definition at line 3532 of file zic.c.

References _, emalloc(), error(), EXIT_FAILURE, is_space(), and size_product().

Referenced by infile().

3533 {
3534  char *dp;
3535  char **array;
3536  int nsubs;
3537 
3538  if (cp == NULL)
3539  return NULL;
3540  array = emalloc(size_product(strlen(cp) + 1, sizeof *array));
3541  nsubs = 0;
3542  for (;;)
3543  {
3544  while (is_space(*cp))
3545  ++cp;
3546  if (*cp == '\0' || *cp == '#')
3547  break;
3548  array[nsubs++] = dp = cp;
3549  do
3550  {
3551  if ((*dp = *cp++) != '"')
3552  ++dp;
3553  else
3554  while ((*dp = *cp++) != '"')
3555  if (*dp != '\0')
3556  ++dp;
3557  else
3558  {
3559  error(_("Odd number of quotation marks"));
3560  exit(EXIT_FAILURE);
3561  }
3562  } while (*cp && *cp != '#' && !is_space(*cp));
3563  if (is_space(*cp))
3564  ++cp;
3565  *dp = '\0';
3566  }
3567  array[nsubs] = NULL;
3568  return array;
3569 }
static bool is_space(char a)
Definition: zic.c:3283
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84
static size_t size_product(size_t nitems, size_t itemsize)
Definition: zic.c:411
static void * emalloc(size_t size)
Definition: zic.c:427

◆ gethms()

static zic_t gethms ( const char *  string,
const char *  errstring,
bool  signable 
)
static

Definition at line 1285 of file zic.c.

References _, error(), HOURSPERDAY, MINSPERHOUR, oadd(), SECSPERHOUR, SECSPERMIN, sign, warning(), and ZIC_MAX.

Referenced by getstdoff(), inleap(), inzsub(), and rulesub().

1286 {
1287  /* PG: make hh be int not zic_t to avoid sscanf portability issues */
1288  int hh;
1289  int sign,
1290  mm = 0,
1291  ss = 0;
1292  char hhx,
1293  mmx,
1294  ssx,
1295  xr = '0',
1296  xs;
1297  int tenths = 0;
1298  bool ok = true;
1299 
1300  if (string == NULL || *string == '\0')
1301  return 0;
1302  if (!signable)
1303  sign = 1;
1304  else if (*string == '-')
1305  {
1306  sign = -1;
1307  ++string;
1308  }
1309  else
1310  sign = 1;
1311  switch (sscanf(string,
1312  "%d%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
1313  &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs))
1314  {
1315  default:
1316  ok = false;
1317  break;
1318  case 8:
1319  ok = '0' <= xr && xr <= '9';
1320  /* fallthrough */
1321  case 7:
1322  ok &= ssx == '.';
1323  if (ok && noise)
1324  warning(_("fractional seconds rejected by"
1325  " pre-2018 versions of zic"));
1326  /* fallthrough */
1327  case 5:
1328  ok &= mmx == ':';
1329  /* fallthrough */
1330  case 3:
1331  ok &= hhx == ':';
1332  /* fallthrough */
1333  case 1:
1334  break;
1335  }
1336  if (!ok)
1337  {
1338  error("%s", errstring);
1339  return 0;
1340  }
1341  if (hh < 0 ||
1342  mm < 0 || mm >= MINSPERHOUR ||
1343  ss < 0 || ss > SECSPERMIN)
1344  {
1345  error("%s", errstring);
1346  return 0;
1347  }
1348  /* Some compilers warn that this test is unsatisfiable for 32-bit ints */
1349 #if INT_MAX > PG_INT32_MAX
1350  if (ZIC_MAX / SECSPERHOUR < hh)
1351  {
1352  error(_("time overflow"));
1353  return 0;
1354  }
1355 #endif
1356  ss += 5 + ((ss ^ 1) & (xr == '0')) <= tenths; /* Round to even. */
1357  if (noise && (hh > HOURSPERDAY ||
1358  (hh == HOURSPERDAY && (mm != 0 || ss != 0))))
1359  warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
1360  return oadd(sign * (zic_t) hh * SECSPERHOUR,
1361  sign * (mm * SECSPERMIN + ss));
1362 }
#define SECSPERMIN
Definition: private.h:90
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
#define SECSPERHOUR
Definition: private.h:96
#define HOURSPERDAY
Definition: private.h:92
#define ZIC_MAX
Definition: zic.c:25
char sign
Definition: informix.c:693
char string[11]
Definition: preproc-type.c:46
int64 zic_t
Definition: zic.c:23
static bool noise
Definition: zic.c:186
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84
static zic_t oadd(zic_t t1, zic_t t2)
Definition: zic.c:3579
#define MINSPERHOUR
Definition: private.h:91

◆ getstdoff()

static zic_t getstdoff ( char *  field,
bool isdst 
)
static

Definition at line 1365 of file zic.c.

References _, and gethms().

Referenced by associate(), and inrule().

1366 {
1367  int dst = -1;
1368  zic_t stdoff;
1369  size_t fieldlen = strlen(field);
1370 
1371  if (fieldlen != 0)
1372  {
1373  char *ep = field + fieldlen - 1;
1374 
1375  switch (*ep)
1376  {
1377  case 'd':
1378  dst = 1;
1379  *ep = '\0';
1380  break;
1381  case 's':
1382  dst = 0;
1383  *ep = '\0';
1384  break;
1385  }
1386  }
1387  stdoff = gethms(field, _("invalid saved time"), true);
1388  *isdst = dst < 0 ? stdoff != 0 : dst;
1389  return stdoff;
1390 }
int64 zic_t
Definition: zic.c:23
static zic_t gethms(const char *string, const char *errstring, bool)
Definition: zic.c:1285
#define _(x)
Definition: elog.c:84

◆ growalloc()

static void* growalloc ( void *  ptr,
size_t  itemsize,
ptrdiff_t  nitems,
ptrdiff_t *  nitems_alloc 
)
static

Definition at line 445 of file zic.c.

References _, erealloc(), memory_exhausted(), PTRDIFF_MAX, SIZE_MAX, size_product(), and WORK_AROUND_QTBUG_53071.

Referenced by addtt(), inlink(), inrule(), and inzsub().

446 {
447  if (nitems < *nitems_alloc)
448  return ptr;
449  else
450  {
451  ptrdiff_t nitems_max = PTRDIFF_MAX - WORK_AROUND_QTBUG_53071;
452  ptrdiff_t amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
453 
454  if ((amax - 1) / 3 * 2 < *nitems_alloc)
455  memory_exhausted(_("integer overflow"));
456  *nitems_alloc += (*nitems_alloc >> 1) + 1;
457  return erealloc(ptr, size_product(*nitems_alloc, itemsize));
458  }
459 }
#define SIZE_MAX
Definition: c.h:419
static ptrdiff_t const PTRDIFF_MAX
Definition: zic.c:49
static void memory_exhausted(const char *msg) pg_attribute_noreturn()
Definition: zic.c:404
#define _(x)
Definition: elog.c:84
static size_t size_product(size_t nitems, size_t itemsize)
Definition: zic.c:411
static void * erealloc(void *ptr, size_t size)
Definition: zic.c:433

◆ hardlinkerr()

static int hardlinkerr ( char const *  from,
char const *  to 
)
static

Definition at line 891 of file zic.c.

References linkat.

Referenced by dolink().

892 {
893  int r = linkat(AT_FDCWD, from, AT_FDCWD, to, AT_SYMLINK_FOLLOW);
894 
895  return r == 0 ? 0 : errno;
896 }
#define linkat(fromdir, from, todir, to, flag)
Definition: zic.c:39

◆ infile()

static void infile ( const char *  filename)
static

Definition at line 1182 of file zic.c.

References _, buf, byword(), close_file(), eat(), error(), EXIT_FAILURE, free, getfields(), inleap(), inlink(), inrule(), inzcont(), inzone(), lookup::l_value, LC_LEAP, LC_LINK, LC_RULE, LC_ZONE, leap_line_codes, strerror(), and zi_line_codes.

Referenced by AlterSystemSetConfigFile(), convert_sourcefiles_in(), isolation_start_test(), main(), psql_start_test(), and readfile().

1183 {
1184  FILE *fp;
1185  char **fields;
1186  char *cp;
1187  const struct lookup *lp;
1188  int nfields;
1189  bool wantcont;
1190  lineno_t num;
1191  char buf[BUFSIZ];
1192 
1193  if (strcmp(name, "-") == 0)
1194  {
1195  name = _("standard input");
1196  fp = stdin;
1197  }
1198  else if ((fp = fopen(name, "r")) == NULL)
1199  {
1200  const char *e = strerror(errno);
1201 
1202  fprintf(stderr, _("%s: Cannot open %s: %s\n"),
1203  progname, name, e);
1204  exit(EXIT_FAILURE);
1205  }
1206  wantcont = false;
1207  for (num = 1;; ++num)
1208  {
1209  eat(name, num);
1210  if (fgets(buf, sizeof buf, fp) != buf)
1211  break;
1212  cp = strchr(buf, '\n');
1213  if (cp == NULL)
1214  {
1215  error(_("line too long"));
1216  exit(EXIT_FAILURE);
1217  }
1218  *cp = '\0';
1219  fields = getfields(buf);
1220  nfields = 0;
1221  while (fields[nfields] != NULL)
1222  {
1223  static char nada;
1224 
1225  if (strcmp(fields[nfields], "-") == 0)
1226  fields[nfields] = &nada;
1227  ++nfields;
1228  }
1229  if (nfields == 0)
1230  {
1231  /* nothing to do */
1232  }
1233  else if (wantcont)
1234  {
1235  wantcont = inzcont(fields, nfields);
1236  }
1237  else
1238  {
1239  struct lookup const *line_codes
1241 
1242  lp = byword(fields[0], line_codes);
1243  if (lp == NULL)
1244  error(_("input line of unknown type"));
1245  else
1246  switch (lp->l_value)
1247  {
1248  case LC_RULE:
1249  inrule(fields, nfields);
1250  wantcont = false;
1251  break;
1252  case LC_ZONE:
1253  wantcont = inzone(fields, nfields);
1254  break;
1255  case LC_LINK:
1256  inlink(fields, nfields);
1257  wantcont = false;
1258  break;
1259  case LC_LEAP:
1260  inleap(fields, nfields);
1261  wantcont = false;
1262  break;
1263  default: /* "cannot happen" */
1264  fprintf(stderr,
1265  _("%s: panic: Invalid l_value %d\n"),
1266  progname, lp->l_value);
1267  exit(EXIT_FAILURE);
1268  }
1269  }
1270  free(fields);
1271  }
1272  close_file(fp, NULL, filename);
1273  if (wantcont)
1274  error(_("expected continuation line not found"));
1275 }
static struct lookup const zi_line_codes[]
Definition: zic.c:306
static struct lookup const leap_line_codes[]
Definition: zic.c:312
static void inrule(char **fields, int nfields)
Definition: zic.c:1393
#define LC_LEAP
Definition: zic.c:203
static const char * leapsec
Definition: zic.c:576
const int l_value
Definition: zic.c:300
static const char * filename
Definition: zic.c:176
static void inleap(char **fields, int nfields)
Definition: zic.c:1569
static char ** getfields(char *buf)
Definition: zic.c:3532
static bool inzcont(char **fields, int nfields)
Definition: zic.c:1459
static char * buf
Definition: pg_test_fsync.c:67
Definition: zic.c:297
#define LC_LINK
Definition: zic.c:202
static void eat(char const *name, lineno_t num)
Definition: zic.c:475
#define LC_ZONE
Definition: zic.c:201
static const char * progname
Definition: zic.c:191
#define free(a)
Definition: header.h:65
static bool inzone(char **fields, int nfields)
Definition: zic.c:1421
static void inlink(char **fields, int nfields)
Definition: zic.c:1689
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:520
static struct lookup const * byword(const char *string, const struct lookup *lp)
Definition: zic.c:3466
const char * name
Definition: encode.c:521
e
Definition: preproc-init.c:82
const char * strerror(int errnum)
Definition: strerror.c:19
#define EXIT_FAILURE
Definition: settings.h:152
int lineno_t
Definition: zic.c:57
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define LC_RULE
Definition: zic.c:200
#define _(x)
Definition: elog.c:84

◆ inleap()

static void inleap ( char **  fields,
int  nfields 
)
static

Definition at line 1569 of file zic.c.

References _, byword(), EPOCH_YEAR, error(), gethms(), i, isleap, lookup::l_value, LEAP_FIELDS, leapadd(), LP_CORR, LP_DAY, LP_MONTH, LP_ROLL, LP_TIME, LP_YEAR, oadd(), SECSPERDAY, tadd(), and TM_JANUARY.

Referenced by infile().

1570 {
1571  const char *cp;
1572  const struct lookup *lp;
1573  zic_t i,
1574  j;
1575 
1576  /* PG: make year be int not zic_t to avoid sscanf portability issues */
1577  int year;
1578  int month,
1579  day;
1580  zic_t dayoff,
1581  tod;
1582  zic_t t;
1583  char xs;
1584 
1585  if (nfields != LEAP_FIELDS)
1586  {
1587  error(_("wrong number of fields on Leap line"));
1588  return;
1589  }
1590  dayoff = 0;
1591  cp = fields[LP_YEAR];
1592  if (sscanf(cp, "%d%c", &year, &xs) != 1)
1593  {
1594  /*
1595  * Leapin' Lizards!
1596  */
1597  error(_("invalid leaping year"));
1598  return;
1599  }
1600  if (!leapseen || leapmaxyear < year)
1601  leapmaxyear = year;
1602  if (!leapseen || leapminyear > year)
1603  leapminyear = year;
1604  leapseen = true;
1605  j = EPOCH_YEAR;
1606  while (j != year)
1607  {
1608  if (year > j)
1609  {
1610  i = len_years[isleap(j)];
1611  ++j;
1612  }
1613  else
1614  {
1615  --j;
1616  i = -len_years[isleap(j)];
1617  }
1618  dayoff = oadd(dayoff, i);
1619  }
1620  if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL)
1621  {
1622  error(_("invalid month name"));
1623  return;
1624  }
1625  month = lp->l_value;
1626  j = TM_JANUARY;
1627  while (j != month)
1628  {
1629  i = len_months[isleap(year)][j];
1630  dayoff = oadd(dayoff, i);
1631  ++j;
1632  }
1633  cp = fields[LP_DAY];
1634  if (sscanf(cp, "%d%c", &day, &xs) != 1 ||
1635  day <= 0 || day > len_months[isleap(year)][month])
1636  {
1637  error(_("invalid day of month"));
1638  return;
1639  }
1640  dayoff = oadd(dayoff, day - 1);
1641  if (dayoff < min_time / SECSPERDAY)
1642  {
1643  error(_("time too small"));
1644  return;
1645  }
1646  if (dayoff > max_time / SECSPERDAY)
1647  {
1648  error(_("time too large"));
1649  return;
1650  }
1651  t = dayoff * SECSPERDAY;
1652  tod = gethms(fields[LP_TIME], _("invalid time of day"), false);
1653  cp = fields[LP_CORR];
1654  {
1655  bool positive;
1656  int count;
1657 
1658  if (strcmp(cp, "") == 0)
1659  { /* infile() turns "-" into "" */
1660  positive = false;
1661  count = 1;
1662  }
1663  else if (strcmp(cp, "+") == 0)
1664  {
1665  positive = true;
1666  count = 1;
1667  }
1668  else
1669  {
1670  error(_("illegal CORRECTION field on Leap line"));
1671  return;
1672  }
1673  if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL)
1674  {
1675  error(_("illegal Rolling/Stationary field on Leap line"));
1676  return;
1677  }
1678  t = tadd(t, tod);
1679  if (t < 0)
1680  {
1681  error(_("leap second precedes Epoch"));
1682  return;
1683  }
1684  leapadd(t, positive, lp->l_value, count);
1685  }
1686 }
#define LP_CORR
Definition: zic.c:265
static zic_t leapmaxyear
Definition: zic.c:180
#define SECSPERDAY
Definition: private.h:97
#define isleap(y)
Definition: datetime.h:273
static const int len_months[2][MONSPERYEAR]
Definition: zic.c:374
const int l_value
Definition: zic.c:300
#define LP_ROLL
Definition: zic.c:266
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3587
#define LEAP_FIELDS
Definition: zic.c:267
static struct lookup const mon_names[]
Definition: zic.c:317
#define LP_DAY
Definition: zic.c:263
static bool leapseen
Definition: zic.c:178
int64 zic_t
Definition: zic.c:23
Definition: zic.c:297
static void leapadd(zic_t, bool, int, int)
Definition: zic.c:3182
#define EPOCH_YEAR
Definition: private.h:123
#define LP_TIME
Definition: zic.c:264
static zic_t gethms(const char *string, const char *errstring, bool)
Definition: zic.c:1285
static zic_t const max_time
Definition: zic.c:999
#define TM_JANUARY
Definition: private.h:108
static struct lookup const * byword(const char *string, const struct lookup *lp)
Definition: zic.c:3466
static zic_t leapminyear
Definition: zic.c:179
#define LP_YEAR
Definition: zic.c:261
int i
static struct lookup const leap_types[]
Definition: zic.c:368
static const int len_years[2]
Definition: zic.c:379
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
static zic_t const min_time
Definition: zic.c:998
#define LP_MONTH
Definition: zic.c:262
#define _(x)
Definition: elog.c:84
static zic_t oadd(zic_t t1, zic_t t2)
Definition: zic.c:3579

◆ inlink()

static void inlink ( char **  fields,
int  nfields 
)
static

Definition at line 1689 of file zic.c.

References _, ecpyalloc(), error(), filename, growalloc(), link::l_filename, link::l_from, link::l_linenum, link::l_to, LF_FROM, LF_TO, linenum, LINK_FIELDS, and namecheck().

Referenced by infile().

1690 {
1691  struct link l;
1692 
1693  if (nfields != LINK_FIELDS)
1694  {
1695  error(_("wrong number of fields on Link line"));
1696  return;
1697  }
1698  if (*fields[LF_FROM] == '\0')
1699  {
1700  error(_("blank FROM field on Link line"));
1701  return;
1702  }
1703  if (!namecheck(fields[LF_TO]))
1704  return;
1705  l.l_filename = filename;
1706  l.l_linenum = linenum;
1707  l.l_from = ecpyalloc(fields[LF_FROM]);
1708  l.l_to = ecpyalloc(fields[LF_TO]);
1709  links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
1710  links[nlinks++] = l;
1711 }
static ptrdiff_t nlinks
Definition: zic.c:294
static char * ecpyalloc(char const *str)
Definition: zic.c:439
#define LF_TO
Definition: zic.c:254
static const char * filename
Definition: zic.c:176
static lineno_t linenum
Definition: zic.c:181
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
Definition: zic.c:445
static ptrdiff_t nlinks_alloc
Definition: zic.c:295
#define LF_FROM
Definition: zic.c:253
static struct link * links
Definition: zic.c:293
#define LINK_FIELDS
Definition: zic.c:255
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84
static bool namecheck(const char *name)
Definition: zic.c:798

◆ inrule()

static void inrule ( char **  fields,
int  nfields 
)
static

Definition at line 1393 of file zic.c.

References _, ecpyalloc(), error(), filename, getstdoff(), growalloc(), linenum, rule::r_abbrvar, rule::r_filename, rule::r_isdst, rule::r_linenum, rule::r_name, rule::r_stdoff, RF_ABBRVAR, RF_COMMAND, RF_DAY, RF_HIYEAR, RF_LOYEAR, RF_MONTH, RF_NAME, RF_STDOFF, RF_TOD, RULE_FIELDS, and rulesub().

Referenced by infile().

1394 {
1395  static struct rule r;
1396 
1397  if (nfields != RULE_FIELDS)
1398  {
1399  error(_("wrong number of fields on Rule line"));
1400  return;
1401  }
1402  if (*fields[RF_NAME] == '\0')
1403  {
1404  error(_("nameless rule"));
1405  return;
1406  }
1407  r.r_filename = filename;
1408  r.r_linenum = linenum;
1409  r.r_stdoff = getstdoff(fields[RF_STDOFF], &r.r_isdst);
1410  rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
1411  fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
1412  r.r_name = ecpyalloc(fields[RF_NAME]);
1413  r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
1414  if (max_abbrvar_len < strlen(r.r_abbrvar))
1415  max_abbrvar_len = strlen(r.r_abbrvar);
1416  rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc);
1417  rules[nrules++] = r;
1418 }
static char * ecpyalloc(char const *str)
Definition: zic.c:439
#define RF_COMMAND
Definition: zic.c:241
static zic_t getstdoff(char *, bool *)
Definition: zic.c:1365
Definition: localtime.c:77
static const char * filename
Definition: zic.c:176
static lineno_t linenum
Definition: zic.c:181
static int max_abbrvar_len
Definition: zic.c:182
static struct rule * rules
Definition: zic.c:277
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
Definition: zic.c:445
#define RF_HIYEAR
Definition: zic.c:240
#define RF_NAME
Definition: zic.c:238
static ptrdiff_t nrules_alloc
Definition: zic.c:279
static void rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, const char *typep, const char *monthp, const char *dayp, const char *timep)
Definition: zic.c:1714
static ptrdiff_t nrules
Definition: zic.c:278
#define RF_TOD
Definition: zic.c:244
#define RF_ABBRVAR
Definition: zic.c:246
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define RF_LOYEAR
Definition: zic.c:239
#define _(x)
Definition: elog.c:84
#define RULE_FIELDS
Definition: zic.c:247
#define RF_MONTH
Definition: zic.c:242
#define RF_STDOFF
Definition: zic.c:245
#define RF_DAY
Definition: zic.c:243

◆ inzcont()

static bool inzcont ( char **  fields,
int  nfields 
)
static

Definition at line 1459 of file zic.c.

References _, error(), inzsub(), and ZONEC_MAXFIELDS.

Referenced by infile().

1460 {
1461  if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS)
1462  {
1463  error(_("wrong number of fields on Zone continuation line"));
1464  return false;
1465  }
1466  return inzsub(fields, nfields, true);
1467 }
#define ZONEC_MAXFIELDS
Definition: zic.c:232
static bool inzsub(char **, int, bool)
Definition: zic.c:1470
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84

◆ inzone()

static bool inzone ( char **  fields,
int  nfields 
)
static

Definition at line 1421 of file zic.c.

References _, error(), i, inzsub(), nzones, TZDEFRULES, ZF_NAME, and ZONE_MAXFIELDS.

Referenced by infile().

1422 {
1423  ptrdiff_t i;
1424 
1425  if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS)
1426  {
1427  error(_("wrong number of fields on Zone line"));
1428  return false;
1429  }
1430  if (lcltime != NULL && strcmp(fields[ZF_NAME], tzdefault) == 0)
1431  {
1432  error(
1433  _("\"Zone %s\" line and -l option are mutually exclusive"),
1434  tzdefault);
1435  return false;
1436  }
1437  if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL)
1438  {
1439  error(
1440  _("\"Zone %s\" line and -p option are mutually exclusive"),
1441  TZDEFRULES);
1442  return false;
1443  }
1444  for (i = 0; i < nzones; ++i)
1445  if (zones[i].z_name != NULL &&
1446  strcmp(zones[i].z_name, fields[ZF_NAME]) == 0)
1447  {
1448  error(_("duplicate zone name %s"
1449  " (file \"%s\", line %d)"),
1450  fields[ZF_NAME],
1451  zones[i].z_filename,
1452  zones[i].z_linenum);
1453  return false;
1454  }
1455  return inzsub(fields, nfields, false);
1456 }
#define ZF_NAME
Definition: zic.c:209
static ptrdiff_t nzones
Definition: zic.c:282
static const char * psxrules
Definition: zic.c:573
static bool inzsub(char **, int, bool)
Definition: zic.c:1470
#define ZONE_MAXFIELDS
Definition: zic.c:218
static const char * lcltime
Definition: zic.c:574
#define TZDEFRULES
Definition: tzfile.h:25
static struct zone * zones
Definition: zic.c:281
int i
static const char * tzdefault
Definition: zic.c:577
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84

◆ inzsub()

static bool inzsub ( char **  fields,
int  nfields,
bool  iscont 
)
static

Definition at line 1470 of file zic.c.

References _, ecpyalloc(), error(), filename, gethms(), growalloc(), linenum, namecheck(), rule::r_filename, rule::r_linenum, rule::r_loyear, rpytime(), rulesub(), warning(), zone::z_filename, zone::z_format, zone::z_format_specifier, zone::z_gmtoff, zone::z_linenum, zone::z_name, zone::z_rule, zone::z_untilrule, zone::z_untiltime, ZF_FORMAT, ZF_GMTOFF, ZF_NAME, ZF_RULE, ZF_TILDAY, ZF_TILMONTH, ZF_TILTIME, ZF_TILYEAR, ZFC_FORMAT, ZFC_GMTOFF, ZFC_RULE, ZFC_TILDAY, ZFC_TILMONTH, ZFC_TILTIME, and ZFC_TILYEAR.

Referenced by inzcont(), and inzone().

1471 {
1472  char *cp;
1473  char *cp1;
1474  static struct zone z;
1475  int i_gmtoff,
1476  i_rule,
1477  i_format;
1478  int i_untilyear,
1479  i_untilmonth;
1480  int i_untilday,
1481  i_untiltime;
1482  bool hasuntil;
1483 
1484  if (iscont)
1485  {
1486  i_gmtoff = ZFC_GMTOFF;
1487  i_rule = ZFC_RULE;
1488  i_format = ZFC_FORMAT;
1489  i_untilyear = ZFC_TILYEAR;
1490  i_untilmonth = ZFC_TILMONTH;
1491  i_untilday = ZFC_TILDAY;
1492  i_untiltime = ZFC_TILTIME;
1493  z.z_name = NULL;
1494  }
1495  else if (!namecheck(fields[ZF_NAME]))
1496  return false;
1497  else
1498  {
1499  i_gmtoff = ZF_GMTOFF;
1500  i_rule = ZF_RULE;
1501  i_format = ZF_FORMAT;
1502  i_untilyear = ZF_TILYEAR;
1503  i_untilmonth = ZF_TILMONTH;
1504  i_untilday = ZF_TILDAY;
1505  i_untiltime = ZF_TILTIME;
1506  z.z_name = ecpyalloc(fields[ZF_NAME]);
1507  }
1508  z.z_filename = filename;
1509  z.z_linenum = linenum;
1510  z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset"), true);
1511  if ((cp = strchr(fields[i_format], '%')) != NULL)
1512  {
1513  if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
1514  || strchr(fields[i_format], '/'))
1515  {
1516  error(_("invalid abbreviation format"));
1517  return false;
1518  }
1519  }
1520  z.z_rule = ecpyalloc(fields[i_rule]);
1521  z.z_format = cp1 = ecpyalloc(fields[i_format]);
1522  z.z_format_specifier = cp ? *cp : '\0';
1523  if (z.z_format_specifier == 'z')
1524  {
1525  if (noise)
1526  warning(_("format '%s' not handled by pre-2015 versions of zic"),
1527  z.z_format);
1528  cp1[cp - fields[i_format]] = 's';
1529  }
1530  if (max_format_len < strlen(z.z_format))
1531  max_format_len = strlen(z.z_format);
1532  hasuntil = nfields > i_untilyear;
1533  if (hasuntil)
1534  {
1535  z.z_untilrule.r_filename = filename;
1536  z.z_untilrule.r_linenum = linenum;
1537  rulesub(&z.z_untilrule,
1538  fields[i_untilyear],
1539  "only",
1540  "",
1541  (nfields > i_untilmonth) ?
1542  fields[i_untilmonth] : "Jan",
1543  (nfields > i_untilday) ? fields[i_untilday] : "1",
1544  (nfields > i_untiltime) ? fields[i_untiltime] : "0");
1545  z.z_untiltime = rpytime(&z.z_untilrule,
1546  z.z_untilrule.r_loyear);
1547  if (iscont && nzones > 0 &&
1548  z.z_untiltime > min_time &&
1549  z.z_untiltime < max_time &&
1550  zones[nzones - 1].z_untiltime > min_time &&
1551  zones[nzones - 1].z_untiltime < max_time &&
1552  zones[nzones - 1].z_untiltime >= z.z_untiltime)
1553  {
1554  error(_("Zone continuation line end time is not after end time of previous line"));
1555  return false;
1556  }
1557  }
1558  zones = growalloc(zones, sizeof *zones, nzones, &nzones_alloc);
1559  zones[nzones++] = z;
1560 
1561  /*
1562  * If there was an UNTIL field on this line, there's more information
1563  * about the zone on the next line.
1564  */
1565  return hasuntil;
1566 }
#define ZF_TILMONTH
Definition: zic.c:214
#define ZF_TILTIME
Definition: zic.c:216
#define ZF_TILYEAR
Definition: zic.c:213
#define ZF_NAME
Definition: zic.c:209
#define ZFC_TILMONTH
Definition: zic.c:228
static char * ecpyalloc(char const *str)
Definition: zic.c:439
#define ZF_RULE
Definition: zic.c:211
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
zic_t z_untiltime
Definition: zic.c:116
static ptrdiff_t nzones
Definition: zic.c:282
#define ZF_GMTOFF
Definition: zic.c:210
#define ZFC_FORMAT
Definition: zic.c:226
static int max_format_len
Definition: zic.c:183
static const char * filename
Definition: zic.c:176
#define ZF_FORMAT
Definition: zic.c:212
static lineno_t linenum
Definition: zic.c:181
static ptrdiff_t nzones_alloc
Definition: zic.c:283
#define ZFC_TILTIME
Definition: zic.c:230
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
Definition: zic.c:445
#define ZFC_RULE
Definition: zic.c:225
static zic_t rpytime(const struct rule *rp, zic_t wantedy)
Definition: zic.c:3616
static zic_t gethms(const char *string, const char *errstring, bool)
Definition: zic.c:1285
#define ZF_TILDAY
Definition: zic.c:215
static zic_t const max_time
Definition: zic.c:999
static bool noise
Definition: zic.c:186
static void rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, const char *typep, const char *monthp, const char *dayp, const char *timep)
Definition: zic.c:1714
static struct zone * zones
Definition: zic.c:281
Definition: zic.c:98
#define ZFC_TILDAY
Definition: zic.c:229
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
static zic_t const min_time
Definition: zic.c:998
#define ZFC_TILYEAR
Definition: zic.c:227
#define _(x)
Definition: elog.c:84
#define ZFC_GMTOFF
Definition: zic.c:224
static bool namecheck(const char *name)
Definition: zic.c:798

◆ is32()

static bool is32 ( const zic_t  x)
static

Definition at line 1939 of file zic.c.

Referenced by writezone().

1940 {
1941  return x == ((zic_t) ((int32) x));
1942 }
signed int int32
Definition: c.h:313
int64 zic_t
Definition: zic.c:23

◆ is_alpha()

static bool is_alpha ( char  a)
static

Definition at line 3301 of file zic.c.

Referenced by doabbr(), and newabbr().

3302 {
3303  switch (a)
3304  {
3305  default:
3306  return false;
3307  case 'A':
3308  case 'B':
3309  case 'C':
3310  case 'D':
3311  case 'E':
3312  case 'F':
3313  case 'G':
3314  case 'H':
3315  case 'I':
3316  case 'J':
3317  case 'K':
3318  case 'L':
3319  case 'M':
3320  case 'N':
3321  case 'O':
3322  case 'P':
3323  case 'Q':
3324  case 'R':
3325  case 'S':
3326  case 'T':
3327  case 'U':
3328  case 'V':
3329  case 'W':
3330  case 'X':
3331  case 'Y':
3332  case 'Z':
3333  case 'a':
3334  case 'b':
3335  case 'c':
3336  case 'd':
3337  case 'e':
3338  case 'f':
3339  case 'g':
3340  case 'h':
3341  case 'i':
3342  case 'j':
3343  case 'k':
3344  case 'l':
3345  case 'm':
3346  case 'n':
3347  case 'o':
3348  case 'p':
3349  case 'q':
3350  case 'r':
3351  case 's':
3352  case 't':
3353  case 'u':
3354  case 'v':
3355  case 'w':
3356  case 'x':
3357  case 'y':
3358  case 'z':
3359  return true;
3360  }
3361 }

◆ is_space()

static bool is_space ( char  a)
static

Definition at line 3283 of file zic.c.

Referenced by getfields().

3284 {
3285  switch (a)
3286  {
3287  default:
3288  return false;
3289  case ' ':
3290  case '\f':
3291  case '\n':
3292  case '\r':
3293  case '\t':
3294  case '\v':
3295  return true;
3296  }
3297 }

◆ itsabbr()

static bool itsabbr ( const char *  abbr,
const char *  word 
)
static

Definition at line 3438 of file zic.c.

References lowerit(), and word().

Referenced by byword().

3439 {
3440  if (lowerit(*abbr) != lowerit(*word))
3441  return false;
3442  ++word;
3443  while (*++abbr != '\0')
3444  do
3445  {
3446  if (*word == '\0')
3447  return false;
3448  } while (lowerit(*word++) != lowerit(*abbr));
3449  return true;
3450 }
static char lowerit(char)
Definition: zic.c:3366
static void word(struct vars *, int, struct state *, struct state *)
Definition: regcomp.c:1244

◆ itsdir()

static bool itsdir ( char const *  name)
static

Definition at line 1045 of file zic.c.

References emalloc(), EOVERFLOW, free, S_ISDIR, and stat.

Referenced by dolink(), and mkdirs().

1046 {
1047  struct stat st;
1048  int res = stat(name, &st);
1049 #ifdef S_ISDIR
1050  if (res == 0)
1051  return S_ISDIR(st.st_mode) != 0;
1052 #endif
1053  if (res == 0 || errno == EOVERFLOW)
1054  {
1055  size_t n = strlen(name);
1056  char *nameslashdot = emalloc(n + 3);
1057  bool dir;
1058 
1059  memcpy(nameslashdot, name, n);
1060  strcpy(&nameslashdot[n], &"/."[!(n && name[n - 1] != '/')]);
1061  dir = stat(nameslashdot, &st) == 0 || errno == EOVERFLOW;
1062  free(nameslashdot);
1063  return dir;
1064  }
1065  return false;
1066 }
#define stat(a, b)
Definition: win32_port.h:266
#define free(a)
Definition: header.h:65
const char * name
Definition: encode.c:521
#define S_ISDIR(m)
Definition: win32_port.h:307
#define EOVERFLOW
Definition: private.h:38
static void * emalloc(size_t size)
Definition: zic.c:427

◆ itssymlink()

static bool itssymlink ( char const *  name)
static

Definition at line 1070 of file zic.c.

References readlink.

Referenced by dolink().

1071 {
1072 #ifdef HAVE_SYMLINK
1073  char c;
1074 
1075  return 0 <= readlink(name, &c, 1);
1076 #else
1077  return false;
1078 #endif
1079 }
char * c
#define readlink(path, buf, size)
Definition: win32_port.h:233
const char * name
Definition: encode.c:521

◆ leapadd()

static void leapadd ( zic_t  t,
bool  positive,
int  rolling,
int  count 
)
static

Definition at line 3182 of file zic.c.

References _, error(), EXIT_FAILURE, i, leapcnt, and TZ_MAX_LEAPS.

Referenced by inleap().

3183 {
3184  int i,
3185  j;
3186 
3187  if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS)
3188  {
3189  error(_("too many leap seconds"));
3190  exit(EXIT_FAILURE);
3191  }
3192  for (i = 0; i < leapcnt; ++i)
3193  if (t <= trans[i])
3194  break;
3195  do
3196  {
3197  for (j = leapcnt; j > i; --j)
3198  {
3199  trans[j] = trans[j - 1];
3200  corr[j] = corr[j - 1];
3201  roll[j] = roll[j - 1];
3202  }
3203  trans[i] = t;
3204  corr[i] = positive ? 1 : -count;
3205  roll[i] = rolling;
3206  ++leapcnt;
3207  } while (positive && --count != 0);
3208 }
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:396
#define TZ_MAX_LEAPS
Definition: tzfile.h:101
static int leapcnt
Definition: zic.c:177
static zic_t trans[TZ_MAX_LEAPS]
Definition: zic.c:395
int i
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84
static char roll[TZ_MAX_LEAPS]
Definition: zic.c:397

◆ link()

int link ( const char *  fromname,
const char *  toname 
)

◆ lowerit()

static char lowerit ( char  a)
static

Definition at line 3366 of file zic.c.

Referenced by ciequal(), ciprefix(), itsabbr(), and rulesub().

3367 {
3368  switch (a)
3369  {
3370  default:
3371  return a;
3372  case 'A':
3373  return 'a';
3374  case 'B':
3375  return 'b';
3376  case 'C':
3377  return 'c';
3378  case 'D':
3379  return 'd';
3380  case 'E':
3381  return 'e';
3382  case 'F':
3383  return 'f';
3384  case 'G':
3385  return 'g';
3386  case 'H':
3387  return 'h';
3388  case 'I':
3389  return 'i';
3390  case 'J':
3391  return 'j';
3392  case 'K':
3393  return 'k';
3394  case 'L':
3395  return 'l';
3396  case 'M':
3397  return 'm';
3398  case 'N':
3399  return 'n';
3400  case 'O':
3401  return 'o';
3402  case 'P':
3403  return 'p';
3404  case 'Q':
3405  return 'q';
3406  case 'R':
3407  return 'r';
3408  case 'S':
3409  return 's';
3410  case 'T':
3411  return 't';
3412  case 'U':
3413  return 'u';
3414  case 'V':
3415  return 'v';
3416  case 'W':
3417  return 'w';
3418  case 'X':
3419  return 'x';
3420  case 'Y':
3421  return 'y';
3422  case 'Z':
3423  return 'z';
3424  }
3425 }

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 581 of file zic.c.

References _, adjleap(), associate(), change_directory(), close_file(), dolink(), eat(), EXIT_FAILURE, EXIT_SUCCESS, getopt(), i, infile(), nlinks, nzones, optarg, optind, outzone(), S_IWGRP, S_IWOTH, TYPE_BIT, TZDEFAULT, TZDEFRULES, usage(), warning(), and zone::z_name.

582 {
583  int c,
584  k;
585  ptrdiff_t i,
586  j;
587 
588 #ifndef WIN32
589  umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
590 #endif
591  progname = argv[0];
592  if (TYPE_BIT(zic_t) <64)
593  {
594  fprintf(stderr, "%s: %s\n", progname,
595  _("wild compilation-time specification of zic_t"));
596  return EXIT_FAILURE;
597  }
598  for (k = 1; k < argc; k++)
599  if (strcmp(argv[k], "--version") == 0)
600  {
601  printf("zic %s\n", PG_VERSION);
602  close_file(stdout, NULL, NULL);
603  return EXIT_SUCCESS;
604  }
605  else if (strcmp(argv[k], "--help") == 0)
606  {
607  usage(stdout, EXIT_SUCCESS);
608  }
609  while ((c = getopt(argc, argv, "d:l:L:p:Pst:vy:")) != EOF && c != -1)
610  switch (c)
611  {
612  default:
613  usage(stderr, EXIT_FAILURE);
614  case 'd':
615  if (directory == NULL)
616  directory = strdup(optarg);
617  else
618  {
619  fprintf(stderr,
620  _("%s: More than one -d option specified\n"),
621  progname);
622  return EXIT_FAILURE;
623  }
624  break;
625  case 'l':
626  if (lcltime == NULL)
627  lcltime = strdup(optarg);
628  else
629  {
630  fprintf(stderr,
631  _("%s: More than one -l option specified\n"),
632  progname);
633  return EXIT_FAILURE;
634  }
635  break;
636  case 'p':
637  if (psxrules == NULL)
638  psxrules = strdup(optarg);
639  else
640  {
641  fprintf(stderr,
642  _("%s: More than one -p option specified\n"),
643  progname);
644  return EXIT_FAILURE;
645  }
646  break;
647  case 't':
648  if (tzdefault != NULL)
649  {
650  fprintf(stderr,
651  _("%s: More than one -t option"
652  " specified\n"),
653  progname);
654  return EXIT_FAILURE;
655  }
656  tzdefault = optarg;
657  break;
658  case 'y':
659  if (yitcommand == NULL)
660  {
661  warning(_("-y is obsolescent"));
662  yitcommand = strdup(optarg);
663  }
664  else
665  {
666  fprintf(stderr,
667  _("%s: More than one -y option specified\n"),
668  progname);
669  return EXIT_FAILURE;
670  }
671  break;
672  case 'L':
673  if (leapsec == NULL)
674  leapsec = strdup(optarg);
675  else
676  {
677  fprintf(stderr,
678  _("%s: More than one -L option specified\n"),
679  progname);
680  return EXIT_FAILURE;
681  }
682  break;
683  case 'v':
684  noise = true;
685  break;
686  case 'P':
687  print_abbrevs = true;
688  print_cutoff = time(NULL);
689  break;
690  case 's':
691  warning(_("-s ignored"));
692  break;
693  }
694  if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
695  usage(stderr, EXIT_FAILURE); /* usage message by request */
696  if (directory == NULL)
697  directory = "data";
698  if (tzdefault == NULL)
700  if (yitcommand == NULL)
701  yitcommand = "yearistype";
702 
703  if (optind < argc && leapsec != NULL)
704  {
705  infile(leapsec);
706  adjleap();
707  }
708 
709  for (k = optind; k < argc; k++)
710  infile(argv[k]);
711  if (errors)
712  return EXIT_FAILURE;
713  associate();
715  for (i = 0; i < nzones; i = j)
716  {
717  /*
718  * Find the next non-continuation zone entry.
719  */
720  for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
721  continue;
722  outzone(&zones[i], j - i);
723  }
724 
725  /*
726  * Make links.
727  */
728  for (i = 0; i < nlinks; ++i)
729  {
730  eat(links[i].l_filename, links[i].l_linenum);
731  dolink(links[i].l_from, links[i].l_to, false);
732  if (noise)
733  for (j = 0; j < nlinks; ++j)
734  if (strcmp(links[i].l_to,
735  links[j].l_from) == 0)
736  warning(_("link to link"));
737  }
738  if (lcltime != NULL)
739  {
740  eat(_("command line"), 1);
741  dolink(lcltime, tzdefault, true);
742  }
743  if (psxrules != NULL)
744  {
745  eat(_("command line"), 1);
746  dolink(psxrules, TZDEFRULES, true);
747  }
748  if (warnings && (ferror(stderr) || fclose(stderr) != 0))
749  return EXIT_FAILURE;
750  return errors ? EXIT_FAILURE : EXIT_SUCCESS;
751 }
#define TZDEFAULT
Definition: tzfile.h:24
static ptrdiff_t nlinks
Definition: zic.c:294
static bool print_abbrevs
Definition: zic.c:187
static zic_t print_cutoff
Definition: zic.c:188
static void change_directory(char const *dir)
Definition: zic.c:553
#define EXIT_SUCCESS
Definition: settings.h:148
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
static bool errors
Definition: zic.c:174
static void associate(void)
Definition: zic.c:1097
#define S_IWOTH
Definition: win32_port.h:298
static ptrdiff_t nzones
Definition: zic.c:282
static const char * yitcommand
Definition: zic.c:578
static bool warnings
Definition: zic.c:175
static const char * leapsec
Definition: zic.c:576
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: getopt.c:72
static const char * psxrules
Definition: zic.c:573
static void static void static void static void usage(FILE *stream, int status) pg_attribute_noreturn()
Definition: zic.c:536
static void dolink(const char *, const char *, bool)
Definition: zic.c:899
int optind
Definition: getopt.c:51
char * c
static void adjleap(void)
Definition: zic.c:3211
static const char * lcltime
Definition: zic.c:574
int64 zic_t
Definition: zic.c:23
#define S_IWGRP
Definition: win32_port.h:286
static void eat(char const *name, lineno_t num)
Definition: zic.c:475
static bool noise
Definition: zic.c:186
static struct link * links
Definition: zic.c:293
static void infile(const char *filename)
Definition: zic.c:1182
static const char * progname
Definition: zic.c:191
#define TZDEFRULES
Definition: tzfile.h:25
static const char * directory
Definition: zic.c:575
const char * z_name
Definition: zic.c:103
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:520
static struct zone * zones
Definition: zic.c:281
static void outzone(const struct zone *zp, ptrdiff_t ntzones)
Definition: zic.c:2730
char * optarg
Definition: getopt.c:53
#define TYPE_BIT(type)
Definition: private.h:49
int i
#define EXIT_FAILURE
Definition: settings.h:152
static const char * tzdefault
Definition: zic.c:577
#define _(x)
Definition: elog.c:84

◆ memcheck()

static void* memcheck ( void *  ptr)
static

Definition at line 419 of file zic.c.

References memory_exhausted(), and strerror().

Referenced by ecpyalloc(), emalloc(), and erealloc().

420 {
421  if (ptr == NULL)
422  memory_exhausted(strerror(errno));
423  return ptr;
424 }
const char * strerror(int errnum)
Definition: strerror.c:19
static void memory_exhausted(const char *msg) pg_attribute_noreturn()
Definition: zic.c:404

◆ memory_exhausted()

static void memory_exhausted ( const char *  msg)
static

Definition at line 404 of file zic.c.

References _, and EXIT_FAILURE.

Referenced by growalloc(), memcheck(), and size_product().

405 {
406  fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, msg);
407  exit(EXIT_FAILURE);
408 }
static const char * progname
Definition: zic.c:191
#define EXIT_FAILURE
Definition: settings.h:152
#define _(x)
Definition: elog.c:84

◆ mkdirs()

static void mkdirs ( char const *  argname,
bool  ancestors 
)
static

Definition at line 3752 of file zic.c.

References _, _dosmaperr(), ecpyalloc(), error(), EXIT_FAILURE, free, itsdir(), link(), mkdir, MKDIR_UMASK, name, and strerror().

Referenced by change_directory(), dolink(), and writezone().

3753 {
3754  char *name;
3755  char *cp;
3756 
3757  cp = name = ecpyalloc(argname);
3758 
3759  /*
3760  * On MS-Windows systems, do not worry about drive letters or backslashes,
3761  * as this should suffice in practice. Time zone names do not use drive
3762  * letters and backslashes. If the -d option of zic does not name an
3763  * already-existing directory, it can use slashes to separate the
3764  * already-existing ancestor prefix from the to-be-created subdirectories.
3765  */
3766 
3767  /* Do not mkdir a root directory, as it must exist. */
3768  while (*cp == '/')
3769  cp++;
3770 
3771  while (cp && ((cp = strchr(cp, '/')) || !ancestors))
3772  {
3773  if (cp)
3774  *cp = '\0';
3775 
3776  /*
3777  * Try to create it. It's OK if creation fails because the directory
3778  * already exists, perhaps because some other process just created it.
3779  * For simplicity do not check first whether it already exists, as
3780  * that is checked anyway if the mkdir fails.
3781  */
3782  if (mkdir(name, MKDIR_UMASK) != 0)
3783  {
3784  /*
3785  * For speed, skip itsdir if errno == EEXIST. Since mkdirs is
3786  * called only after open fails with ENOENT on a subfile, EEXIST
3787  * implies itsdir here.
3788  */
3789  int err = errno;
3790 
3791  if (err != EEXIST && !itsdir(name))
3792  {
3793  error(_("%s: Cannot create directory %s: %s"),
3794  progname, name, strerror(err));
3795  exit(EXIT_FAILURE);
3796  }
3797  }
3798  if (cp)
3799  *cp++ = '/';
3800  }
3801  free(name);
3802 }
static char * ecpyalloc(char const *str)
Definition: zic.c:439
static bool itsdir(char const *)
Definition: zic.c:1045
static const char * progname
Definition: zic.c:191
#define free(a)
Definition: header.h:65
#define MKDIR_UMASK
Definition: zic.c:35
const char * name
Definition: encode.c:521
const char * strerror(int errnum)
Definition: strerror.c:19
#define EXIT_FAILURE
Definition: settings.h:152
#define mkdir(a, b)
Definition: win32_port.h:58
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84

◆ namecheck()

static bool namecheck ( const char *  name)
static

Definition at line 798 of file zic.c.

References _, componentcheck(), emalloc(), i, memmove, name, SIZE_MAX, and warning().

Referenced by inlink(), and inzsub().

799 {
800  char const *cp;
801 
802  /* Benign characters in a portable file name. */
803  static char const benign[] =
804  "-/_"
805  "abcdefghijklmnopqrstuvwxyz"
806  "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
807 
808  /*
809  * Non-control chars in the POSIX portable character set, excluding the
810  * benign characters.
811  */
812  static char const printable_and_not_benign[] =
813  " !\"#$%&'()*+,.0123456789:;<=>?@[\\]^`{|}~";
814 
815  char const *component = name;
816 
817  for (cp = name; *cp; cp++)
818  {
819  unsigned char c = *cp;
820 
821  if (noise && !strchr(benign, c))
822  {
823  warning((strchr(printable_and_not_benign, c)
824  ? _("file name '%s' contains byte '%c'")
825  : _("file name '%s' contains byte '\\%o'")),
826  name, c);
827  }
828  if (c == '/')
829  {
830  if (!componentcheck(name, component, cp))
831  return false;
832  component = cp + 1;
833  }
834  }
835  return componentcheck(name, component, cp);
836 }
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
static bool componentcheck(char const *name, char const *component, char const *component_end)
Definition: zic.c:754
char * c
static bool noise
Definition: zic.c:186
const char * name
Definition: encode.c:521
#define _(x)
Definition: elog.c:84

◆ newabbr()

static void newabbr ( const char *  abbr)
static

Definition at line 3714 of file zic.c.

References _, error(), EXIT_FAILURE, GRANDPARENTED, i, is_alpha(), TZ_MAX_CHARS, warning(), and ZIC_MAX_ABBR_LEN_WO_WARN.

Referenced by addtype().

3715 {
3716  int i;
3717 
3718  if (strcmp(string, GRANDPARENTED) != 0)
3719  {
3720  const char *cp;
3721  const char *mp;
3722 
3723  cp = string;
3724  mp = NULL;
3725  while (is_alpha(*cp) || ('0' <= *cp && *cp <= '9')
3726  || *cp == '-' || *cp == '+')
3727  ++cp;
3728  if (noise && cp - string < 3)
3729  mp = _("time zone abbreviation has fewer than 3 characters");
3730  if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN)
3731  mp = _("time zone abbreviation has too many characters");
3732  if (*cp != '\0')
3733  mp = _("time zone abbreviation differs from POSIX standard");
3734  if (mp != NULL)
3735  warning("%s (%s)", mp, string);
3736  }
3737  i = strlen(string) + 1;
3738  if (charcnt + i > TZ_MAX_CHARS)
3739  {
3740  error(_("too many, or too long, time zone abbreviations"));
3741  exit(EXIT_FAILURE);
3742  }
3743  strcpy(&chars[charcnt], string);
3744  charcnt += i;
3745 }
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
#define GRANDPARENTED
Definition: private.h:27
static bool is_alpha(char a)
Definition: zic.c:3301
char string[11]
Definition: preproc-type.c:46
#define ZIC_MAX_ABBR_LEN_WO_WARN
Definition: zic.c:28
#define TZ_MAX_CHARS
Definition: tzfile.h:98
static bool noise
Definition: zic.c:186
static int charcnt
Definition: zic.c:173
int i
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
static char chars[TZ_MAX_CHARS]
Definition: zic.c:394
#define _(x)
Definition: elog.c:84

◆ oadd()

static zic_t oadd ( zic_t  t1,
zic_t  t2 
)
static

Definition at line 3579 of file zic.c.

References time_overflow(), ZIC_MAX, and ZIC_MIN.

Referenced by gethms(), inleap(), outzone(), and rpytime().

3580 {
3581  if (t1 < 0 ? t2 < ZIC_MIN - t1 : ZIC_MAX - t1 < t2)
3582  time_overflow();
3583  return t1 + t2;
3584 }
#define ZIC_MAX
Definition: zic.c:25
#define ZIC_MIN
Definition: zic.c:24
static void time_overflow(void)
Definition: zic.c:3572

◆ outzone()

static void outzone ( const struct zone zp,
ptrdiff_t  ntzones 
)
static

Definition at line 2730 of file zic.c.

References _, addtt(), addtype(), attype::at, attypes, compat, DC_DOM, doabbr(), attype::dontmerge, eat(), eats(), emalloc(), EPOCH_YEAR, error(), free, i, INITIALIZE, max_abbrvar_len, max_year, oadd(), rule::r_abbrvar, rule::r_dayofmonth, rule::r_dycode, rule::r_filename, rule::r_hiwasnum, rule::r_hiyear, rule::r_isdst, rule::r_linenum, rule::r_lowasnum, rule::r_loyear, rule::r_month, rule::r_stdoff, rule::r_temp, rule::r_tod, rule::r_todisgmt, rule::r_todisstd, rule::r_todo, rule::r_yrtype, rpytime(), stringzone(), tadd(), timecnt, TM_JANUARY, generate_unaccent_rules::type, updateminmax(), warning(), writezone(), YEAR_BY_YEAR_ZONE, yearistype(), YEARSPERREPEAT, zone::z_filename, zone::z_format, zone::z_gmtoff, zone::z_isdst, zone::z_linenum, zone::z_name, zone::z_nrules, zone::z_rules, zone::z_stdoff, zone::z_untilrule, zone::z_untiltime, ZIC_MAX, ZIC_MIN, ZIC_VERSION, and ZIC_VERSION_PRE_2013.

Referenced by main().

2731 {
2732  const struct zone *zp;
2733  struct rule *rp;
2734  ptrdiff_t i,
2735  j;
2736  bool usestart,
2737  useuntil;
2738  zic_t starttime,
2739  untiltime;
2740  zic_t gmtoff;
2741  zic_t stdoff;
2742  zic_t year;
2743  zic_t startoff;
2744  bool startttisstd;
2745  bool startttisgmt;
2746  int type;
2747  char *startbuf;
2748  char *ab;
2749  char *envvar;
2750  int max_abbr_len;
2751  int max_envvar_len;
2752  bool prodstic; /* all rules are min to max */
2753  int compat;
2754  bool do_extend;
2755  char version;
2756  ptrdiff_t lastatmax = -1;
2757  zic_t one = 1;
2758  zic_t y2038_boundary = one << 31;
2759  zic_t max_year0;
2760 
2761  max_abbr_len = 2 + max_format_len + max_abbrvar_len;
2762  max_envvar_len = 2 * max_abbr_len + 5 * 9;
2763  startbuf = emalloc(max_abbr_len + 1);
2764  ab = emalloc(max_abbr_len + 1);
2765  envvar = emalloc(max_envvar_len + 1);
2766  INITIALIZE(untiltime);
2767  INITIALIZE(starttime);
2768 
2769  /*
2770  * Now. . .finally. . .generate some useful data!
2771  */
2772  timecnt = 0;
2773  typecnt = 0;
2774  charcnt = 0;
2775  prodstic = zonecount == 1;
2776 
2777  /*
2778  * Thanks to Earl Chew for noting the need to unconditionally initialize
2779  * startttisstd.
2780  */
2781  startttisstd = false;
2782  startttisgmt = false;
2784  if (leapseen)
2785  {
2788  }
2789  for (i = 0; i < zonecount; ++i)
2790  {
2791  zp = &zpfirst[i];
2792  if (i < zonecount - 1)
2794  for (j = 0; j < zp->z_nrules; ++j)
2795  {
2796  rp = &zp->z_rules[j];
2797  if (rp->r_lowasnum)
2798  updateminmax(rp->r_loyear);
2799  if (rp->r_hiwasnum)
2800  updateminmax(rp->r_hiyear);
2801  if (rp->r_lowasnum || rp->r_hiwasnum)
2802  prodstic = false;
2803  }
2804  }
2805 
2806  /*
2807  * Generate lots of data if a rule can't cover all future times.
2808  */
2809  compat = stringzone(envvar, zpfirst, zonecount);
2810  version = compat < 2013 ? ZIC_VERSION_PRE_2013 : ZIC_VERSION;
2811  do_extend = compat < 0 || compat == YEAR_BY_YEAR_ZONE;
2812  if (noise)
2813  {
2814  if (!*envvar)
2815  warning("%s %s",
2816  _("no POSIX environment variable for zone"),
2817  zpfirst->z_name);
2818  else if (compat != 0 && compat != YEAR_BY_YEAR_ZONE)
2819  {
2820  /*
2821  * Circa-COMPAT clients, and earlier clients, might not work for
2822  * this zone when given dates before 1970 or after 2038.
2823  */
2824  warning(_("%s: pre-%d clients may mishandle"
2825  " distant timestamps"),
2826  zpfirst->z_name, compat);
2827  }
2828  }
2829  if (do_extend)
2830  {
2831  /*
2832  * Search through a couple of extra years past the obvious 400, to
2833  * avoid edge cases. For example, suppose a non-POSIX rule applies
2834  * from 2012 onwards and has transitions in March and September, plus
2835  * some one-off transitions in November 2013. If zic looked only at
2836  * the last 400 years, it would set max_year=2413, with the intent
2837  * that the 400 years 2014 through 2413 will be repeated. The last
2838  * transition listed in the tzfile would be in 2413-09, less than 400
2839  * years after the last one-off transition in 2013-11. Two years
2840  * might be overkill, but with the kind of edge cases available we're
2841  * not sure that one year would suffice.
2842  */
2843  enum
2844  {
2845  years_of_observations = YEARSPERREPEAT + 2};
2846 
2847  if (min_year >= ZIC_MIN + years_of_observations)
2848  min_year -= years_of_observations;
2849  else
2850  min_year = ZIC_MIN;
2851  if (max_year <= ZIC_MAX - years_of_observations)
2852  max_year += years_of_observations;
2853  else
2854  max_year = ZIC_MAX;
2855 
2856  /*
2857  * Regardless of any of the above, for a "proDSTic" zone which
2858  * specifies that its rules always have and always will be in effect,
2859  * we only need one cycle to define the zone.
2860  */
2861  if (prodstic)
2862  {
2863  min_year = 1900;
2864  max_year = min_year + years_of_observations;
2865  }
2866  }
2867 
2868  /*
2869  * For the benefit of older systems, generate data from 1900 through 2038.
2870  */
2871  if (min_year > 1900)
2872  min_year = 1900;
2873  max_year0 = max_year;
2874  if (max_year < 2038)
2875  max_year = 2038;
2876  for (i = 0; i < zonecount; ++i)
2877  {
2878  /*
2879  * A guess that may well be corrected later.
2880  */
2881  stdoff = 0;
2882  zp = &zpfirst[i];
2883  usestart = i > 0 && (zp - 1)->z_untiltime > early_time;
2884  useuntil = i < (zonecount - 1);
2885  if (useuntil && zp->z_untiltime <= early_time)
2886  continue;
2887  gmtoff = zp->z_gmtoff;
2888  eat(zp->z_filename, zp->z_linenum);
2889  *startbuf = '\0';
2890  startoff = zp->z_gmtoff;
2891  if (zp->z_nrules == 0)
2892  {
2893  stdoff = zp->z_stdoff;
2894  doabbr(startbuf, zp, NULL, zp->z_isdst, stdoff, false);
2895  type = addtype(oadd(zp->z_gmtoff, stdoff),
2896  startbuf, zp->z_isdst, startttisstd,
2897  startttisgmt);
2898  if (usestart)
2899  {
2900  addtt(starttime, type);
2901  usestart = false;
2902  }
2903  else
2904  addtt(early_time, type);
2905  }
2906  else
2907  for (year = min_year; year <= max_year; ++year)
2908  {
2909  if (useuntil && year > zp->z_untilrule.r_hiyear)
2910  break;
2911 
2912  /*
2913  * Mark which rules to do in the current year. For those to
2914  * do, calculate rpytime(rp, year);
2915  */
2916  for (j = 0; j < zp->z_nrules; ++j)
2917  {
2918  rp = &zp->z_rules[j];
2919  eats(zp->z_filename, zp->z_linenum,
2920  rp->r_filename, rp->r_linenum);
2921  rp->r_todo = year >= rp->r_loyear &&
2922  year <= rp->r_hiyear &&
2923  yearistype(year, rp->r_yrtype);
2924  if (rp->r_todo)
2925  {
2926  rp->r_temp = rpytime(rp, year);
2927  rp->r_todo
2928  = (rp->r_temp < y2038_boundary
2929  || year <= max_year0);
2930  }
2931  }
2932  for (;;)
2933  {
2934  ptrdiff_t k;
2935  zic_t jtime,
2936  ktime;
2937  zic_t offset;
2938 
2939  INITIALIZE(ktime);
2940  if (useuntil)
2941  {
2942  /*
2943  * Turn untiltime into UT assuming the current gmtoff
2944  * and stdoff values.
2945  */
2946  untiltime = zp->z_untiltime;
2947  if (!zp->z_untilrule.r_todisgmt)
2948  untiltime = tadd(untiltime,
2949  -gmtoff);
2950  if (!zp->z_untilrule.r_todisstd)
2951  untiltime = tadd(untiltime,
2952  -stdoff);
2953  }
2954 
2955  /*
2956  * Find the rule (of those to do, if any) that takes
2957  * effect earliest in the year.
2958  */
2959  k = -1;
2960  for (j = 0; j < zp->z_nrules; ++j)
2961  {
2962  rp = &zp->z_rules[j];
2963  if (!rp->r_todo)
2964  continue;
2965  eats(zp->z_filename, zp->z_linenum,
2966  rp->r_filename, rp->r_linenum);
2967  offset = rp->r_todisgmt ? 0 : gmtoff;
2968  if (!rp->r_todisstd)
2969  offset = oadd(offset, stdoff);
2970  jtime = rp->r_temp;
2971  if (jtime == min_time ||
2972  jtime == max_time)
2973  continue;
2974  jtime = tadd(jtime, -offset);
2975  if (k < 0 || jtime < ktime)
2976  {
2977  k = j;
2978  ktime = jtime;
2979  }
2980  else if (jtime == ktime)
2981  {
2982  char const *dup_rules_msg =
2983  _("two rules for same instant");
2984 
2985  eats(zp->z_filename, zp->z_linenum,
2986  rp->r_filename, rp->r_linenum);
2987  warning("%s", dup_rules_msg);
2988  rp = &zp->z_rules[k];
2989  eats(zp->z_filename, zp->z_linenum,
2990  rp->r_filename, rp->r_linenum);
2991  error("%s", dup_rules_msg);
2992  }
2993  }
2994  if (k < 0)
2995  break; /* go on to next year */
2996  rp = &zp->z_rules[k];
2997  rp->r_todo = false;
2998  if (useuntil && ktime >= untiltime)
2999  break;
3000  stdoff = rp->r_stdoff;
3001  if (usestart && ktime == starttime)
3002  usestart = false;
3003  if (usestart)
3004  {
3005  if (ktime < starttime)
3006  {
3007  startoff = oadd(zp->z_gmtoff,
3008  stdoff);
3009  doabbr(startbuf, zp,
3010  rp->r_abbrvar,
3011  rp->r_isdst,
3012  rp->r_stdoff,
3013  false);
3014  continue;
3015  }
3016  if (*startbuf == '\0' &&
3017  startoff == oadd(zp->z_gmtoff,
3018  stdoff))
3019  {
3020  doabbr(startbuf,
3021  zp,
3022  rp->r_abbrvar,
3023  rp->r_isdst,
3024  rp->r_stdoff,
3025  false);
3026  }
3027  }
3028  eats(zp->z_filename, zp->z_linenum,
3029  rp->r_filename, rp->r_linenum);
3030  doabbr(ab, zp, rp->r_abbrvar,
3031  rp->r_isdst, rp->r_stdoff, false);
3032  offset = oadd(zp->z_gmtoff, rp->r_stdoff);
3033  type = addtype(offset, ab, rp->r_isdst,
3034  rp->r_todisstd, rp->r_todisgmt);
3035  if (rp->r_hiyear == ZIC_MAX
3036  && !(0 <= lastatmax
3037  && ktime < attypes[lastatmax].at))
3038  lastatmax = timecnt;
3039  addtt(ktime, type);
3040  }
3041  }
3042  if (usestart)
3043  {
3044  if (*startbuf == '\0' &&
3045  zp->z_format != NULL &&
3046  strchr(zp->z_format, '%') == NULL &&
3047  strchr(zp->z_format, '/') == NULL)
3048  strcpy(startbuf, zp->z_format);
3049  eat(zp->z_filename, zp->z_linenum);
3050  if (*startbuf == '\0')
3051  error(_("cannot determine time zone abbreviation to use just after until time"));
3052  else
3053  addtt(starttime,
3054  addtype(startoff, startbuf,
3055  startoff != zp->z_gmtoff,
3056  startttisstd,
3057  startttisgmt));
3058  }
3059 
3060  /*
3061  * Now we may get to set starttime for the next zone line.
3062  */
3063  if (useuntil)
3064  {
3065  startttisstd = zp->z_untilrule.r_todisstd;
3066  startttisgmt = zp->z_untilrule.r_todisgmt;
3067  starttime = zp->z_untiltime;
3068  if (!startttisstd)
3069  starttime = tadd(starttime, -stdoff);
3070  if (!startttisgmt)
3071  starttime = tadd(starttime, -gmtoff);
3072  }
3073  }
3074  if (0 <= lastatmax)
3075  attypes[lastatmax].dontmerge = true;
3076  if (do_extend)
3077  {
3078  /*
3079  * If we're extending the explicitly listed observations for 400 years
3080  * because we can't fill the POSIX-TZ field, check whether we actually
3081  * ended up explicitly listing observations through that period. If
3082  * there aren't any near the end of the 400-year period, add a
3083  * redundant one at the end of the final year, to make it clear that
3084  * we are claiming to have definite knowledge of the lack of
3085  * transitions up to that point.
3086  */
3087  struct rule xr;
3088  struct attype *lastat;
3089 
3090  xr.r_month = TM_JANUARY;
3091  xr.r_dycode = DC_DOM;
3092  xr.r_dayofmonth = 1;
3093  xr.r_tod = 0;
3094  for (lastat = &attypes[0], i = 1; i < timecnt; i++)
3095  if (attypes[i].at > lastat->at)
3096  lastat = &attypes[i];
3097  if (lastat->at < rpytime(&xr, max_year - 1))
3098  {
3099  addtt(rpytime(&xr, max_year + 1), typecnt - 1);
3100  attypes[timecnt - 1].dontmerge = true;
3101  }
3102  }
3103  writezone(zpfirst->z_name, envvar, version);
3104  free(startbuf);
3105  free(ab);
3106  free(envvar);
3107 }
static bool yearistype(zic_t year, const char *type)
Definition: zic.c:3248
static void writezone(const char *const name, const char *const string, char version)
Definition: zic.c:1945
static zic_t leapmaxyear
Definition: zic.c:180
lineno_t r_linenum
Definition: zic.c:62
static int typecnt
Definition: zic.c:194
static int stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
Definition: zic.c:2592
Definition: zic.c:383
bool r_todisstd
Definition: zic.c:78
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
static void addtt(zic_t starttime, int type)
Definition: zic.c:3110
#define INITIALIZE(x)
Definition: private.h:81
const char * z_format
Definition: zic.c:106
#define DC_DOM
Definition: zic.c:94
zic_t z_untiltime
Definition: zic.c:116
struct rule z_untilrule
Definition: zic.c:115
static zic_t min_year
Definition: zic.c:185
static size_t doabbr(char *abbr, struct zone const *zp, char const *letters, bool isdst, zic_t stdoff, bool doquotes)
Definition: zic.c:2406
static void updateminmax(const zic_t x)
Definition: zic.c:2449
static int max_format_len
Definition: zic.c:183
bool z_isdst
Definition: zic.c:109
Definition: localtime.c:77
static const zic_t early_time
Definition: zic.c:1039
bool r_lowasnum
Definition: zic.c:68
#define ZIC_MAX
Definition: zic.c:25
const char * z_filename
Definition: zic.c:100
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3587
static int addtype(zic_t, char const *, bool, bool, bool)
Definition: zic.c:3135
bool r_todo
Definition: zic.c:86
#define ZIC_VERSION_PRE_2013
Definition: zic.c:20
bool r_isdst
Definition: zic.c:81
static bool leapseen
Definition: zic.c:178
#define ZIC_VERSION
Definition: zic.c:21
static int max_abbrvar_len
Definition: zic.c:182
int64 zic_t
Definition: zic.c:23
zic_t r_hiyear
Definition: zic.c:66
const char * r_yrtype
Definition: zic.c:67
zic_t r_temp
Definition: zic.c:87
#define ZIC_MIN
Definition: zic.c:24
const char * r_filename
Definition: zic.c:61
enum COMPAT_MODE compat
Definition: ecpg.c:25
zic_t at
Definition: zic.c:385
#define EPOCH_YEAR
Definition: private.h:123
static zic_t rpytime(const struct rule *rp, zic_t wantedy)
Definition: zic.c:3616
static void eat(char const *name, lineno_t num)
Definition: zic.c:475
const char * r_abbrvar
Definition: zic.c:84
static struct attype * attypes
static zic_t const max_time
Definition: zic.c:999
static bool noise
Definition: zic.c:186
ptrdiff_t z_nrules
Definition: zic.c:113
#define TM_JANUARY
Definition: private.h:108
lineno_t z_linenum
Definition: zic.c:101
static zic_t max_year
Definition: zic.c:184
#define free(a)
Definition: header.h:65
zic_t r_stdoff
Definition: zic.c:82
zic_t z_gmtoff
Definition: zic.c:104
static ptrdiff_t timecnt
Definition: zic.c:192
static int charcnt
Definition: zic.c:173
static zic_t leapminyear
Definition: zic.c:179
#define YEARSPERREPEAT
Definition: private.h:88
struct rule * z_rules
Definition: zic.c:112
Definition: zic.c:98
bool r_hiwasnum
Definition: zic.c:69
int i
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
zic_t r_loyear
Definition: zic.c:65
bool r_todisgmt
Definition: zic.c:80
static zic_t const min_time
Definition: zic.c:998
bool dontmerge
Definition: zic.c:386
static void eats(char const *name, lineno_t num, char const *rname, lineno_t rnum)
Definition: zic.c:466
#define _(x)
Definition: elog.c:84
static zic_t oadd(zic_t t1, zic_t t2)
Definition: zic.c:3579
zic_t z_stdoff
Definition: zic.c:110
static void * emalloc(size_t size)
Definition: zic.c:427

◆ puttzcode()

static void puttzcode ( const int32  val,
FILE *const  fp 
)
static

Definition at line 1912 of file zic.c.

References buf, and convert().

Referenced by writezone().

1913 {
1914  char buf[4];
1915 
1916  convert(val, buf);
1917  fwrite(buf, sizeof buf, 1, fp);
1918 }
static void convert(const int32 val, char *const buf)
Definition: zic.c:1890
static char * buf
Definition: pg_test_fsync.c:67
long val
Definition: informix.c:689

◆ puttzcode64()

static void puttzcode64 ( const zic_t  val,
FILE *const  fp 
)
static

Definition at line 1921 of file zic.c.

References buf, and convert64().

Referenced by writezone().

1922 {
1923  char buf[8];
1924 
1925  convert64(val, buf);
1926  fwrite(buf, sizeof buf, 1, fp);
1927 }
static char * buf
Definition: pg_test_fsync.c:67
long val
Definition: informix.c:689
static void convert64(const zic_t val, char *const buf)
Definition: zic.c:1901

◆ rcomp()

static int rcomp ( const void *  cp1,
const void *  cp2 
)
static

Definition at line 1090 of file zic.c.

References rule::r_name.

Referenced by associate().

1091 {
1092  return strcmp(((const struct rule *) cp1)->r_name,
1093  ((const struct rule *) cp2)->r_name);
1094 }
Definition: localtime.c:77

◆ rpytime()

static zic_t rpytime ( const struct rule rp,
zic_t  wantedy 
)
static

Definition at line 3616 of file zic.c.

References _, DC_DOWGEQ, DC_DOWLEQ, EPOCH_WDAY, EPOCH_YEAR, error(), EXIT_FAILURE, i, isleap, LDAYSPERWEEK, max_time, min_time, oadd(), rule::r_dayofmonth, rule::r_dycode, rule::r_month, rule::r_tod, rule::r_wday, SECSPERDAY, tadd(), TM_FEBRUARY, TM_JANUARY, warning(), ZIC_MAX, and ZIC_MIN.

Referenced by inzsub(), and outzone().

3617 {
3618  int m,
3619  i;
3620  zic_t dayoff; /* with a nod to Margaret O. */
3621  zic_t t,
3622  y;
3623 
3624  if (wantedy == ZIC_MIN)
3625  return min_time;
3626  if (wantedy == ZIC_MAX)
3627  return max_time;
3628  dayoff = 0;
3629  m = TM_JANUARY;
3630  y = EPOCH_YEAR;
3631  while (wantedy != y)
3632  {
3633  if (wantedy > y)
3634  {
3635  i = len_years[isleap(y)];
3636  ++y;
3637  }
3638  else
3639  {
3640  --y;
3641  i = -len_years[isleap(y)];
3642  }
3643  dayoff = oadd(dayoff, i);
3644  }
3645  while (m != rp->r_month)
3646  {
3647  i = len_months[isleap(y)][m];
3648  dayoff = oadd(dayoff, i);
3649  ++m;
3650  }
3651  i = rp->r_dayofmonth;
3652  if (m == TM_FEBRUARY && i == 29 && !isleap(y))
3653  {
3654  if (rp->r_dycode == DC_DOWLEQ)
3655  --i;
3656  else
3657  {
3658  error(_("use of 2/29 in non leap-year"));
3659  exit(EXIT_FAILURE);
3660  }
3661  }
3662  --i;
3663  dayoff = oadd(dayoff, i);
3664  if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ)
3665  {
3666  zic_t wday;
3667 
3668 #define LDAYSPERWEEK ((zic_t) DAYSPERWEEK)
3669  wday = EPOCH_WDAY;
3670 
3671  /*
3672  * Don't trust mod of negative numbers.
3673  */
3674  if (dayoff >= 0)
3675  wday = (wday + dayoff) % LDAYSPERWEEK;
3676  else
3677  {
3678  wday -= ((-dayoff) % LDAYSPERWEEK);
3679  if (wday < 0)
3680  wday += LDAYSPERWEEK;
3681  }
3682  while (wday != rp->r_wday)
3683  if (rp->r_dycode == DC_DOWGEQ)
3684  {
3685  dayoff = oadd(dayoff, 1);
3686  if (++wday >= LDAYSPERWEEK)
3687  wday = 0;
3688  ++i;
3689  }
3690  else
3691  {
3692  dayoff = oadd(dayoff, -1);
3693  if (--wday < 0)
3694  wday = LDAYSPERWEEK - 1;
3695  --i;
3696  }
3697  if (i < 0 || i >= len_months[isleap(y)][m])
3698  {
3699  if (noise)
3700  warning(_("rule goes past start/end of month; \
3701 will not work with pre-2004 versions of zic"));
3702  }
3703  }
3704  if (dayoff < min_time / SECSPERDAY)
3705  return min_time;
3706  if (dayoff > max_time / SECSPERDAY)
3707  return max_time;
3708  t = (zic_t) dayoff * SECSPERDAY;
3709 
3710  return tadd(t, rp->r_tod);
3711 }
zic_t r_tod
Definition: zic.c:77
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
int r_month
Definition: zic.c:71
#define DC_DOWGEQ
Definition: zic.c:95
#define SECSPERDAY
Definition: private.h:97
#define isleap(y)
Definition: datetime.h:273
static const int len_months[2][MONSPERYEAR]
Definition: zic.c:374
#define ZIC_MAX
Definition: zic.c:25
#define LDAYSPERWEEK
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3587
int64 zic_t
Definition: zic.c:23
#define ZIC_MIN
Definition: zic.c:24
int r_dycode
Definition: zic.c:73
#define EPOCH_YEAR
Definition: private.h:123
#define DC_DOWLEQ
Definition: zic.c:96
static zic_t const max_time
Definition: zic.c:999
static bool noise
Definition: zic.c:186
#define TM_JANUARY
Definition: private.h:108
#define TM_FEBRUARY
Definition: private.h:109
int r_dayofmonth
Definition: zic.c:74
int r_wday
Definition: zic.c:75
#define EPOCH_WDAY
Definition: private.h:124
int i
#define EXIT_FAILURE
Definition: settings.h:152
static const int len_years[2]
Definition: zic.c:379
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
static zic_t const min_time
Definition: zic.c:998
#define _(x)
Definition: elog.c:84
static zic_t oadd(zic_t t1, zic_t t2)
Definition: zic.c:3579

◆ rule_cmp()

static int rule_cmp ( struct rule const *  a,
struct rule const *  b 
)
static

Definition at line 2574 of file zic.c.

References rule::r_dayofmonth, rule::r_hiyear, and rule::r_month.

Referenced by stringzone().

2575 {
2576  if (!a)
2577  return -!!b;
2578  if (!b)
2579  return 1;
2580  if (a->r_hiyear != b->r_hiyear)
2581  return a->r_hiyear < b->r_hiyear ? -1 : 1;
2582  if (a->r_month - b->r_month != 0)
2583  return a->r_month - b->r_month;
2584  return a->r_dayofmonth - b->r_dayofmonth;
2585 }

◆ rulesub()

static void rulesub ( struct rule rp,
const char *  loyearp,
const char *  hiyearp,
const char *  typep,
const char *  monthp,
const char *  dayp,
const char *  timep 
)
static

Definition at line 1714 of file zic.c.

References _, byword(), DC_DOM, DC_DOWGEQ, DC_DOWLEQ, ecpyalloc(), error(), EXIT_FAILURE, free, gethms(), lookup::l_value, lowerit(), rule::r_dayofmonth, rule::r_dycode, rule::r_hiwasnum, rule::r_hiyear, rule::r_lowasnum, rule::r_loyear, rule::r_month, rule::r_tod, rule::r_todisgmt, rule::r_todisstd, rule::r_wday, rule::r_yrtype, warning(), YR_MAXIMUM, YR_MINIMUM, YR_ONLY, ZIC_MAX, and ZIC_MIN.

Referenced by inrule(), and inzsub().

1717 {
1718  const struct lookup *lp;
1719  const char *cp;
1720  char *dp;
1721  char *ep;
1722  char xs;
1723 
1724  /* PG: year_tmp is to avoid sscanf portability issues */
1725  int year_tmp;
1726 
1727  if ((lp = byword(monthp, mon_names)) == NULL)
1728  {
1729  error(_("invalid month name"));
1730  return;
1731  }
1732  rp->r_month = lp->l_value;
1733  rp->r_todisstd = false;
1734  rp->r_todisgmt = false;
1735  dp = ecpyalloc(timep);
1736  if (*dp != '\0')
1737  {
1738  ep = dp + strlen(dp) - 1;
1739  switch (lowerit(*ep))
1740  {
1741  case 's': /* Standard */
1742  rp->r_todisstd = true;
1743  rp->r_todisgmt = false;
1744  *ep = '\0';
1745  break;
1746  case 'w': /* Wall */
1747  rp->r_todisstd = false;
1748  rp->r_todisgmt = false;
1749  *ep = '\0';
1750  break;
1751  case 'g': /* Greenwich */
1752  case 'u': /* Universal */
1753  case 'z': /* Zulu */
1754  rp->r_todisstd = true;
1755  rp->r_todisgmt = true;
1756  *ep = '\0';
1757  break;
1758  }
1759  }
1760  rp->r_tod = gethms(dp, _("invalid time of day"), false);
1761  free(dp);
1762 
1763  /*
1764  * Year work.
1765  */
1766  cp = loyearp;
1767  lp = byword(cp, begin_years);
1768  rp->r_lowasnum = lp == NULL;
1769  if (!rp->r_lowasnum)
1770  switch (lp->l_value)
1771  {
1772  case YR_MINIMUM:
1773  rp->r_loyear = ZIC_MIN;
1774  break;
1775  case YR_MAXIMUM:
1776  rp->r_loyear = ZIC_MAX;
1777  break;
1778  default: /* "cannot happen" */
1779  fprintf(stderr,
1780  _("%s: panic: Invalid l_value %d\n"),
1781  progname, lp->l_value);
1782  exit(EXIT_FAILURE);
1783  }
1784  else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
1785  rp->r_loyear = year_tmp;
1786  else
1787  {
1788  error(_("invalid starting year"));
1789  return;
1790  }
1791  cp = hiyearp;
1792  lp = byword(cp, end_years);
1793  rp->r_hiwasnum = lp == NULL;
1794  if (!rp->r_hiwasnum)
1795  switch (lp->l_value)
1796  {
1797  case YR_MINIMUM:
1798  rp->r_hiyear = ZIC_MIN;
1799  break;
1800  case YR_MAXIMUM:
1801  rp->r_hiyear = ZIC_MAX;
1802  break;
1803  case YR_ONLY:
1804  rp->r_hiyear = rp->r_loyear;
1805  break;
1806  default: /* "cannot happen" */
1807  fprintf(stderr,
1808  _("%s: panic: Invalid l_value %d\n"),
1809  progname, lp->l_value);
1810  exit(EXIT_FAILURE);
1811  }
1812  else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
1813  rp->r_hiyear = year_tmp;
1814  else
1815  {
1816  error(_("invalid ending year"));
1817  return;
1818  }
1819  if (rp->r_loyear > rp->r_hiyear)
1820  {
1821  error(_("starting year greater than ending year"));
1822  return;
1823  }
1824  if (*typep == '\0')
1825  rp->r_yrtype = NULL;
1826  else
1827  {
1828  if (rp->r_loyear == rp->r_hiyear)
1829  {
1830  error(_("typed single year"));
1831  return;
1832  }
1833  warning(_("year type \"%s\" is obsolete; use \"-\" instead"),
1834  typep);
1835  rp->r_yrtype = ecpyalloc(typep);
1836  }
1837 
1838  /*
1839  * Day work. Accept things such as: 1 lastSunday last-Sunday
1840  * (undocumented; warn about this) Sun<=20 Sun>=7
1841  */
1842  dp = ecpyalloc(dayp);
1843  if ((lp = byword(dp, lasts)) != NULL)
1844  {
1845  rp->r_dycode = DC_DOWLEQ;
1846  rp->r_wday = lp->l_value;
1847  rp->r_dayofmonth = len_months[1][rp->r_month];
1848  }
1849  else
1850  {
1851  if ((ep = strchr(dp, '<')) != NULL)
1852  rp->r_dycode = DC_DOWLEQ;
1853  else if ((ep = strchr(dp, '>')) != NULL)
1854  rp->r_dycode = DC_DOWGEQ;
1855  else
1856  {
1857  ep = dp;
1858  rp->r_dycode = DC_DOM;
1859  }
1860  if (rp->r_dycode != DC_DOM)
1861  {
1862  *ep++ = 0;
1863  if (*ep++ != '=')
1864  {
1865  error(_("invalid day of month"));
1866  free(dp);
1867  return;
1868  }
1869  if ((lp = byword(dp, wday_names)) == NULL)
1870  {
1871  error(_("invalid weekday name"));
1872  free(dp);
1873  return;
1874  }
1875  rp->r_wday = lp->l_value;
1876  }
1877  if (sscanf(ep, "%d%c", &rp->r_dayofmonth, &xs) != 1 ||
1878  rp->r_dayofmonth <= 0 ||
1879  (rp->r_dayofmonth > len_months[1][rp->r_month]))
1880  {
1881  error(_("invalid day of month"));
1882  free(dp);
1883  return;
1884  }
1885  }
1886  free(dp);
1887 }
#define YR_MINIMUM
Definition: zic.c:273
zic_t r_tod
Definition: zic.c:77
bool r_todisstd
Definition: zic.c:78
static char * ecpyalloc(char const *str)
Definition: zic.c:439
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
int r_month
Definition: zic.c:71
#define DC_DOWGEQ
Definition: zic.c:95
static struct lookup const begin_years[]
Definition: zic.c:355
#define DC_DOM
Definition: zic.c:94
static const int len_months[2][MONSPERYEAR]
Definition: zic.c:374
const int l_value
Definition: zic.c:300
bool r_lowasnum
Definition: zic.c:68
#define ZIC_MAX
Definition: zic.c:25
#define YR_ONLY
Definition: zic.c:275
static struct lookup const mon_names[]
Definition: zic.c:317
Definition: zic.c:297
zic_t r_hiyear
Definition: zic.c:66
const char * r_yrtype
Definition: zic.c:67
#define ZIC_MIN
Definition: zic.c:24
static struct lookup const end_years[]
Definition: zic.c:361
int r_dycode
Definition: zic.c:73
#define DC_DOWLEQ
Definition: zic.c:96
static zic_t gethms(const char *string, const char *errstring, bool)
Definition: zic.c:1285
static const char * progname
Definition: zic.c:191
#define free(a)
Definition: header.h:65
int r_dayofmonth
Definition: zic.c:74
int r_wday
Definition: zic.c:75
static struct lookup const * byword(const char *string, const struct lookup *lp)
Definition: zic.c:3466
static char lowerit(char)
Definition: zic.c:3366
#define YR_MAXIMUM
Definition: zic.c:274
static struct lookup const lasts[]
Definition: zic.c:344
bool r_hiwasnum
Definition: zic.c:69
static struct lookup const wday_names[]
Definition: zic.c:333
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
zic_t r_loyear
Definition: zic.c:65
bool r_todisgmt
Definition: zic.c:80
#define _(x)
Definition: elog.c:84

◆ shellquote()

static char* shellquote ( char *  b,
char const *  s 
)
static

Definition at line 3234 of file zic.c.

Referenced by yearistype().

3235 {
3236  *b++ = '\'';
3237  while (*s)
3238  {
3239  if (*s == '\'')
3240  *b++ = '\'', *b++ = '\\', *b++ = '\'';
3241  *b++ = *s++;
3242  }
3243  *b++ = '\'';
3244  return b;
3245 }

◆ size_product()

static size_t size_product ( size_t  nitems,
size_t  itemsize 
)
static

Definition at line 411 of file zic.c.

References _, memory_exhausted(), and SIZE_MAX.

Referenced by getfields(), growalloc(), and writezone().

412 {
413  if (SIZE_MAX / itemsize < nitems)
414  memory_exhausted(_("size overflow"));
415  return nitems * itemsize;
416 }
#define SIZE_MAX
Definition: c.h:419
static void memory_exhausted(const char *msg) pg_attribute_noreturn()
Definition: zic.c:404
#define _(x)
Definition: elog.c:84

◆ stringoffset()

static int stringoffset ( char *  result,
zic_t  offset 
)
static

Definition at line 2458 of file zic.c.

References DAYSPERWEEK, HOURSPERDAY, MINSPERHOUR, and SECSPERMIN.

Referenced by stringrule(), and stringzone().

2459 {
2460  int hours;
2461  int minutes;
2462  int seconds;
2463  bool negative = offset < 0;
2464  int len = negative;
2465 
2466  if (negative)
2467  {
2468  offset = -offset;
2469  result[0] = '-';
2470  }
2471  seconds = offset % SECSPERMIN;
2472  offset /= SECSPERMIN;
2473  minutes = offset % MINSPERHOUR;
2474  offset /= MINSPERHOUR;
2475  hours = offset;
2476  if (hours >= HOURSPERDAY * DAYSPERWEEK)
2477  {
2478  result[0] = '\0';
2479  return 0;
2480  }
2481  len += sprintf(result + len, "%d", hours);
2482  if (minutes != 0 || seconds != 0)
2483  {
2484  len += sprintf(result + len, ":%02d", minutes);
2485  if (seconds != 0)
2486  len += sprintf(result + len, ":%02d", seconds);
2487  }
2488  return len;
2489 }
#define SECSPERMIN
Definition: private.h:90
#define HOURSPERDAY
Definition: private.h:92
#define DAYSPERWEEK
Definition: private.h:93
#define MINSPERHOUR
Definition: private.h:91

◆ stringrule()

static int stringrule ( char *  result,
const struct rule *const  rp,
const zic_t  dstoff,
const zic_t  gmtoff 
)
static

Definition at line 2492 of file zic.c.

References compat, DAYSPERWEEK, DC_DOM, DC_DOWGEQ, DC_DOWLEQ, MINSPERHOUR, rule::r_dayofmonth, rule::r_dycode, rule::r_isdst, rule::r_month, rule::r_tod, rule::r_todisgmt, rule::r_todisstd, rule::r_wday, SECSPERDAY, SECSPERMIN, stringoffset(), and TM_FEBRUARY.

Referenced by stringzone().

2494 {
2495  zic_t tod = rp->r_tod;
2496  int compat = 0;
2497 
2498  if (rp->r_dycode == DC_DOM)
2499  {
2500  int month,
2501  total;
2502 
2503  if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY)
2504  return -1;
2505  total = 0;
2506  for (month = 0; month < rp->r_month; ++month)
2507  total += len_months[0][month];
2508  /* Omit the "J" in Jan and Feb, as that's shorter. */
2509  if (rp->r_month <= 1)
2510  result += sprintf(result, "%d", total + rp->r_dayofmonth - 1);
2511  else
2512  result += sprintf(result, "J%d", total + rp->r_dayofmonth);
2513  }
2514  else
2515  {
2516  int week;
2517  int wday = rp->r_wday;
2518  int wdayoff;
2519 
2520  if (rp->r_dycode == DC_DOWGEQ)
2521  {
2522  wdayoff = (rp->r_dayofmonth - 1) % DAYSPERWEEK;
2523  if (wdayoff)
2524  compat = 2013;
2525  wday -= wdayoff;
2526  tod += wdayoff * SECSPERDAY;
2527  week = 1 + (rp->r_dayofmonth - 1) / DAYSPERWEEK;
2528  }
2529  else if (rp->r_dycode == DC_DOWLEQ)
2530  {
2531  if (rp->r_dayofmonth == len_months[1][rp->r_month])
2532  week = 5;
2533  else
2534  {
2535  wdayoff = rp->r_dayofmonth % DAYSPERWEEK;
2536  if (wdayoff)
2537  compat = 2013;
2538  wday -= wdayoff;
2539  tod += wdayoff * SECSPERDAY;
2540  week = rp->r_dayofmonth / DAYSPERWEEK;
2541  }
2542  }
2543  else
2544  return -1; /* "cannot happen" */
2545  if (wday < 0)
2546  wday += DAYSPERWEEK;
2547  result += sprintf(result, "M%d.%d.%d",
2548  rp->r_month + 1, week, wday);
2549  }
2550  if (rp->r_todisgmt)
2551  tod += gmtoff;
2552  if (rp->r_todisstd && !rp->r_isdst)
2553  tod += dstoff;
2554  if (tod != 2 * SECSPERMIN * MINSPERHOUR)
2555  {
2556  *result++ = '/';
2557  if (!stringoffset(result, tod))
2558  return -1;
2559  if (tod < 0)
2560  {
2561  if (compat < 2013)
2562  compat = 2013;
2563  }
2564  else if (SECSPERDAY <= tod)
2565  {
2566  if (compat < 1994)
2567  compat = 1994;
2568  }
2569  }
2570  return compat;
2571 }
#define SECSPERMIN
Definition: private.h:90
zic_t r_tod
Definition: zic.c:77
bool r_todisstd
Definition: zic.c:78
int r_month
Definition: zic.c:71
#define DC_DOWGEQ
Definition: zic.c:95
#define SECSPERDAY
Definition: private.h:97
#define DC_DOM
Definition: zic.c:94
static const int len_months[2][MONSPERYEAR]
Definition: zic.c:374
static int stringoffset(char *result, zic_t offset)
Definition: zic.c:2458
#define DAYSPERWEEK
Definition: private.h:93
bool r_isdst
Definition: zic.c:81
int64 zic_t
Definition: zic.c:23
enum COMPAT_MODE compat
Definition: ecpg.c:25
int r_dycode
Definition: zic.c:73
#define DC_DOWLEQ
Definition: zic.c:96
#define TM_FEBRUARY
Definition: private.h:109
int r_dayofmonth
Definition: zic.c:74
int r_wday
Definition: zic.c:75
bool r_todisgmt
Definition: zic.c:80
#define MINSPERHOUR
Definition: private.h:91

◆ stringzone()

static int stringzone ( char *  result,
struct zone const *  zpfirst,
ptrdiff_t  zonecount 
)
static

Definition at line 2592 of file zic.c.

References compat, DC_DOM, doabbr(), i, MINSPERHOUR, rule::r_abbrvar, rule::r_dayofmonth, rule::r_dycode, rule::r_hiwasnum, rule::r_hiyear, rule::r_isdst, rule::r_month, rule::r_stdoff, rule::r_tod, rule::r_todisgmt, rule::r_todisstd, rule::r_yrtype, rule_cmp(), SECSPERDAY, SECSPERMIN, stringoffset(), stringrule(), TM_DECEMBER, TM_JANUARY, YEAR_BY_YEAR_ZONE, zone::z_gmtoff, zone::z_isdst, zone::z_nrules, zone::z_rules, and ZIC_MAX.

Referenced by outzone().

2593 {
2594  const struct zone *zp;
2595  struct rule *rp;
2596  struct rule *stdrp;
2597  struct rule *dstrp;
2598  ptrdiff_t i;
2599  const char *abbrvar;
2600  int compat = 0;
2601  int c;
2602  size_t len;
2603  int offsetlen;
2604  struct rule stdr,
2605  dstr;
2606 
2607  result[0] = '\0';
2608  zp = zpfirst + zonecount - 1;
2609  stdrp = dstrp = NULL;
2610  for (i = 0; i < zp->z_nrules; ++i)
2611  {
2612  rp = &zp->z_rules[i];
2613  if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)
2614  continue;
2615  if (rp->r_yrtype != NULL)
2616  continue;
2617  if (!rp->r_isdst)
2618  {
2619  if (stdrp == NULL)
2620  stdrp = rp;
2621  else
2622  return -1;
2623  }
2624  else
2625  {
2626  if (dstrp == NULL)
2627  dstrp = rp;
2628  else
2629  return -1;
2630  }
2631  }
2632  if (stdrp == NULL && dstrp == NULL)
2633  {
2634  /*
2635  * There are no rules running through "max". Find the latest std rule
2636  * in stdabbrrp and latest rule of any type in stdrp.
2637  */
2638  struct rule *stdabbrrp = NULL;
2639 
2640  for (i = 0; i < zp->z_nrules; ++i)
2641  {
2642  rp = &zp->z_rules[i];
2643  if (!rp->r_isdst && rule_cmp(stdabbrrp, rp) < 0)
2644  stdabbrrp = rp;
2645  if (rule_cmp(stdrp, rp) < 0)
2646  stdrp = rp;
2647  }
2648 
2649  /*
2650  * Horrid special case: if year is 2037, presume this is a zone
2651  * handled on a year-by-year basis; do not try to apply a rule to the
2652  * zone.
2653  */
2654  if (stdrp != NULL && stdrp->r_hiyear == 2037)
2655  return YEAR_BY_YEAR_ZONE;
2656 
2657  if (stdrp != NULL && stdrp->r_isdst)
2658  {
2659  /* Perpetual DST. */
2660  dstr.r_month = TM_JANUARY;
2661  dstr.r_dycode = DC_DOM;
2662  dstr.r_dayofmonth = 1;
2663  dstr.r_tod = 0;
2664  dstr.r_todisstd = dstr.r_todisgmt = false;
2665  dstr.r_isdst = stdrp->r_isdst;
2666  dstr.r_stdoff = stdrp->r_stdoff;
2667  dstr.r_abbrvar = stdrp->r_abbrvar;
2668  stdr.r_month = TM_DECEMBER;
2669  stdr.r_dycode = DC_DOM;
2670  stdr.r_dayofmonth = 31;
2671  stdr.r_tod = SECSPERDAY + stdrp->r_stdoff;
2672  stdr.r_todisstd = stdr.r_todisgmt = false;
2673  stdr.r_isdst = false;
2674  stdr.r_stdoff = 0;
2675  stdr.r_abbrvar
2676  = (stdabbrrp ? stdabbrrp->r_abbrvar : "");
2677  dstrp = &dstr;
2678  stdrp = &stdr;
2679  }
2680  }
2681  if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_isdst))
2682  return -1;
2683  abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
2684  len = doabbr(result, zp, abbrvar, false, 0, true);
2685  offsetlen = stringoffset(result + len, -zp->z_gmtoff);
2686  if (!offsetlen)
2687  {
2688  result[0] = '\0';
2689  return -1;
2690  }
2691  len += offsetlen;
2692  if (dstrp == NULL)
2693  return compat;
2694  len += doabbr(result + len, zp, dstrp->r_abbrvar,
2695  dstrp->r_isdst, dstrp->r_stdoff, true);
2696  if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR)
2697  {
2698  offsetlen = stringoffset(result + len,
2699  -(zp->z_gmtoff + dstrp->r_stdoff));
2700  if (!offsetlen)
2701  {
2702  result[0] = '\0';
2703  return -1;
2704  }
2705  len += offsetlen;
2706  }
2707  result[len++] = ',';
2708  c = stringrule(result + len, dstrp, dstrp->r_stdoff, zp->z_gmtoff);
2709  if (c < 0)
2710  {
2711  result[0] = '\0';
2712  return -1;
2713  }
2714  if (compat < c)
2715  compat = c;
2716  len += strlen(result + len);
2717  result[len++] = ',';
2718  c = stringrule(result + len, stdrp, dstrp->r_stdoff, zp->z_gmtoff);
2719  if (c < 0)
2720  {
2721  result[0] = '\0';
2722  return -1;
2723  }
2724  if (compat < c)
2725  compat = c;
2726  return compat;
2727 }
#define SECSPERMIN
Definition: private.h:90
static int stringrule(char *result, const struct rule *const rp, const zic_t dstoff, const zic_t gmtoff)
Definition: zic.c:2492
#define SECSPERDAY
Definition: private.h:97
#define TM_DECEMBER
Definition: private.h:119
static int rule_cmp(struct rule const *a, struct rule const *b)
Definition: zic.c:2574
#define DC_DOM
Definition: zic.c:94
static size_t doabbr(char *abbr, struct zone const *zp, char const *letters, bool isdst, zic_t stdoff, bool doquotes)
Definition: zic.c:2406
static int stringoffset(char *result, zic_t offset)
Definition: zic.c:2458
bool z_isdst
Definition: zic.c:109
Definition: localtime.c:77
#define ZIC_MAX
Definition: zic.c:25
bool r_isdst
Definition: zic.c:81
char * c
zic_t r_hiyear
Definition: zic.c:66
const char * r_yrtype
Definition: zic.c:67
enum COMPAT_MODE compat
Definition: ecpg.c:25
const char * r_abbrvar
Definition: zic.c:84
ptrdiff_t z_nrules
Definition: zic.c:113
#define TM_JANUARY
Definition: private.h:108
zic_t r_stdoff
Definition: zic.c:82
zic_t z_gmtoff
Definition: zic.c:104
struct rule * z_rules
Definition: zic.c:112
Definition: zic.c:98
bool r_hiwasnum
Definition: zic.c:69
int i
#define MINSPERHOUR
Definition: private.h:91

◆ tadd()

static zic_t tadd ( zic_t  t1,
zic_t  t2 
)
static

Definition at line 3587 of file zic.c.

References max_time, min_time, and time_overflow().

Referenced by adjleap(), inleap(), outzone(), rpytime(), and writezone().

3588 {
3589  if (t1 < 0)
3590  {
3591  if (t2 < min_time - t1)
3592  {
3593  if (t1 != min_time)
3594  time_overflow();
3595  return min_time;
3596  }
3597  }
3598  else
3599  {
3600  if (max_time - t1 < t2)
3601  {
3602  if (t1 != max_time)
3603  time_overflow();
3604  return max_time;
3605  }
3606  }
3607  return t1 + t2;
3608 }
static void time_overflow(void)
Definition: zic.c:3572
static zic_t const max_time
Definition: zic.c:999
static zic_t const min_time
Definition: zic.c:998

◆ time_overflow()

static void time_overflow ( void  )
static

Definition at line 3572 of file zic.c.

References _, error(), and EXIT_FAILURE.

Referenced by oadd(), and tadd().

3573 {
3574  error(_("time overflow"));
3575  exit(EXIT_FAILURE);
3576 }
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
#define _(x)
Definition: elog.c:84

◆ updateminmax()

static void updateminmax ( const zic_t  x)
static

Definition at line 2449 of file zic.c.

Referenced by outzone().

2450 {
2451  if (min_year > x)
2452  min_year = x;
2453  if (max_year < x)
2454  max_year = x;
2455 }
static zic_t min_year
Definition: zic.c:185
static zic_t max_year
Definition: zic.c:184

◆ usage()

static void usage ( FILE *  stream,
int  status 
)
static

Definition at line 536 of file zic.c.

References _, close_file(), and EXIT_SUCCESS.

Referenced by main().

537 {
538  fprintf(stream,
539  _("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -P ] \\\n"
540  "\t[ -l localtime ] [ -p posixrules ] [ -d directory ] \\\n"
541  "\t[ -t localtime-link ] [ -L leapseconds ] [ filename ... ]\n\n"
542  "Report bugs to %s.\n"),
543  progname, progname, PACKAGE_BUGREPORT);
544  if (status == EXIT_SUCCESS)
545  close_file(stream, NULL, NULL);
546  exit(status);
547 }
#define EXIT_SUCCESS
Definition: settings.h:148
static const char * progname
Definition: zic.c:191
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:520
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
#define _(x)
Definition: elog.c:84

◆ verror()

static void verror ( const char *  string,
va_list  args 
)
static

Definition at line 481 of file zic.c.

References _.

Referenced by error(), and warning().

482 {
483  /*
484  * Match the format of "cc" to allow sh users to zic ... 2>&1 | error -t
485  * "*" -v on BSD systems.
486  */
487  if (filename)
488  fprintf(stderr, _("\"%s\", line %d: "), filename, linenum);
489  vfprintf(stderr, string, args);
490  if (rfilename != NULL)
491  fprintf(stderr, _(" (rule from \"%s\", line %d)"),
493  fprintf(stderr, "\n");
494 }
static lineno_t rlinenum
Definition: zic.c:190
static const char * filename
Definition: zic.c:176
static lineno_t linenum
Definition: zic.c:181
static const char * rfilename
Definition: zic.c:189
#define _(x)
Definition: elog.c:84

◆ warning()

static void warning ( const char *  string,
  ... 
)
static

Definition at line 508 of file zic.c.

References _, generate_unaccent_rules::args, and verror().

Referenced by associate(), byword(), componentcheck(), dolink(), gethms(), inzsub(), main(), namecheck(), newabbr(), outzone(), rpytime(), rulesub(), and writezone().

509 {
510  va_list args;
511 
512  fprintf(stderr, _("warning: "));
513  va_start(args, string);
514  verror(string, args);
515  va_end(args);
516  warnings = true;
517 }
static bool warnings
Definition: zic.c:175
static void verror(const char *string, va_list args) pg_attribute_printf(1
Definition: zic.c:481
#define _(x)
Definition: elog.c:84

◆ writezone()

static void writezone ( const char *const  name,
const char *const  string,
char  version 
)
static

Definition at line 1945 of file zic.c.

References _, addtype(), attype::at, atcomp(), attypes, close_file(), convert(), DO, emalloc(), error(), EXIT_FAILURE, free, GRANDPARENTED, i, INT64_FORMAT, is32(), leapcnt, mkdirs(), PG_INT32_MIN, puttzcode(), puttzcode64(), qsort, size_product(), strerror(), tadd(), timecnt, tm, generate_unaccent_rules::type, attype::type, typecnt, types, TZ_MAGIC, TZ_MAX_CHARS, TZ_MAX_TIMES, TZ_MAX_TYPES, tzhead::tzh_charcnt, tzhead::tzh_leapcnt, tzhead::tzh_magic, tzhead::tzh_reserved, tzhead::tzh_timecnt, tzhead::tzh_ttisgmtcnt, tzhead::tzh_ttisstdcnt, tzhead::tzh_typecnt, tzhead::tzh_version, warning(), and WORK_AROUND_QTBUG_53071.

Referenced by outzone().

1946 {
1947  FILE *fp;
1948  ptrdiff_t i,
1949  j;
1950  int leapcnt32,
1951  leapi32;
1952  ptrdiff_t timecnt32,
1953  timei32;
1954  int pass;
1955  static const struct tzhead tzh0;
1956  static struct tzhead tzh;
1957  bool dir_checked = false;
1958  zic_t one = 1;
1959  zic_t y2038_boundary = one << 31;
1960  ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071;
1961  zic_t *ats = emalloc(size_product(nats, sizeof *ats + 1));
1962  void *typesptr = ats + nats;
1963  unsigned char *types = typesptr;
1964 
1965  /*
1966  * Sort.
1967  */
1968  if (timecnt > 1)
1969  qsort(attypes, timecnt, sizeof *attypes, atcomp);
1970 
1971  /*
1972  * Optimize.
1973  */
1974  {
1975  ptrdiff_t fromi,
1976  toi;
1977 
1978  toi = 0;
1979  fromi = 0;
1980  while (fromi < timecnt && attypes[fromi].at < early_time)
1981  ++fromi;
1982  for (; fromi < timecnt; ++fromi)
1983  {
1984  if (toi > 1 && ((attypes[fromi].at +
1985  gmtoffs[attypes[toi - 1].type]) <=
1986  (attypes[toi - 1].at +
1987  gmtoffs[attypes[toi - 2].type])))
1988  {
1989  attypes[toi - 1].type =
1990  attypes[fromi].type;
1991  continue;
1992  }
1993  if (toi == 0
1994  || attypes[fromi].dontmerge
1995  || attypes[toi - 1].type != attypes[fromi].type)
1996  attypes[toi++] = attypes[fromi];
1997  }
1998  timecnt = toi;
1999  }
2000 
2001  if (noise && timecnt > 1200)
2002  {
2003  if (timecnt > TZ_MAX_TIMES)
2004  warning(_("reference clients mishandle"
2005  " more than %d transition times"),
2006  TZ_MAX_TIMES);
2007  else
2008  warning(_("pre-2014 clients may mishandle"
2009  " more than 1200 transition times"));
2010  }
2011 
2012  /*
2013  * Transfer.
2014  */
2015  for (i = 0; i < timecnt; ++i)
2016  {
2017  ats[i] = attypes[i].at;
2018  types[i] = attypes[i].type;
2019  }
2020 
2021  /*
2022  * Work around QTBUG-53071 for time stamps less than y2038_boundary - 1,
2023  * by inserting a no-op transition at time y2038_boundary - 1. This works
2024  * only for timestamps before the boundary, which should be good enough in
2025  * practice as QTBUG-53071 should be long-dead by 2038.
2026  */
2027  if (WORK_AROUND_QTBUG_53071 && timecnt != 0
2028  && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<'))
2029  {
2030  ats[timecnt] = y2038_boundary - 1;
2031  types[timecnt] = types[timecnt - 1];
2032  timecnt++;
2033  }
2034 
2035  /*
2036  * Correct for leap seconds.
2037  */
2038  for (i = 0; i < timecnt; ++i)
2039  {
2040  j = leapcnt;
2041  while (--j >= 0)
2042  if (ats[i] > trans[j] - corr[j])
2043  {
2044  ats[i] = tadd(ats[i], corr[j]);
2045  break;
2046  }
2047  }
2048 
2049  /*
2050  * Figure out 32-bit-limited starts and counts.
2051  */
2052  timecnt32 = timecnt;
2053  timei32 = 0;
2054  leapcnt32 = leapcnt;
2055  leapi32 = 0;
2056  while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
2057  --timecnt32;
2058  while (timecnt32 > 0 && !is32(ats[timei32]))
2059  {
2060  --timecnt32;
2061  ++timei32;
2062  }
2063 
2064  /*
2065  * Output an INT32_MIN "transition" if appropriate; see below.
2066  */
2067  if (timei32 > 0 && ats[timei32] > PG_INT32_MIN)
2068  {
2069  --timei32;
2070  ++timecnt32;
2071  }
2072  while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
2073  --leapcnt32;
2074  while (leapcnt32 > 0 && !is32(trans[leapi32]))
2075  {
2076  --leapcnt32;
2077  ++leapi32;
2078  }
2079 
2080  /*
2081  * Remove old file, if any, to snap links.
2082  */
2083  if (remove(name) == 0)
2084  dir_checked = true;
2085  else if (errno != ENOENT)
2086  {
2087  const char *e = strerror(errno);
2088 
2089  fprintf(stderr, _("%s: Cannot remove %s/%s: %s\n"),
2090  progname, directory, name, e);
2091  exit(EXIT_FAILURE);
2092  }
2093  fp = fopen(name, "wb");
2094  if (!fp)
2095  {
2096  int fopen_errno = errno;
2097 
2098  if (fopen_errno == ENOENT && !dir_checked)
2099  {
2100  mkdirs(name, true);
2101  fp = fopen(name, "wb");
2102  fopen_errno = errno;
2103  }
2104  if (!fp)
2105  {
2106  fprintf(stderr, _("%s: Cannot create %s/%s: %s\n"),
2107  progname, directory, name, strerror(fopen_errno));
2108  exit(EXIT_FAILURE);
2109  }
2110  }
2111  for (pass = 1; pass <= 2; ++pass)
2112  {
2113  ptrdiff_t thistimei,
2114  thistimecnt,
2115  thistimelim;
2116  int thisleapi,
2117  thisleapcnt,
2118  thisleaplim;
2119  int writetype[TZ_MAX_TYPES];
2120  int typemap[TZ_MAX_TYPES];
2121  int thistypecnt;
2122  char thischars[TZ_MAX_CHARS];
2123  int thischarcnt;
2124  bool toomanytimes;
2125  int indmap[TZ_MAX_CHARS];
2126 
2127  if (pass == 1)
2128  {
2129  thistimei = timei32;
2130  thistimecnt = timecnt32;
2131  toomanytimes = thistimecnt >> 31 >> 1 != 0;
2132  thisleapi = leapi32;
2133  thisleapcnt = leapcnt32;
2134  }
2135  else
2136  {
2137  thistimei = 0;
2138  thistimecnt = timecnt;
2139  toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
2140  thisleapi = 0;
2141  thisleapcnt = leapcnt;
2142  }
2143  if (toomanytimes)
2144  error(_("too many transition times"));
2145  thistimelim = thistimei + thistimecnt;
2146  thisleaplim = thisleapi + thisleapcnt;
2147  for (i = 0; i < typecnt; ++i)
2148  writetype[i] = thistimecnt == timecnt;
2149  if (thistimecnt == 0)
2150  {
2151  /*
2152  * No transition times fall in the current (32- or 64-bit) window.
2153  */
2154  if (typecnt != 0)
2155  writetype[typecnt - 1] = true;
2156  }
2157  else
2158  {
2159  for (i = thistimei - 1; i < thistimelim; ++i)
2160  if (i >= 0)
2161  writetype[types[i]] = true;
2162 
2163  /*
2164  * For America/Godthab and Antarctica/Palmer
2165  */
2166  if (thistimei == 0)
2167  writetype[0] = true;
2168  }
2169 #ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH
2170 
2171  /*
2172  * For some pre-2011 systems: if the last-to-be-written standard (or
2173  * daylight) type has an offset different from the most recently used
2174  * offset, append an (unused) copy of the most recently used type (to
2175  * help get global "altzone" and "timezone" variables set correctly).
2176  */
2177  {
2178  int mrudst,
2179  mrustd,
2180  hidst,
2181  histd,
2182  type;
2183 
2184  hidst = histd = mrudst = mrustd = -1;
2185  for (i = thistimei; i < thistimelim; ++i)
2186  if (isdsts[types[i]])
2187  mrudst = types[i];
2188  else
2189  mrustd = types[i];
2190  for (i = 0; i < typecnt; ++i)
2191  if (writetype[i])
2192  {
2193  if (isdsts[i])
2194  hidst = i;
2195  else
2196  histd = i;
2197  }
2198  if (hidst >= 0 && mrudst >= 0 && hidst != mrudst &&
2199  gmtoffs[hidst] != gmtoffs[mrudst])
2200  {
2201  isdsts[mrudst] = -1;
2202  type = addtype(gmtoffs[mrudst],
2203  &chars[abbrinds[mrudst]],
2204  true,
2205  ttisstds[mrudst],
2206  ttisgmts[mrudst]);
2207  isdsts[mrudst] = 1;
2208  writetype[type] = true;
2209  }
2210  if (histd >= 0 && mrustd >= 0 && histd != mrustd &&
2211  gmtoffs[histd] != gmtoffs[mrustd])
2212  {
2213  isdsts[mrustd] = -1;
2214  type = addtype(gmtoffs[mrustd],
2215  &chars[abbrinds[mrustd]],
2216  false,
2217  ttisstds[mrustd],
2218  ttisgmts[mrustd]);
2219  isdsts[mrustd] = 0;
2220  writetype[type] = true;
2221  }
2222  }
2223 #endif /* !defined
2224  * LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */
2225  thistypecnt = 0;
2226  for (i = 0; i < typecnt; ++i)
2227  typemap[i] = writetype[i] ? thistypecnt++ : -1;
2228  for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i)
2229  indmap[i] = -1;
2230  thischarcnt = 0;
2231  for (i = 0; i < typecnt; ++i)
2232  {
2233  char *thisabbr;
2234 
2235  if (!writetype[i])
2236  continue;
2237  if (indmap[abbrinds[i]] >= 0)
2238  continue;
2239  thisabbr = &chars[abbrinds[i]];
2240  for (j = 0; j < thischarcnt; ++j)
2241  if (strcmp(&thischars[j], thisabbr) == 0)
2242  break;
2243  if (j == thischarcnt)
2244  {
2245  strcpy(&thischars[thischarcnt], thisabbr);
2246  thischarcnt += strlen(thisabbr) + 1;
2247  }
2248  indmap[abbrinds[i]] = j;
2249  }
2250 #define DO(field) fwrite(tzh.field, sizeof tzh.field, 1, fp)
2251  tzh = tzh0;
2252  memcpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
2253  tzh.tzh_version[0] = version;
2254  convert(thistypecnt, tzh.tzh_ttisgmtcnt);
2255  convert(thistypecnt, tzh.tzh_ttisstdcnt);
2256  convert(thisleapcnt, tzh.tzh_leapcnt);
2257  convert(thistimecnt, tzh.tzh_timecnt);
2258  convert(thistypecnt, tzh.tzh_typecnt);
2259  convert(thischarcnt, tzh.tzh_charcnt);
2260  DO(tzh_magic);
2261  DO(tzh_version);
2262  DO(tzh_reserved);
2263  DO(tzh_ttisgmtcnt);
2264  DO(tzh_ttisstdcnt);
2265  DO(tzh_leapcnt);
2266  DO(tzh_timecnt);
2267  DO(tzh_typecnt);
2268  DO(tzh_charcnt);
2269 #undef DO
2270  for (i = thistimei; i < thistimelim; ++i)
2271  if (pass == 1)
2272 
2273  /*
2274  * Output an INT32_MIN "transition" if appropriate; see above.
2275  */
2276  puttzcode(((ats[i] < PG_INT32_MIN) ?
2277  PG_INT32_MIN : ats[i]), fp);
2278  else
2279  {
2280  puttzcode64(ats[i], fp);
2281 
2282  /* Print current timezone abbreviations if requested */
2283  if (print_abbrevs &&
2284  (i == thistimelim - 1 || ats[i + 1] > print_cutoff))
2285  {
2286  unsigned char tm = typemap[types[i]];
2287  char *thisabbrev = &thischars[indmap[abbrinds[tm]]];
2288 
2289  /* filter out assorted junk entries */
2290  if (strcmp(thisabbrev, GRANDPARENTED) != 0 &&
2291  strcmp(thisabbrev, "zzz") != 0)
2292  fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
2293  thisabbrev,
2294  gmtoffs[tm],
2295  isdsts[tm] ? "\tD" : "");
2296  }
2297  }
2298  for (i = thistimei; i < thistimelim; ++i)
2299  {
2300  unsigned char uc;
2301 
2302  uc = typemap[types[i]];
2303  fwrite(&uc, sizeof uc, 1, fp);
2304  }
2305  for (i = 0; i < typecnt; ++i)
2306  if (writetype[i])
2307  {
2308  puttzcode(gmtoffs[i], fp);
2309  putc(isdsts[i], fp);
2310  putc((unsigned char) indmap[abbrinds[i]], fp);
2311  }
2312  if (thischarcnt != 0)
2313  fwrite(thischars, sizeof thischars[0],
2314  thischarcnt, fp);
2315  for (i = thisleapi; i < thisleaplim; ++i)
2316  {
2317  zic_t todo;
2318 
2319  if (roll[i])
2320  {
2321  if (timecnt == 0 || trans[i] < ats[0])
2322  {
2323  j = 0;
2324  while (isdsts[j])
2325  if (++j >= typecnt)
2326  {
2327  j = 0;
2328  break;
2329  }
2330  }
2331  else
2332  {
2333  j = 1;
2334  while (j < timecnt &&
2335  trans[i] >= ats[j])
2336  ++j;
2337  j = types[j - 1];
2338  }
2339  todo = tadd(trans[i], -gmtoffs[j]);
2340  }
2341  else
2342  todo = trans[i];
2343  if (pass == 1)
2344  puttzcode(todo, fp);
2345  else
2346  puttzcode64(todo, fp);
2347  puttzcode(corr[i], fp);
2348  }
2349  for (i = 0; i < typecnt; ++i)
2350  if (writetype[i])
2351  putc(ttisstds[i], fp);
2352  for (i = 0; i < typecnt; ++i)
2353  if (writetype[i])
2354  putc(ttisgmts[i], fp);
2355  }
2356  fprintf(fp, "\n%s\n", string);
2357  close_file(fp, directory, name);
2358  free(ats);
2359 }
static bool ttisstds[TZ_MAX_TYPES]
Definition: zic.c:392
static bool print_abbrevs
Definition: zic.c:187
static zic_t print_cutoff
Definition: zic.c:188
static int typecnt
Definition: zic.c:194
static zic_t gmtoffs[TZ_MAX_TYPES]
Definition: zic.c:389
static unsigned char abbrinds[TZ_MAX_TYPES]
Definition: zic.c:391
struct typedefs * types
Definition: ecpg.c:29
unsigned char type
Definition: zic.c:387
static char isdsts[TZ_MAX_TYPES]
Definition: zic.c:390
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:508
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:396
static bool is32(const zic_t x)
Definition: zic.c:1939
#define TZ_MAX_TIMES
Definition: tzfile.h:93
char tzh_timecnt[4]
Definition: tzfile.h:41
static bool ttisgmts[TZ_MAX_TYPES]
Definition: zic.c:393
static void mkdirs(char const *, bool)
Definition: zic.c:3752
#define GRANDPARENTED
Definition: private.h:27
static const zic_t early_time
Definition: zic.c:1039
static struct pg_tm tm
Definition: localtime.c:106
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3587
static void convert(const int32 val, char *const buf)
Definition: zic.c:1890
static int addtype(zic_t, char const *, bool, bool, bool)
Definition: zic.c:3135
char tzh_magic[4]
Definition: tzfile.h:35
#define TZ_MAGIC
Definition: tzfile.h:31
static int leapcnt
Definition: zic.c:177
int64 zic_t
Definition: zic.c:23
char tzh_leapcnt[4]
Definition: tzfile.h:40
#define PG_INT32_MIN
Definition: c.h:407
#define TZ_MAX_CHARS
Definition: tzfile.h:98
zic_t at
Definition: zic.c:385
static void puttzcode64(const zic_t val, FILE *const fp)
Definition: zic.c:1921
static struct attype * attypes
static bool noise
Definition: zic.c:186
Definition: tzfile.h:33
char tzh_typecnt[4]
Definition: tzfile.h:42
static const char * progname
Definition: zic.c:191
#define free(a)
Definition: header.h:65
char tzh_version[1]
Definition: tzfile.h:36
char tzh_charcnt[4]
Definition: tzfile.h:43
static ptrdiff_t timecnt
Definition: zic.c:192
static const char * directory
Definition: zic.c:575
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:520
#define INT64_FORMAT
Definition: c.h:367
const char * name
Definition: encode.c:521
static int atcomp(const void *avp, const void *bvp)
Definition: zic.c:1930
e
Definition: preproc-init.c:82
static zic_t trans[TZ_MAX_LEAPS]
Definition: zic.c:395
#define TZ_MAX_TYPES
Definition: tzfile.h:96
char tzh_ttisstdcnt[4]
Definition: tzfile.h:39
int i
const char * strerror(int errnum)
Definition: strerror.c:19
#define EXIT_FAILURE
Definition: settings.h:152
char tzh_reserved[15]
Definition: tzfile.h:37
#define qsort(a, b, c, d)
Definition: port.h:421
#define DO(field)
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:497
static char chars[TZ_MAX_CHARS]
Definition: zic.c:394
#define _(x)
Definition: elog.c:84
static size_t size_product(size_t nitems, size_t itemsize)
Definition: zic.c:411
static void puttzcode(const int32 val, FILE *const fp)
Definition: zic.c:1912
static char roll[TZ_MAX_LEAPS]
Definition: zic.c:397
static void * emalloc(size_t size)
Definition: zic.c:427
char tzh_ttisgmtcnt[4]
Definition: tzfile.h:38

◆ yearistype()

static bool yearistype ( zic_t  year,
const char *  type 
)
static

Definition at line 3248 of file zic.c.

References _, buf, emalloc(), error(), EXIT_FAILURE, free, INT64_FORMAT, INT_STRLEN_MAXIMUM, shellquote(), status(), WEXITSTATUS, and WIFEXITED.

Referenced by outzone().

3249 {
3250  char *buf;
3251  char *b;
3252  int result;
3253 
3254  if (type == NULL || *type == '\0')
3255  return true;
3256  buf = emalloc(1 + 4 * strlen(yitcommand) + 2
3257  + INT_STRLEN_MAXIMUM(zic_t) +2 + 4 * strlen(type) + 2);
3258  b = shellquote(buf, yitcommand);
3259  *b++ = ' ';
3260  b += sprintf(b, INT64_FORMAT, year);
3261  *b++ = ' ';
3262  b = shellquote(b, type);
3263  *b = '\0';
3264  result = system(buf);
3265  if (WIFEXITED(result))
3266  {
3267  int status = WEXITSTATUS(result);
3268 
3269  if (status <= 1)
3270  {
3271  free(buf);
3272  return status == 0;
3273  }
3274  }
3275  error(_("Wild result from command execution"));
3276  fprintf(stderr, _("%s: command was '%s', result was %d\n"),
3277  progname, buf, result);
3278  exit(EXIT_FAILURE);
3279 }
#define INT_STRLEN_MAXIMUM(type)
Definition: private.h:74
static const char * yitcommand
Definition: zic.c:578
static char * shellquote(char *b, char const *s)
Definition: zic.c:3234
static char * buf
Definition: pg_test_fsync.c:67
int64 zic_t
Definitio