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 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, 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 * 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 1000 of file zic.c.

◆ DC_DOM

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

Definition at line 88 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 89 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 90 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 195 of file zic.c.

Referenced by infile().

◆ LC_LINK

#define LC_LINK   2

Definition at line 194 of file zic.c.

Referenced by infile().

◆ LC_RULE

#define LC_RULE   0

Definition at line 192 of file zic.c.

Referenced by infile().

◆ LC_ZONE

#define LC_ZONE   1

Definition at line 193 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 259 of file zic.c.

Referenced by inleap().

◆ LF_FROM

#define LF_FROM   1

Definition at line 245 of file zic.c.

Referenced by inlink().

◆ LF_TO

#define LF_TO   2

Definition at line 246 of file zic.c.

Referenced by inlink().

◆ LINK_FIELDS

#define LINK_FIELDS   3

Definition at line 247 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 257 of file zic.c.

Referenced by inleap().

◆ LP_DAY

#define LP_DAY   3

Definition at line 255 of file zic.c.

Referenced by inleap().

◆ LP_MONTH

#define LP_MONTH   2

Definition at line 254 of file zic.c.

Referenced by inleap().

◆ LP_ROLL

#define LP_ROLL   6

Definition at line 258 of file zic.c.

Referenced by inleap().

◆ LP_TIME

#define LP_TIME   4

Definition at line 256 of file zic.c.

Referenced by inleap().

◆ LP_YEAR

#define LP_YEAR   1

Definition at line 253 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 238 of file zic.c.

Referenced by inrule().

◆ RF_COMMAND

#define RF_COMMAND   4

Definition at line 233 of file zic.c.

Referenced by inrule().

◆ RF_DAY

#define RF_DAY   6

Definition at line 235 of file zic.c.

Referenced by inrule().

◆ RF_HIYEAR

#define RF_HIYEAR   3

Definition at line 232 of file zic.c.

Referenced by inrule().

◆ RF_LOYEAR

#define RF_LOYEAR   2

Definition at line 231 of file zic.c.

Referenced by inrule().

◆ RF_MONTH

#define RF_MONTH   5

Definition at line 234 of file zic.c.

Referenced by inrule().

◆ RF_NAME

#define RF_NAME   1

Definition at line 230 of file zic.c.

Referenced by inrule().

◆ RF_STDOFF

#define RF_STDOFF   8

Definition at line 237 of file zic.c.

Referenced by inrule().

◆ RF_TOD

#define RF_TOD   7

Definition at line 236 of file zic.c.

Referenced by inrule().

◆ RULE_FIELDS

#define RULE_FIELDS   10

Definition at line 239 of file zic.c.

Referenced by inrule().

◆ TIME_T_BITS_IN_FILE

#define TIME_T_BITS_IN_FILE   64

Definition at line 972 of file zic.c.

◆ YR_MAXIMUM

#define YR_MAXIMUM   1

Definition at line 266 of file zic.c.

Referenced by rulesub().

◆ YR_MINIMUM

#define YR_MINIMUM   0

Definition at line 265 of file zic.c.

Referenced by rulesub().

◆ YR_ONLY

#define YR_ONLY   2

Definition at line 267 of file zic.c.

Referenced by rulesub().

◆ ZF_FORMAT

#define ZF_FORMAT   4

Definition at line 204 of file zic.c.

Referenced by inzsub().

◆ ZF_GMTOFF

#define ZF_GMTOFF   2

Definition at line 202 of file zic.c.

Referenced by inzsub().

◆ ZF_NAME

#define ZF_NAME   1

Definition at line 201 of file zic.c.

Referenced by inzone(), and inzsub().

◆ ZF_RULE

#define ZF_RULE   3

Definition at line 203 of file zic.c.

Referenced by inzsub().

◆ ZF_TILDAY

#define ZF_TILDAY   7

Definition at line 207 of file zic.c.

Referenced by inzsub().

◆ ZF_TILMONTH

#define ZF_TILMONTH   6

Definition at line 206 of file zic.c.

Referenced by inzsub().

◆ ZF_TILTIME

#define ZF_TILTIME   8

Definition at line 208 of file zic.c.

Referenced by inzsub().

◆ ZF_TILYEAR

#define ZF_TILYEAR   5

Definition at line 205 of file zic.c.

Referenced by inzsub().

◆ ZFC_FORMAT

#define ZFC_FORMAT   2

Definition at line 218 of file zic.c.

Referenced by inzsub().

◆ ZFC_GMTOFF

#define ZFC_GMTOFF   0

Definition at line 216 of file zic.c.

Referenced by inzsub().

◆ ZFC_RULE

#define ZFC_RULE   1

Definition at line 217 of file zic.c.

Referenced by inzsub().

◆ ZFC_TILDAY

#define ZFC_TILDAY   5

Definition at line 221 of file zic.c.

Referenced by inzsub().

◆ ZFC_TILMONTH

#define ZFC_TILMONTH   4

Definition at line 220 of file zic.c.

Referenced by inzsub().

◆ ZFC_TILTIME

#define ZFC_TILTIME   6

Definition at line 222 of file zic.c.

Referenced by inzsub().

◆ ZFC_TILYEAR

#define ZFC_TILYEAR   3

Definition at line 219 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 210 of file zic.c.

Referenced by inzone().

◆ ZONE_MINFIELDS

#define ZONE_MINFIELDS   5

Definition at line 209 of file zic.c.

◆ ZONEC_MAXFIELDS

#define ZONEC_MAXFIELDS   7

Definition at line 224 of file zic.c.

Referenced by inzcont().

◆ ZONEC_MINFIELDS

#define ZONEC_MINFIELDS   3

Definition at line 223 of file zic.c.

Typedef Documentation

◆ lineno_t

Definition at line 53 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 152 of file zic.c.

153 {
154 PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1};

◆ anonymous enum

anonymous enum
Enumerator
WORK_AROUND_QTBUG_53071 

Definition at line 161 of file zic.c.

◆ anonymous enum

anonymous enum
Enumerator
WORK_AROUND_GNOME_BUG_730332 

Definition at line 1011 of file zic.c.

◆ anonymous enum

anonymous enum
Enumerator
YEAR_BY_YEAR_ZONE 

Definition at line 2509 of file zic.c.

2510 {
2511 YEAR_BY_YEAR_ZONE = 1};

Function Documentation

◆ abbroffset()

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

Definition at line 2284 of file zic.c.

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

Referenced by doabbr().

2285 {
2286  char sign = '+';
2287  int seconds,
2288  minutes;
2289 
2290  if (offset < 0)
2291  {
2292  offset = -offset;
2293  sign = '-';
2294  }
2295 
2296  seconds = offset % SECSPERMIN;
2297  offset /= SECSPERMIN;
2298  minutes = offset % MINSPERHOUR;
2299  offset /= MINSPERHOUR;
2300  if (100 <= offset)
2301  {
2302  error(_("%%z UTC offset magnitude exceeds 99:59:59"));
2303  return "%z";
2304  }
2305  else
2306  {
2307  char *p = buf;
2308 
2309  *p++ = sign;
2310  *p++ = '0' + offset / 10;
2311  *p++ = '0' + offset % 10;
2312  if (minutes | seconds)
2313  {
2314  *p++ = '0' + minutes / 10;
2315  *p++ = '0' + minutes % 10;
2316  if (seconds)
2317  {
2318  *p++ = '0' + seconds / 10;
2319  *p++ = '0' + seconds % 10;
2320  }
2321  }
2322  *p = '\0';
2323  return buf;
2324  }
2325 }
#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:489
#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 3027 of file zic.c.

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

Referenced by outzone().

3028 {
3029  if (starttime <= early_time
3030  || (timecnt == 1 && attypes[0].at < early_time))
3031  {
3032  gmtoffs[0] = gmtoffs[type];
3033  isdsts[0] = isdsts[type];
3034  ttisstds[0] = ttisstds[type];
3035  ttisgmts[0] = ttisgmts[type];
3036  if (abbrinds[type] != 0)
3037  strcpy(chars, &chars[abbrinds[type]]);
3038  abbrinds[0] = 0;
3039  charcnt = strlen(chars) + 1;
3040  typecnt = 1;
3041  timecnt = 0;
3042  type = 0;
3043  }
3045  attypes[timecnt].at = starttime;
3046  attypes[timecnt].dontmerge = false;
3047  attypes[timecnt].type = type;
3048  ++timecnt;
3049 }
static bool ttisstds[TZ_MAX_TYPES]
Definition: zic.c:384
static int typecnt
Definition: zic.c:186
static zic_t gmtoffs[TZ_MAX_TYPES]
Definition: zic.c:381
static unsigned char abbrinds[TZ_MAX_TYPES]
Definition: zic.c:383
unsigned char type
Definition: zic.c:379
static char isdsts[TZ_MAX_TYPES]
Definition: zic.c:382
static bool ttisgmts[TZ_MAX_TYPES]
Definition: zic.c:385
static const zic_t early_time
Definition: zic.c:1015
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
Definition: zic.c:437
zic_t at
Definition: zic.c:377
static ptrdiff_t timecnt_alloc
Definition: zic.c:185
static struct attype * attypes
static ptrdiff_t timecnt
Definition: zic.c:184
static int charcnt
Definition: zic.c:165
bool dontmerge
Definition: zic.c:378
static char chars[TZ_MAX_CHARS]
Definition: zic.c:386

◆ addtype()

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

Definition at line 3052 of file zic.c.

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

Referenced by outzone(), and writezone().

3053 {
3054  int i,
3055  j;
3056 
3057  /*
3058  * See if there's already an entry for this zone type. If so, just return
3059  * its index.
3060  */
3061  for (i = 0; i < typecnt; ++i)
3062  {
3063  if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
3064  strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
3065  ttisstd == ttisstds[i] &&
3066  ttisgmt == ttisgmts[i])
3067  return i;
3068  }
3069 
3070  /*
3071  * There isn't one; add a new one, unless there are already too many.
3072  */
3073  if (typecnt >= TZ_MAX_TYPES)
3074  {
3075  error(_("too many local time types"));
3076  exit(EXIT_FAILURE);
3077  }
3078  if (!(-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L))
3079  {
3080  error(_("UT offset out of range"));
3081  exit(EXIT_FAILURE);
3082  }
3083  gmtoffs[i] = gmtoff;
3084  isdsts[i] = isdst;
3085  ttisstds[i] = ttisstd;
3086  ttisgmts[i] = ttisgmt;
3087 
3088  for (j = 0; j < charcnt; ++j)
3089  if (strcmp(&chars[j], abbr) == 0)
3090  break;
3091  if (j == charcnt)
3092  newabbr(abbr);
3093  abbrinds[i] = j;
3094  ++typecnt;
3095  return i;
3096 }
static bool ttisstds[TZ_MAX_TYPES]
Definition: zic.c:384
static int typecnt
Definition: zic.c:186
static zic_t gmtoffs[TZ_MAX_TYPES]
Definition: zic.c:381
static unsigned char abbrinds[TZ_MAX_TYPES]
Definition: zic.c:383
static char isdsts[TZ_MAX_TYPES]
Definition: zic.c:382
static bool ttisgmts[TZ_MAX_TYPES]
Definition: zic.c:385
static int charcnt
Definition: zic.c:165
#define TZ_MAX_TYPES
Definition: tzfile.h:96
static void newabbr(const char *abbr)
Definition: zic.c:3631
int i
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
static char chars[TZ_MAX_CHARS]
Definition: zic.c:386
#define _(x)
Definition: elog.c:84

◆ adjleap()

static void adjleap ( void  )
static

Definition at line 3128 of file zic.c.

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

Referenced by main().

3129 {
3130  int i;
3131  zic_t last = 0;
3132  zic_t prevtrans = 0;
3133 
3134  /*
3135  * propagate leap seconds forward
3136  */
3137  for (i = 0; i < leapcnt; ++i)
3138  {
3139  if (trans[i] - prevtrans < 28 * SECSPERDAY)
3140  {
3141  error(_("Leap seconds too close together"));
3142  exit(EXIT_FAILURE);
3143  }
3144  prevtrans = trans[i];
3145  trans[i] = tadd(trans[i], last);
3146  last = corr[i] += last;
3147  }
3148 }
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:388
#define SECSPERDAY
Definition: private.h:97
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3504
static int leapcnt
Definition: zic.c:169
int64 zic_t
Definition: zic.c:23
static zic_t trans[TZ_MAX_LEAPS]
Definition: zic.c:387
int i
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84

◆ associate()

static void associate ( void  )
static

Definition at line 1073 of file zic.c.

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

Referenced by main().

1074 {
1075  struct zone *zp;
1076  struct rule *rp;
1077  ptrdiff_t i,
1078  j,
1079  base,
1080  out;
1081 
1082  if (nrules != 0)
1083  {
1084  qsort(rules, nrules, sizeof *rules, rcomp);
1085  for (i = 0; i < nrules - 1; ++i)
1086  {
1087  if (strcmp(rules[i].r_name,
1088  rules[i + 1].r_name) != 0)
1089  continue;
1090  if (strcmp(rules[i].r_filename,
1091  rules[i + 1].r_filename) == 0)
1092  continue;
1093  eat(rules[i].r_filename, rules[i].r_linenum);
1094  warning(_("same rule name in multiple files"));
1095  eat(rules[i + 1].r_filename, rules[i + 1].r_linenum);
1096  warning(_("same rule name in multiple files"));
1097  for (j = i + 2; j < nrules; ++j)
1098  {
1099  if (strcmp(rules[i].r_name,
1100  rules[j].r_name) != 0)
1101  break;
1102  if (strcmp(rules[i].r_filename,
1103  rules[j].r_filename) == 0)
1104  continue;
1105  if (strcmp(rules[i + 1].r_filename,
1106  rules[j].r_filename) == 0)
1107  continue;
1108  break;
1109  }
1110  i = j - 1;
1111  }
1112  }
1113  for (i = 0; i < nzones; ++i)
1114  {
1115  zp = &zones[i];
1116  zp->z_rules = NULL;
1117  zp->z_nrules = 0;
1118  }
1119  for (base = 0; base < nrules; base = out)
1120  {
1121  rp = &rules[base];
1122  for (out = base + 1; out < nrules; ++out)
1123  if (strcmp(rp->r_name, rules[out].r_name) != 0)
1124  break;
1125  for (i = 0; i < nzones; ++i)
1126  {
1127  zp = &zones[i];
1128  if (strcmp(zp->z_rule, rp->r_name) != 0)
1129  continue;
1130  zp->z_rules = rp;
1131  zp->z_nrules = out - base;
1132  }
1133  }
1134  for (i = 0; i < nzones; ++i)
1135  {
1136  zp = &zones[i];
1137  if (zp->z_nrules == 0)
1138  {
1139  /*
1140  * Maybe we have a local standard time offset.
1141  */
1142  eat(zp->z_filename, zp->z_linenum);
1143  zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"),
1144  true);
1145 
1146  /*
1147  * Note, though, that if there's no rule, a '%s' in the format is
1148  * a bad thing.
1149  */
1150  if (zp->z_format_specifier == 's')
1151  error("%s", _("%s in ruleless zone"));
1152  }
1153  }
1154  if (errors)
1155  exit(EXIT_FAILURE);
1156 }
lineno_t r_linenum
Definition: zic.c:58
static int rcomp(const void *cp1, const void *cp2)
Definition: zic.c:1066
const char * z_rule
Definition: zic.c:99
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
static bool errors
Definition: zic.c:166
static ptrdiff_t nzones
Definition: zic.c:274
Definition: localtime.c:78
char z_format_specifier
Definition: zic.c:101
const char * r_name
Definition: zic.c:59
const char * z_filename
Definition: zic.c:94
static struct rule * rules
Definition: zic.c:269
const char * r_filename
Definition: zic.c:57
static zic_t gethms(const char *string, const char *errstring, bool)
Definition: zic.c:1262
static void eat(char const *name, lineno_t num)
Definition: zic.c:467
ptrdiff_t z_nrules
Definition: zic.c:106
lineno_t z_linenum
Definition: zic.c:95
static ptrdiff_t nrules
Definition: zic.c:270
static struct zone * zones
Definition: zic.c:273
struct rule * z_rules
Definition: zic.c:105
Definition: zic.c:92
int i
#define EXIT_FAILURE
Definition: settings.h:152
#define qsort(a, b, c, d)
Definition: port.h:408
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84
zic_t z_stdoff
Definition: zic.c:103

◆ atcomp()

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

Definition at line 1852 of file zic.c.

Referenced by writezone().

1853 {
1854  const zic_t a = ((const struct attype *) avp)->at;
1855  const zic_t b = ((const struct attype *) bvp)->at;
1856 
1857  return (a < b) ? -1 : (a > b);
1858 }
Definition: zic.c:375
int64 zic_t
Definition: zic.c:23

◆ byword()

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

Definition at line 3383 of file zic.c.

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

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

3384 {
3385  const struct lookup *foundlp;
3386  const struct lookup *lp;
3387 
3388  if (word == NULL || table == NULL)
3389  return NULL;
3390 
3391  /*
3392  * If TABLE is LASTS and the word starts with "last" followed by a
3393  * non-'-', skip the "last" and look in WDAY_NAMES instead. Warn about any
3394  * usage of the undocumented prefix "last-".
3395  */
3396  if (table == lasts && ciprefix("last", word) && word[4])
3397  {
3398  if (word[4] == '-')
3399  warning(_("\"%s\" is undocumented; use \"last%s\" instead"),
3400  word, word + 5);
3401  else
3402  {
3403  word += 4;
3404  table = wday_names;
3405  }
3406  }
3407 
3408  /*
3409  * Look for exact match.
3410  */
3411  for (lp = table; lp->l_word != NULL; ++lp)
3412  if (ciequal(word, lp->l_word))
3413  return lp;
3414 
3415  /*
3416  * Look for inexact match.
3417  */
3418  foundlp = NULL;
3419  for (lp = table; lp->l_word != NULL; ++lp)
3420  if (ciprefix(word, lp->l_word))
3421  {
3422  if (foundlp == NULL)
3423  foundlp = lp;
3424  else
3425  return NULL; /* multiple inexact matches */
3426  }
3427 
3428  /* Warn about any backward-compatibility issue with pre-2017c zic. */
3429  if (foundlp)
3430  {
3431  bool pre_2017c_match = false;
3432 
3433  for (lp = table; lp->l_word; lp++)
3434  if (itsabbr(word, lp->l_word))
3435  {
3436  if (pre_2017c_match)
3437  {
3438  warning(_("\"%s\" is ambiguous in pre-2017c zic"), word);
3439  break;
3440  }
3441  pre_2017c_match = true;
3442  }
3443  }
3444 
3445  return foundlp;
3446 }
static bool ciprefix(char const *abbr, char const *word)
Definition: zic.c:3372
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
Definition: zic.c:289
static bool ciequal(const char *ap, const char *bp)
Definition: zic.c:3346
const char * l_word
Definition: zic.c:291
static void word(struct vars *, int, struct state *, struct state *)
Definition: regcomp.c:1243
static struct lookup const lasts[]
Definition: zic.c:336
static struct lookup const wday_names[]
Definition: zic.c:325
#define _(x)
Definition: elog.c:84
static bool itsabbr(const char *abbr, const char *word)
Definition: zic.c:3355

◆ change_directory()

static void change_directory ( char const *  dir)
static

Definition at line 545 of file zic.c.

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

Referenced by main().

546 {
547  if (chdir(dir) != 0)
548  {
549  int chdir_errno = errno;
550 
551  if (chdir_errno == ENOENT)
552  {
553  mkdirs(dir, false);
554  chdir_errno = chdir(dir) == 0 ? 0 : errno;
555  }
556  if (chdir_errno != 0)
557  {
558  fprintf(stderr, _("%s: Can't chdir to %s: %s\n"),
559  progname, dir, strerror(chdir_errno));
560  exit(EXIT_FAILURE);
561  }
562  }
563 }
static void mkdirs(char const *, bool)
Definition: zic.c:3669
static const char * progname
Definition: zic.c:183
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 3346 of file zic.c.

References lowerit().

Referenced by byword().

3347 {
3348  while (lowerit(*ap) == lowerit(*bp++))
3349  if (*ap++ == '\0')
3350  return true;
3351  return false;
3352 }
static char lowerit(char)
Definition: zic.c:3283

◆ ciprefix()

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

Definition at line 3372 of file zic.c.

References lowerit().

Referenced by byword().

3373 {
3374  do
3375  if (!*abbr)
3376  return true;
3377  while (lowerit(*abbr++) == lowerit(*word++));
3378 
3379  return false;
3380 }
static char lowerit(char)
Definition: zic.c:3283
static void word(struct vars *, int, struct state *, struct state *)
Definition: regcomp.c:1243

◆ close_file()

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

Definition at line 512 of file zic.c.

References _, EXIT_FAILURE, and strerror().

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

513 {
514  char const *e = (ferror(stream) ? _("I/O error")
515  : fclose(stream) != 0 ? strerror(errno) : NULL);
516 
517  if (e)
518  {
519  fprintf(stderr, "%s: %s%s%s%s%s\n", progname,
520  dir ? dir : "", dir ? "/" : "",
521  name ? name : "", name ? ": " : "",
522  e);
523  exit(EXIT_FAILURE);
524  }
525 }
static const char * progname
Definition: zic.c:183
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 732 of file zic.c.

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

Referenced by namecheck().

734 {
735  enum
736  {
737  component_len_max = 14};
738  ptrdiff_t component_len = component_end - component;
739 
740  if (component_len == 0)
741  {
742  if (!*name)
743  error(_("empty file name"));
744  else
745  error(_(component == name
746  ? "file name '%s' begins with '/'"
747  : *component_end
748  ? "file name '%s' contains '//'"
749  : "file name '%s' ends with '/'"),
750  name);
751  return false;
752  }
753  if (0 < component_len && component_len <= 2
754  && component[0] == '.' && component_end[-1] == '.')
755  {
756  int len = component_len;
757 
758  error(_("file name '%s' contains '%.*s' component"),
759  name, len, component);
760  return false;
761  }
762  if (noise)
763  {
764  if (0 < component_len && component[0] == '-')
765  warning(_("file name '%s' component contains leading '-'"),
766  name);
767  if (component_len_max < component_len)
768  warning(_("file name '%s' contains overlength component"
769  " '%.*s...'"),
770  name, component_len_max, component);
771  }
772  return true;
773 }
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
static bool noise
Definition: zic.c:178
const char * name
Definition: encode.c:521
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84

◆ convert()

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

Definition at line 1812 of file zic.c.

References i.

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

1813 {
1814  int i;
1815  int shift;
1816  unsigned char *const b = (unsigned char *) buf;
1817 
1818  for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
1819  b[i] = val >> shift;
1820 }
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 1823 of file zic.c.

References i.

Referenced by puttzcode64().

1824 {
1825  int i;
1826  int shift;
1827  unsigned char *const b = (unsigned char *) buf;
1828 
1829  for (i = 0, shift = 56; i < 8; ++i, shift -= 8)
1830  b[i] = val >> shift;
1831 }
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,
zic_t  stdoff,
bool  doquotes 
)
static

Definition at line 2328 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().

2330 {
2331  char *cp;
2332  char *slashp;
2333  size_t len;
2334  char const *format = zp->z_format;
2335 
2336  slashp = strchr(format, '/');
2337  if (slashp == NULL)
2338  {
2339  char letterbuf[PERCENT_Z_LEN_BOUND + 1];
2340 
2341  if (zp->z_format_specifier == 'z')
2342  letters = abbroffset(letterbuf, zp->z_gmtoff + stdoff);
2343  else if (!letters)
2344  letters = "%s";
2345  sprintf(abbr, format, letters);
2346  }
2347  else if (stdoff != 0)
2348  {
2349  strcpy(abbr, slashp + 1);
2350  }
2351  else
2352  {
2353  memcpy(abbr, format, slashp - format);
2354  abbr[slashp - format] = '\0';
2355  }
2356  len = strlen(abbr);
2357  if (!doquotes)
2358  return len;
2359  for (cp = abbr; is_alpha(*cp); cp++)
2360  continue;
2361  if (len > 0 && *cp == '\0')
2362  return len;
2363  abbr[len + 2] = '\0';
2364  abbr[len + 1] = '>';
2365  memmove(abbr + 1, abbr, len);
2366  abbr[0] = '<';
2367  return len + 2;
2368 }
static char const * abbroffset(char *buf, zic_t offset)
Definition: zic.c:2284
static bool is_alpha(char a)
Definition: zic.c:3218
#define memmove(d, s, c)
Definition: c.h:1045
static char format
Definition: pg_basebackup.c:81

◆ dolink()

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

Definition at line 877 of file zic.c.

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

Referenced by main().

878 {
879  bool todirs_made = false;
880  int link_errno;
881 
882  /*
883  * We get to be careful here since there's a fair chance of root running
884  * us.
885  */
886  if (itsdir(fromfield))
887  {
888  fprintf(stderr, _("%s: link from %s/%s failed: %s\n"),
889  progname, directory, fromfield, strerror(EPERM));
890  exit(EXIT_FAILURE);
891  }
892  if (staysymlink)
893  staysymlink = itssymlink(tofield);
894  if (remove(tofield) == 0)
895  todirs_made = true;
896  else if (errno != ENOENT)
897  {
898  char const *e = strerror(errno);
899 
900  fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
901  progname, directory, tofield, e);
902  exit(EXIT_FAILURE);
903  }
904  link_errno = staysymlink ? ENOTSUP : hardlinkerr(fromfield, tofield);
905  if (link_errno == ENOENT && !todirs_made)
906  {
907  mkdirs(tofield, true);
908  todirs_made = true;
909  link_errno = hardlinkerr(fromfield, tofield);
910  }
911  if (link_errno != 0)
912  {
913 #ifdef HAVE_SYMLINK
914  bool absolute = *fromfield == '/';
915  char *linkalloc = absolute ? NULL : relname(fromfield, tofield);
916  char const *contents = absolute ? fromfield : linkalloc;
917  int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
918 
919  if (symlink_errno == ENOENT && !todirs_made)
920  {
921  mkdirs(tofield, true);
922  symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
923  }
924  free(linkalloc);
925  if (symlink_errno == 0)
926  {
927  if (link_errno != ENOTSUP)
928  warning(_("symbolic link used because hard link failed: %s"),
929  strerror(link_errno));
930  }
931  else
932 #endif /* HAVE_SYMLINK */
933  {
934  FILE *fp,
935  *tp;
936  int c;
937 
938  fp = fopen(fromfield, "rb");
939  if (!fp)
940  {
941  char const *e = strerror(errno);
942 
943  fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
944  progname, directory, fromfield, e);
945  exit(EXIT_FAILURE);
946  }
947  tp = fopen(tofield, "wb");
948  if (!tp)
949  {
950  char const *e = strerror(errno);
951 
952  fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
953  progname, directory, tofield, e);
954  exit(EXIT_FAILURE);
955  }
956  while ((c = getc(fp)) != EOF)
957  putc(c, tp);
958  close_file(fp, directory, fromfield);
959  close_file(tp, directory, tofield);
960  if (link_errno != ENOTSUP)
961  warning(_("copy used because hard link failed: %s"),
962  strerror(link_errno));
963 #ifdef HAVE_SYMLINK
964  else if (symlink_errno != ENOTSUP)
965  warning(_("copy used because symbolic link failed: %s"),
966  strerror(symlink_errno));
967 #endif
968  }
969  }
970 }
static int hardlinkerr(char const *from, char const *to)
Definition: zic.c:869
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
#define ENOTSUP
Definition: private.h:35
static void mkdirs(char const *, bool)
Definition: zic.c:3669
static bool itsdir(char const *)
Definition: zic.c:1021
char * c
#define symlink(oldpath, newpath)
Definition: win32_port.h:232
static bool itssymlink(char const *)
Definition: zic.c:1046
static const char * progname
Definition: zic.c:183
#define free(a)
Definition: header.h:65
static const char * directory
Definition: zic.c:567
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:512
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 467 of file zic.c.

References eats().

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

468 {
469  eats(name, num, NULL, -1);
470 }
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:458

◆ eats()

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

Definition at line 458 of file zic.c.

References name.

Referenced by eat(), and outzone().

459 {
460  filename = name;
461  linenum = num;
462  rfilename = rname;
463  rlinenum = rnum;
464 }
static lineno_t rlinenum
Definition: zic.c:182
static const char * filename
Definition: zic.c:168
static lineno_t linenum
Definition: zic.c:173
static const char * rfilename
Definition: zic.c:181
const char * name
Definition: encode.c:521

◆ ecpyalloc()

static char* ecpyalloc ( char const *  str)
static

Definition at line 431 of file zic.c.

References memcheck().

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

432 {
433  return memcheck(strdup(str));
434 }
static void * memcheck(void *ptr)
Definition: zic.c:411

◆ emalloc()

static void* emalloc ( size_t  size)
static

Definition at line 419 of file zic.c.

References malloc, and memcheck().

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

420 {
421  return memcheck(malloc(size));
422 }
#define malloc(a)
Definition: header.h:50
static void * memcheck(void *ptr)
Definition: zic.c:411

◆ erealloc()

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

Definition at line 425 of file zic.c.

References memcheck(), and realloc.

Referenced by growalloc().

426 {
427  return memcheck(realloc(ptr, size));
428 }
#define realloc(a, b)
Definition: header.h:60
static void * memcheck(void *ptr)
Definition: zic.c:411

◆ error()

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

Definition at line 489 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().

490 {
491  va_list args;
492 
493  va_start(args, string);
494  verror(string, args);
495  va_end(args);
496  errors = true;
497 }
static bool errors
Definition: zic.c:166
static void verror(const char *string, va_list args) pg_attribute_printf(1
Definition: zic.c:473

◆ getfields()

static char ** getfields ( char *  buf)
static

Definition at line 3449 of file zic.c.

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

Referenced by infile().

3450 {
3451  char *dp;
3452  char **array;
3453  int nsubs;
3454 
3455  if (cp == NULL)
3456  return NULL;
3457  array = emalloc(size_product(strlen(cp) + 1, sizeof *array));
3458  nsubs = 0;
3459  for (;;)
3460  {
3461  while (is_space(*cp))
3462  ++cp;
3463  if (*cp == '\0' || *cp == '#')
3464  break;
3465  array[nsubs++] = dp = cp;
3466  do
3467  {
3468  if ((*dp = *cp++) != '"')
3469  ++dp;
3470  else
3471  while ((*dp = *cp++) != '"')
3472  if (*dp != '\0')
3473  ++dp;
3474  else
3475  {
3476  error(_("Odd number of quotation marks"));
3477  exit(EXIT_FAILURE);
3478  }
3479  } while (*cp && *cp != '#' && !is_space(*cp));
3480  if (is_space(*cp))
3481  ++cp;
3482  *dp = '\0';
3483  }
3484  array[nsubs] = NULL;
3485  return array;
3486 }
static bool is_space(char a)
Definition: zic.c:3200
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84
static size_t size_product(size_t nitems, size_t itemsize)
Definition: zic.c:403
static void * emalloc(size_t size)
Definition: zic.c:419

◆ gethms()

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

Definition at line 1262 of file zic.c.

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

Referenced by associate(), inleap(), inrule(), inzsub(), and rulesub().

1263 {
1264  /* PG: make hh be int not zic_t to avoid sscanf portability issues */
1265  int hh;
1266  int mm,
1267  ss,
1268  sign;
1269  char xs;
1270 
1271  if (string == NULL || *string == '\0')
1272  return 0;
1273  if (!signable)
1274  sign = 1;
1275  else if (*string == '-')
1276  {
1277  sign = -1;
1278  ++string;
1279  }
1280  else
1281  sign = 1;
1282  if (sscanf(string, "%d%c", &hh, &xs) == 1)
1283  mm = ss = 0;
1284  else if (sscanf(string, "%d:%d%c", &hh, &mm, &xs) == 2)
1285  ss = 0;
1286  else if (sscanf(string, "%d:%d:%d%c", &hh, &mm, &ss, &xs)
1287  != 3)
1288  {
1289  error("%s", errstring);
1290  return 0;
1291  }
1292  if (hh < 0 ||
1293  mm < 0 || mm >= MINSPERHOUR ||
1294  ss < 0 || ss > SECSPERMIN)
1295  {
1296  error("%s", errstring);
1297  return 0;
1298  }
1299  /* Some compilers warn that this test is unsatisfiable for 32-bit ints */
1300 #if INT_MAX > PG_INT32_MAX
1301  if (ZIC_MAX / SECSPERHOUR < hh)
1302  {
1303  error(_("time overflow"));
1304  return 0;
1305  }
1306 #endif
1307  if (noise && (hh > HOURSPERDAY ||
1308  (hh == HOURSPERDAY && (mm != 0 || ss != 0))))
1309  warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
1310  return oadd(sign * (zic_t) hh * SECSPERHOUR,
1311  sign * (mm * SECSPERMIN + ss));
1312 }
#define SECSPERMIN
Definition: private.h:90
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
#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:178
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84
static zic_t oadd(zic_t t1, zic_t t2)
Definition: zic.c:3496
#define MINSPERHOUR
Definition: private.h:91

◆ growalloc()

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

Definition at line 437 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().

438 {
439  if (nitems < *nitems_alloc)
440  return ptr;
441  else
442  {
443  ptrdiff_t nitems_max = PTRDIFF_MAX - WORK_AROUND_QTBUG_53071;
444  ptrdiff_t amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
445 
446  if ((amax - 1) / 3 * 2 < *nitems_alloc)
447  memory_exhausted(_("integer overflow"));
448  *nitems_alloc += (*nitems_alloc >> 1) + 1;
449  return erealloc(ptr, size_product(*nitems_alloc, itemsize));
450  }
451 }
#define SIZE_MAX
Definition: c.h:390
static ptrdiff_t const PTRDIFF_MAX
Definition: zic.c:45
static void memory_exhausted(const char *msg) pg_attribute_noreturn()
Definition: zic.c:396
#define _(x)
Definition: elog.c:84
static size_t size_product(size_t nitems, size_t itemsize)
Definition: zic.c:403
static void * erealloc(void *ptr, size_t size)
Definition: zic.c:425

◆ hardlinkerr()

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

Definition at line 869 of file zic.c.

References linkat.

Referenced by dolink().

870 {
871  int r = linkat(AT_FDCWD, from, AT_FDCWD, to, AT_SYMLINK_FOLLOW);
872 
873  return r == 0 ? 0 : errno;
874 }
#define linkat(fromdir, from, todir, to, flag)
Definition: zic.c:39

◆ infile()

static void infile ( const char *  filename)
static

Definition at line 1159 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().

1160 {
1161  FILE *fp;
1162  char **fields;
1163  char *cp;
1164  const struct lookup *lp;
1165  int nfields;
1166  bool wantcont;
1167  lineno_t num;
1168  char buf[BUFSIZ];
1169 
1170  if (strcmp(name, "-") == 0)
1171  {
1172  name = _("standard input");
1173  fp = stdin;
1174  }
1175  else if ((fp = fopen(name, "r")) == NULL)
1176  {
1177  const char *e = strerror(errno);
1178 
1179  fprintf(stderr, _("%s: Cannot open %s: %s\n"),
1180  progname, name, e);
1181  exit(EXIT_FAILURE);
1182  }
1183  wantcont = false;
1184  for (num = 1;; ++num)
1185  {
1186  eat(name, num);
1187  if (fgets(buf, sizeof buf, fp) != buf)
1188  break;
1189  cp = strchr(buf, '\n');
1190  if (cp == NULL)
1191  {
1192  error(_("line too long"));
1193  exit(EXIT_FAILURE);
1194  }
1195  *cp = '\0';
1196  fields = getfields(buf);
1197  nfields = 0;
1198  while (fields[nfields] != NULL)
1199  {
1200  static char nada;
1201 
1202  if (strcmp(fields[nfields], "-") == 0)
1203  fields[nfields] = &nada;
1204  ++nfields;
1205  }
1206  if (nfields == 0)
1207  {
1208  /* nothing to do */
1209  }
1210  else if (wantcont)
1211  {
1212  wantcont = inzcont(fields, nfields);
1213  }
1214  else
1215  {
1216  struct lookup const *line_codes
1218 
1219  lp = byword(fields[0], line_codes);
1220  if (lp == NULL)
1221  error(_("input line of unknown type"));
1222  else
1223  switch (lp->l_value)
1224  {
1225  case LC_RULE:
1226  inrule(fields, nfields);
1227  wantcont = false;
1228  break;
1229  case LC_ZONE:
1230  wantcont = inzone(fields, nfields);
1231  break;
1232  case LC_LINK:
1233  inlink(fields, nfields);
1234  wantcont = false;
1235  break;
1236  case LC_LEAP:
1237  inleap(fields, nfields);
1238  wantcont = false;
1239  break;
1240  default: /* "cannot happen" */
1241  fprintf(stderr,
1242  _("%s: panic: Invalid l_value %d\n"),
1243  progname, lp->l_value);
1244  exit(EXIT_FAILURE);
1245  }
1246  }
1247  free(fields);
1248  }
1249  close_file(fp, NULL, filename);
1250  if (wantcont)
1251  error(_("expected continuation line not found"));
1252 }
static struct lookup const zi_line_codes[]
Definition: zic.c:298
static struct lookup const leap_line_codes[]
Definition: zic.c:304
static void inrule(char **fields, int nfields)
Definition: zic.c:1315
#define LC_LEAP
Definition: zic.c:195
static const char * leapsec
Definition: zic.c:568
const int l_value
Definition: zic.c:292
static const char * filename
Definition: zic.c:168
static void inleap(char **fields, int nfields)
Definition: zic.c:1491
static char ** getfields(char *buf)
Definition: zic.c:3449
static bool inzcont(char **fields, int nfields)
Definition: zic.c:1381
static char * buf
Definition: pg_test_fsync.c:67
Definition: zic.c:289
#define LC_LINK
Definition: zic.c:194
static void eat(char const *name, lineno_t num)
Definition: zic.c:467
#define LC_ZONE
Definition: zic.c:193
static const char * progname
Definition: zic.c:183
#define free(a)
Definition: header.h:65
static bool inzone(char **fields, int nfields)
Definition: zic.c:1343
static void inlink(char **fields, int nfields)
Definition: zic.c:1611
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:512
static struct lookup const * byword(const char *string, const struct lookup *lp)
Definition: zic.c:3383
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:53
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define LC_RULE
Definition: zic.c:192
#define _(x)
Definition: elog.c:84

◆ inleap()

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

Definition at line 1491 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().

1492 {
1493  const char *cp;
1494  const struct lookup *lp;
1495  zic_t i,
1496  j;
1497 
1498  /* PG: make year be int not zic_t to avoid sscanf portability issues */
1499  int year;
1500  int month,
1501  day;
1502  zic_t dayoff,
1503  tod;
1504  zic_t t;
1505  char xs;
1506 
1507  if (nfields != LEAP_FIELDS)
1508  {
1509  error(_("wrong number of fields on Leap line"));
1510  return;
1511  }
1512  dayoff = 0;
1513  cp = fields[LP_YEAR];
1514  if (sscanf(cp, "%d%c", &year, &xs) != 1)
1515  {
1516  /*
1517  * Leapin' Lizards!
1518  */
1519  error(_("invalid leaping year"));
1520  return;
1521  }
1522  if (!leapseen || leapmaxyear < year)
1523  leapmaxyear = year;
1524  if (!leapseen || leapminyear > year)
1525  leapminyear = year;
1526  leapseen = true;
1527  j = EPOCH_YEAR;
1528  while (j != year)
1529  {
1530  if (year > j)
1531  {
1532  i = len_years[isleap(j)];
1533  ++j;
1534  }
1535  else
1536  {
1537  --j;
1538  i = -len_years[isleap(j)];
1539  }
1540  dayoff = oadd(dayoff, i);
1541  }
1542  if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL)
1543  {
1544  error(_("invalid month name"));
1545  return;
1546  }
1547  month = lp->l_value;
1548  j = TM_JANUARY;
1549  while (j != month)
1550  {
1551  i = len_months[isleap(year)][j];
1552  dayoff = oadd(dayoff, i);
1553  ++j;
1554  }
1555  cp = fields[LP_DAY];
1556  if (sscanf(cp, "%d%c", &day, &xs) != 1 ||
1557  day <= 0 || day > len_months[isleap(year)][month])
1558  {
1559  error(_("invalid day of month"));
1560  return;
1561  }
1562  dayoff = oadd(dayoff, day - 1);
1563  if (dayoff < min_time / SECSPERDAY)
1564  {
1565  error(_("time too small"));
1566  return;
1567  }
1568  if (dayoff > max_time / SECSPERDAY)
1569  {
1570  error(_("time too large"));
1571  return;
1572  }
1573  t = dayoff * SECSPERDAY;
1574  tod = gethms(fields[LP_TIME], _("invalid time of day"), false);
1575  cp = fields[LP_CORR];
1576  {
1577  bool positive;
1578  int count;
1579 
1580  if (strcmp(cp, "") == 0)
1581  { /* infile() turns "-" into "" */
1582  positive = false;
1583  count = 1;
1584  }
1585  else if (strcmp(cp, "+") == 0)
1586  {
1587  positive = true;
1588  count = 1;
1589  }
1590  else
1591  {
1592  error(_("illegal CORRECTION field on Leap line"));
1593  return;
1594  }
1595  if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL)
1596  {
1597  error(_("illegal Rolling/Stationary field on Leap line"));
1598  return;
1599  }
1600  t = tadd(t, tod);
1601  if (t < 0)
1602  {
1603  error(_("leap second precedes Epoch"));
1604  return;
1605  }
1606  leapadd(t, positive, lp->l_value, count);
1607  }
1608 }
#define LP_CORR
Definition: zic.c:257
static zic_t leapmaxyear
Definition: zic.c:172
#define SECSPERDAY
Definition: private.h:97
#define isleap(y)
Definition: datetime.h:273
static const int len_months[2][MONSPERYEAR]
Definition: zic.c:366
const int l_value
Definition: zic.c:292
#define LP_ROLL
Definition: zic.c:258
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3504
#define LEAP_FIELDS
Definition: zic.c:259
static struct lookup const mon_names[]
Definition: zic.c:309
#define LP_DAY
Definition: zic.c:255
static bool leapseen
Definition: zic.c:170
int64 zic_t
Definition: zic.c:23
Definition: zic.c:289
static void leapadd(zic_t, bool, int, int)
Definition: zic.c:3099
#define EPOCH_YEAR
Definition: private.h:123
#define LP_TIME
Definition: zic.c:256
static zic_t gethms(const char *string, const char *errstring, bool)
Definition: zic.c:1262
static zic_t const max_time
Definition: zic.c:975
#define TM_JANUARY
Definition: private.h:108
static struct lookup const * byword(const char *string, const struct lookup *lp)
Definition: zic.c:3383
static zic_t leapminyear
Definition: zic.c:171
#define LP_YEAR
Definition: zic.c:253
int i
static struct lookup const leap_types[]
Definition: zic.c:360
static const int len_years[2]
Definition: zic.c:371
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
static zic_t const min_time
Definition: zic.c:974
#define LP_MONTH
Definition: zic.c:254
#define _(x)
Definition: elog.c:84
static zic_t oadd(zic_t t1, zic_t t2)
Definition: zic.c:3496

◆ inlink()

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

Definition at line 1611 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().

1612 {
1613  struct link l;
1614 
1615  if (nfields != LINK_FIELDS)
1616  {
1617  error(_("wrong number of fields on Link line"));
1618  return;
1619  }
1620  if (*fields[LF_FROM] == '\0')
1621  {
1622  error(_("blank FROM field on Link line"));
1623  return;
1624  }
1625  if (!namecheck(fields[LF_TO]))
1626  return;
1627  l.l_filename = filename;
1628  l.l_linenum = linenum;
1629  l.l_from = ecpyalloc(fields[LF_FROM]);
1630  l.l_to = ecpyalloc(fields[LF_TO]);
1631  links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
1632  links[nlinks++] = l;
1633 }
static ptrdiff_t nlinks
Definition: zic.c:286
static char * ecpyalloc(char const *str)
Definition: zic.c:431
#define LF_TO
Definition: zic.c:246
static const char * filename
Definition: zic.c:168
static lineno_t linenum
Definition: zic.c:173
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
Definition: zic.c:437
static ptrdiff_t nlinks_alloc
Definition: zic.c:287
#define LF_FROM
Definition: zic.c:245
static struct link * links
Definition: zic.c:285
#define LINK_FIELDS
Definition: zic.c:247
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84
static bool namecheck(const char *name)
Definition: zic.c:776

◆ inrule()

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

Definition at line 1315 of file zic.c.

References _, ecpyalloc(), error(), filename, gethms(), growalloc(), linenum, rule::r_abbrvar, rule::r_filename, 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().

1316 {
1317  static struct rule r;
1318 
1319  if (nfields != RULE_FIELDS)
1320  {
1321  error(_("wrong number of fields on Rule line"));
1322  return;
1323  }
1324  if (*fields[RF_NAME] == '\0')
1325  {
1326  error(_("nameless rule"));
1327  return;
1328  }
1329  r.r_filename = filename;
1330  r.r_linenum = linenum;
1331  r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), true);
1332  rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
1333  fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
1334  r.r_name = ecpyalloc(fields[RF_NAME]);
1335  r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
1336  if (max_abbrvar_len < strlen(r.r_abbrvar))
1337  max_abbrvar_len = strlen(r.r_abbrvar);
1338  rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc);
1339  rules[nrules++] = r;
1340 }
static char * ecpyalloc(char const *str)
Definition: zic.c:431
#define RF_COMMAND
Definition: zic.c:233
Definition: localtime.c:78
static const char * filename
Definition: zic.c:168
static lineno_t linenum
Definition: zic.c:173
static int max_abbrvar_len
Definition: zic.c:174
static struct rule * rules
Definition: zic.c:269
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
Definition: zic.c:437
static zic_t gethms(const char *string, const char *errstring, bool)
Definition: zic.c:1262
#define RF_HIYEAR
Definition: zic.c:232
#define RF_NAME
Definition: zic.c:230
static ptrdiff_t nrules_alloc
Definition: zic.c:271
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:1636
static ptrdiff_t nrules
Definition: zic.c:270
#define RF_TOD
Definition: zic.c:236
#define RF_ABBRVAR
Definition: zic.c:238
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define RF_LOYEAR
Definition: zic.c:231
#define _(x)
Definition: elog.c:84
#define RULE_FIELDS
Definition: zic.c:239
#define RF_MONTH
Definition: zic.c:234
#define RF_STDOFF
Definition: zic.c:237
#define RF_DAY
Definition: zic.c:235

◆ inzcont()

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

Definition at line 1381 of file zic.c.

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

Referenced by infile().

1382 {
1383  if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS)
1384  {
1385  error(_("wrong number of fields on Zone continuation line"));
1386  return false;
1387  }
1388  return inzsub(fields, nfields, true);
1389 }
#define ZONEC_MAXFIELDS
Definition: zic.c:224
static bool inzsub(char **, int, bool)
Definition: zic.c:1392
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84

◆ inzone()

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

Definition at line 1343 of file zic.c.

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

Referenced by infile().

1344 {
1345  ptrdiff_t i;
1346 
1347  if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS)
1348  {
1349  error(_("wrong number of fields on Zone line"));
1350  return false;
1351  }
1352  if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL)
1353  {
1354  error(
1355  _("\"Zone %s\" line and -l option are mutually exclusive"),
1356  TZDEFAULT);
1357  return false;
1358  }
1359  if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL)
1360  {
1361  error(
1362  _("\"Zone %s\" line and -p option are mutually exclusive"),
1363  TZDEFRULES);
1364  return false;
1365  }
1366  for (i = 0; i < nzones; ++i)
1367  if (zones[i].z_name != NULL &&
1368  strcmp(zones[i].z_name, fields[ZF_NAME]) == 0)
1369  {
1370  error(_("duplicate zone name %s"
1371  " (file \"%s\", line %d)"),
1372  fields[ZF_NAME],
1373  zones[i].z_filename,
1374  zones[i].z_linenum);
1375  return false;
1376  }
1377  return inzsub(fields, nfields, false);
1378 }
#define TZDEFAULT
Definition: tzfile.h:24
#define ZF_NAME
Definition: zic.c:201
static ptrdiff_t nzones
Definition: zic.c:274
static const char * psxrules
Definition: zic.c:565
static bool inzsub(char **, int, bool)
Definition: zic.c:1392
#define ZONE_MAXFIELDS
Definition: zic.c:210
static const char * lcltime
Definition: zic.c:566
#define TZDEFRULES
Definition: tzfile.h:25
static struct zone * zones
Definition: zic.c:273
int i
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84

◆ inzsub()

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

Definition at line 1392 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().

1393 {
1394  char *cp;
1395  char *cp1;
1396  static struct zone z;
1397  int i_gmtoff,
1398  i_rule,
1399  i_format;
1400  int i_untilyear,
1401  i_untilmonth;
1402  int i_untilday,
1403  i_untiltime;
1404  bool hasuntil;
1405 
1406  if (iscont)
1407  {
1408  i_gmtoff = ZFC_GMTOFF;
1409  i_rule = ZFC_RULE;
1410  i_format = ZFC_FORMAT;
1411  i_untilyear = ZFC_TILYEAR;
1412  i_untilmonth = ZFC_TILMONTH;
1413  i_untilday = ZFC_TILDAY;
1414  i_untiltime = ZFC_TILTIME;
1415  z.z_name = NULL;
1416  }
1417  else if (!namecheck(fields[ZF_NAME]))
1418  return false;
1419  else
1420  {
1421  i_gmtoff = ZF_GMTOFF;
1422  i_rule = ZF_RULE;
1423  i_format = ZF_FORMAT;
1424  i_untilyear = ZF_TILYEAR;
1425  i_untilmonth = ZF_TILMONTH;
1426  i_untilday = ZF_TILDAY;
1427  i_untiltime = ZF_TILTIME;
1428  z.z_name = ecpyalloc(fields[ZF_NAME]);
1429  }
1430  z.z_filename = filename;
1431  z.z_linenum = linenum;
1432  z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset"), true);
1433  if ((cp = strchr(fields[i_format], '%')) != NULL)
1434  {
1435  if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
1436  || strchr(fields[i_format], '/'))
1437  {
1438  error(_("invalid abbreviation format"));
1439  return false;
1440  }
1441  }
1442  z.z_rule = ecpyalloc(fields[i_rule]);
1443  z.z_format = cp1 = ecpyalloc(fields[i_format]);
1444  z.z_format_specifier = cp ? *cp : '\0';
1445  if (z.z_format_specifier == 'z')
1446  {
1447  if (noise)
1448  warning(_("format '%s' not handled by pre-2015 versions of zic"),
1449  z.z_format);
1450  cp1[cp - fields[i_format]] = 's';
1451  }
1452  if (max_format_len < strlen(z.z_format))
1453  max_format_len = strlen(z.z_format);
1454  hasuntil = nfields > i_untilyear;
1455  if (hasuntil)
1456  {
1457  z.z_untilrule.r_filename = filename;
1458  z.z_untilrule.r_linenum = linenum;
1459  rulesub(&z.z_untilrule,
1460  fields[i_untilyear],
1461  "only",
1462  "",
1463  (nfields > i_untilmonth) ?
1464  fields[i_untilmonth] : "Jan",
1465  (nfields > i_untilday) ? fields[i_untilday] : "1",
1466  (nfields > i_untiltime) ? fields[i_untiltime] : "0");
1467  z.z_untiltime = rpytime(&z.z_untilrule,
1468  z.z_untilrule.r_loyear);
1469  if (iscont && nzones > 0 &&
1470  z.z_untiltime > min_time &&
1471  z.z_untiltime < max_time &&
1472  zones[nzones - 1].z_untiltime > min_time &&
1473  zones[nzones - 1].z_untiltime < max_time &&
1474  zones[nzones - 1].z_untiltime >= z.z_untiltime)
1475  {
1476  error(_("Zone continuation line end time is not after end time of previous line"));
1477  return false;
1478  }
1479  }
1480  zones = growalloc(zones, sizeof *zones, nzones, &nzones_alloc);
1481  zones[nzones++] = z;
1482 
1483  /*
1484  * If there was an UNTIL field on this line, there's more information
1485  * about the zone on the next line.
1486  */
1487  return hasuntil;
1488 }
#define ZF_TILMONTH
Definition: zic.c:206
#define ZF_TILTIME
Definition: zic.c:208
#define ZF_TILYEAR
Definition: zic.c:205
#define ZF_NAME
Definition: zic.c:201
#define ZFC_TILMONTH
Definition: zic.c:220
static char * ecpyalloc(char const *str)
Definition: zic.c:431
#define ZF_RULE
Definition: zic.c:203
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
zic_t z_untiltime
Definition: zic.c:109
static ptrdiff_t nzones
Definition: zic.c:274
#define ZF_GMTOFF
Definition: zic.c:202
#define ZFC_FORMAT
Definition: zic.c:218
static int max_format_len
Definition: zic.c:175
static const char * filename
Definition: zic.c:168
#define ZF_FORMAT
Definition: zic.c:204
static lineno_t linenum
Definition: zic.c:173
static ptrdiff_t nzones_alloc
Definition: zic.c:275
#define ZFC_TILTIME
Definition: zic.c:222
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
Definition: zic.c:437
#define ZFC_RULE
Definition: zic.c:217
static zic_t rpytime(const struct rule *rp, zic_t wantedy)
Definition: zic.c:3533
static zic_t gethms(const char *string, const char *errstring, bool)
Definition: zic.c:1262
#define ZF_TILDAY
Definition: zic.c:207
static zic_t const max_time
Definition: zic.c:975
static bool noise
Definition: zic.c:178
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:1636
static struct zone * zones
Definition: zic.c:273
Definition: zic.c:92
#define ZFC_TILDAY
Definition: zic.c:221
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
static zic_t const min_time
Definition: zic.c:974
#define ZFC_TILYEAR
Definition: zic.c:219
#define _(x)
Definition: elog.c:84
#define ZFC_GMTOFF
Definition: zic.c:216
static bool namecheck(const char *name)
Definition: zic.c:776

◆ is32()

static bool is32 ( const zic_t  x)
static

Definition at line 1861 of file zic.c.

Referenced by writezone().

1862 {
1863  return x == ((zic_t) ((int32) x));
1864 }
signed int int32
Definition: c.h:284
int64 zic_t
Definition: zic.c:23

◆ is_alpha()

static bool is_alpha ( char  a)
static

Definition at line 3218 of file zic.c.

Referenced by doabbr(), and newabbr().

3219 {
3220  switch (a)
3221  {
3222  default:
3223  return false;
3224  case 'A':
3225  case 'B':
3226  case 'C':
3227  case 'D':
3228  case 'E':
3229  case 'F':
3230  case 'G':
3231  case 'H':
3232  case 'I':
3233  case 'J':
3234  case 'K':
3235  case 'L':
3236  case 'M':
3237  case 'N':
3238  case 'O':
3239  case 'P':
3240  case 'Q':
3241  case 'R':
3242  case 'S':
3243  case 'T':
3244  case 'U':
3245  case 'V':
3246  case 'W':
3247  case 'X':
3248  case 'Y':
3249  case 'Z':
3250  case 'a':
3251  case 'b':
3252  case 'c':
3253  case 'd':
3254  case 'e':
3255  case 'f':
3256  case 'g':
3257  case 'h':
3258  case 'i':
3259  case 'j':
3260  case 'k':
3261  case 'l':
3262  case 'm':
3263  case 'n':
3264  case 'o':
3265  case 'p':
3266  case 'q':
3267  case 'r':
3268  case 's':
3269  case 't':
3270  case 'u':
3271  case 'v':
3272  case 'w':
3273  case 'x':
3274  case 'y':
3275  case 'z':
3276  return true;
3277  }
3278 }

◆ is_space()

static bool is_space ( char  a)
static

Definition at line 3200 of file zic.c.

Referenced by getfields().

3201 {
3202  switch (a)
3203  {
3204  default:
3205  return false;
3206  case ' ':
3207  case '\f':
3208  case '\n':
3209  case '\r':
3210  case '\t':
3211  case '\v':
3212  return true;
3213  }
3214 }

◆ itsabbr()

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

Definition at line 3355 of file zic.c.

References lowerit(), and word().

Referenced by byword().

3356 {
3357  if (lowerit(*abbr) != lowerit(*word))
3358  return false;
3359  ++word;
3360  while (*++abbr != '\0')
3361  do
3362  {
3363  if (*word == '\0')
3364  return false;
3365  } while (lowerit(*word++) != lowerit(*abbr));
3366  return true;
3367 }
static char lowerit(char)
Definition: zic.c:3283
static void word(struct vars *, int, struct state *, struct state *)
Definition: regcomp.c:1243

◆ itsdir()

static bool itsdir ( char const *  name)
static

Definition at line 1021 of file zic.c.

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

Referenced by dolink(), and mkdirs().

1022 {
1023  struct stat st;
1024  int res = stat(name, &st);
1025 #ifdef S_ISDIR
1026  if (res == 0)
1027  return S_ISDIR(st.st_mode) != 0;
1028 #endif
1029  if (res == 0 || errno == EOVERFLOW)
1030  {
1031  size_t n = strlen(name);
1032  char *nameslashdot = emalloc(n + 3);
1033  bool dir;
1034 
1035  memcpy(nameslashdot, name, n);
1036  strcpy(&nameslashdot[n], &"/."[!(n && name[n - 1] != '/')]);
1037  dir = stat(nameslashdot, &st) == 0 || errno == EOVERFLOW;
1038  free(nameslashdot);
1039  return dir;
1040  }
1041  return false;
1042 }
#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:419

◆ itssymlink()

static bool itssymlink ( char const *  name)
static

Definition at line 1046 of file zic.c.

References readlink.

Referenced by dolink().

1047 {
1048 #ifdef HAVE_SYMLINK
1049  char c;
1050 
1051  return 0 <= readlink(name, &c, 1);
1052 #else
1053  return false;
1054 #endif
1055 }
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 3099 of file zic.c.

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

Referenced by inleap().

3100 {
3101  int i,
3102  j;
3103 
3104  if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS)
3105  {
3106  error(_("too many leap seconds"));
3107  exit(EXIT_FAILURE);
3108  }
3109  for (i = 0; i < leapcnt; ++i)
3110  if (t <= trans[i])
3111  break;
3112  do
3113  {
3114  for (j = leapcnt; j > i; --j)
3115  {
3116  trans[j] = trans[j - 1];
3117  corr[j] = corr[j - 1];
3118  roll[j] = roll[j - 1];
3119  }
3120  trans[i] = t;
3121  corr[i] = positive ? 1 : -count;
3122  roll[i] = rolling;
3123  ++leapcnt;
3124  } while (positive && --count != 0);
3125 }
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:388
#define TZ_MAX_LEAPS
Definition: tzfile.h:101
static int leapcnt
Definition: zic.c:169
static zic_t trans[TZ_MAX_LEAPS]
Definition: zic.c:387
int i
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84
static char roll[TZ_MAX_LEAPS]
Definition: zic.c:389

◆ link()

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

◆ lowerit()

static char lowerit ( char  a)
static

Definition at line 3283 of file zic.c.

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

3284 {
3285  switch (a)
3286  {
3287  default:
3288  return a;
3289  case 'A':
3290  return 'a';
3291  case 'B':
3292  return 'b';
3293  case 'C':
3294  return 'c';
3295  case 'D':
3296  return 'd';
3297  case 'E':
3298  return 'e';
3299  case 'F':
3300  return 'f';
3301  case 'G':
3302  return 'g';
3303  case 'H':
3304  return 'h';
3305  case 'I':
3306  return 'i';
3307  case 'J':
3308  return 'j';
3309  case 'K':
3310  return 'k';
3311  case 'L':
3312  return 'l';
3313  case 'M':
3314  return 'm';
3315  case 'N':
3316  return 'n';
3317  case 'O':
3318  return 'o';
3319  case 'P':
3320  return 'p';
3321  case 'Q':
3322  return 'q';
3323  case 'R':
3324  return 'r';
3325  case 'S':
3326  return 's';
3327  case 'T':
3328  return 't';
3329  case 'U':
3330  return 'u';
3331  case 'V':
3332  return 'v';
3333  case 'W':
3334  return 'w';
3335  case 'X':
3336  return 'x';
3337  case 'Y':
3338  return 'y';
3339  case 'Z':
3340  return 'z';
3341  }
3342 }

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 572 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.

573 {
574  int c,
575  k;
576  ptrdiff_t i,
577  j;
578 
579 #ifndef WIN32
580  umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
581 #endif
582  progname = argv[0];
583  if (TYPE_BIT(zic_t) <64)
584  {
585  fprintf(stderr, "%s: %s\n", progname,
586  _("wild compilation-time specification of zic_t"));
587  return EXIT_FAILURE;
588  }
589  for (k = 1; k < argc; k++)
590  if (strcmp(argv[k], "--version") == 0)
591  {
592  printf("zic %s\n", PG_VERSION);
593  close_file(stdout, NULL, NULL);
594  return EXIT_SUCCESS;
595  }
596  else if (strcmp(argv[k], "--help") == 0)
597  {
598  usage(stdout, EXIT_SUCCESS);
599  }
600  while ((c = getopt(argc, argv, "d:l:p:L:vPsy:")) != EOF && c != -1)
601  switch (c)
602  {
603  default:
604  usage(stderr, EXIT_FAILURE);
605  case 'd':
606  if (directory == NULL)
607  directory = strdup(optarg);
608  else
609  {
610  fprintf(stderr,
611  _("%s: More than one -d option specified\n"),
612  progname);
613  return EXIT_FAILURE;
614  }
615  break;
616  case 'l':
617  if (lcltime == NULL)
618  lcltime = strdup(optarg);
619  else
620  {
621  fprintf(stderr,
622  _("%s: More than one -l option specified\n"),
623  progname);
624  return EXIT_FAILURE;
625  }
626  break;
627  case 'p':
628  if (psxrules == NULL)
629  psxrules = strdup(optarg);
630  else
631  {
632  fprintf(stderr,
633  _("%s: More than one -p option specified\n"),
634  progname);
635  return EXIT_FAILURE;
636  }
637  break;
638  case 'y':
639  if (yitcommand == NULL)
640  {
641  warning(_("-y is obsolescent"));
642  yitcommand = strdup(optarg);
643  }
644  else
645  {
646  fprintf(stderr,
647  _("%s: More than one -y option specified\n"),
648  progname);
649  return EXIT_FAILURE;
650  }
651  break;
652  case 'L':
653  if (leapsec == NULL)
654  leapsec = strdup(optarg);
655  else
656  {
657  fprintf(stderr,
658  _("%s: More than one -L option specified\n"),
659  progname);
660  return EXIT_FAILURE;
661  }
662  break;
663  case 'v':
664  noise = true;
665  break;
666  case 'P':
667  print_abbrevs = true;
668  print_cutoff = time(NULL);
669  break;
670  case 's':
671  warning(_("-s ignored"));
672  break;
673  }
674  if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
675  usage(stderr, EXIT_FAILURE); /* usage message by request */
676  if (directory == NULL)
677  directory = "data";
678  if (yitcommand == NULL)
679  yitcommand = "yearistype";
680 
681  if (optind < argc && leapsec != NULL)
682  {
683  infile(leapsec);
684  adjleap();
685  }
686 
687  for (k = optind; k < argc; k++)
688  infile(argv[k]);
689  if (errors)
690  return EXIT_FAILURE;
691  associate();
693  for (i = 0; i < nzones; i = j)
694  {
695  /*
696  * Find the next non-continuation zone entry.
697  */
698  for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
699  continue;
700  outzone(&zones[i], j - i);
701  }
702 
703  /*
704  * Make links.
705  */
706  for (i = 0; i < nlinks; ++i)
707  {
708  eat(links[i].l_filename, links[i].l_linenum);
709  dolink(links[i].l_from, links[i].l_to, false);
710  if (noise)
711  for (j = 0; j < nlinks; ++j)
712  if (strcmp(links[i].l_to,
713  links[j].l_from) == 0)
714  warning(_("link to link"));
715  }
716  if (lcltime != NULL)
717  {
718  eat(_("command line"), 1);
719  dolink(lcltime, TZDEFAULT, true);
720  }
721  if (psxrules != NULL)
722  {
723  eat(_("command line"), 1);
724  dolink(psxrules, TZDEFRULES, true);
725  }
726  if (warnings && (ferror(stderr) || fclose(stderr) != 0))
727  return EXIT_FAILURE;
728  return errors ? EXIT_FAILURE : EXIT_SUCCESS;
729 }
#define TZDEFAULT
Definition: tzfile.h:24
static ptrdiff_t nlinks
Definition: zic.c:286
static bool print_abbrevs
Definition: zic.c:179
static zic_t print_cutoff
Definition: zic.c:180
static void change_directory(char const *dir)
Definition: zic.c:545
#define EXIT_SUCCESS
Definition: settings.h:148
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
static bool errors
Definition: zic.c:166
static void associate(void)
Definition: zic.c:1073
#define S_IWOTH
Definition: win32_port.h:298
static ptrdiff_t nzones
Definition: zic.c:274
static const char * yitcommand
Definition: zic.c:569
static bool warnings
Definition: zic.c:167
static const char * leapsec
Definition: zic.c:568
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: getopt.c:72
static const char * psxrules
Definition: zic.c:565
static void static void static void static void usage(FILE *stream, int status) pg_attribute_noreturn()
Definition: zic.c:528
static void dolink(const char *, const char *, bool)
Definition: zic.c:877
int optind
Definition: getopt.c:51
char * c
static void adjleap(void)
Definition: zic.c:3128
static const char * lcltime
Definition: zic.c:566
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:467
static bool noise
Definition: zic.c:178
static struct link * links
Definition: zic.c:285
static void infile(const char *filename)
Definition: zic.c:1159
static const char * progname
Definition: zic.c:183
#define TZDEFRULES
Definition: tzfile.h:25
static const char * directory
Definition: zic.c:567
const char * z_name
Definition: zic.c:97
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:512
static struct zone * zones
Definition: zic.c:273
static void outzone(const struct zone *zp, ptrdiff_t ntzones)
Definition: zic.c:2649
char * optarg
Definition: getopt.c:53
#define TYPE_BIT(type)
Definition: private.h:49
int i
#define EXIT_FAILURE
Definition: settings.h:152
#define _(x)
Definition: elog.c:84

◆ memcheck()

static void* memcheck ( void *  ptr)
static

Definition at line 411 of file zic.c.

References memory_exhausted(), and strerror().

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

412 {
413  if (ptr == NULL)
414  memory_exhausted(strerror(errno));
415  return ptr;
416 }
const char * strerror(int errnum)
Definition: strerror.c:19
static void memory_exhausted(const char *msg) pg_attribute_noreturn()
Definition: zic.c:396

◆ memory_exhausted()

static void memory_exhausted ( const char *  msg)
static

Definition at line 396 of file zic.c.

References _, and EXIT_FAILURE.

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

397 {
398  fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, msg);
399  exit(EXIT_FAILURE);
400 }
static const char * progname
Definition: zic.c:183
#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 3669 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().

3670 {
3671  char *name;
3672  char *cp;
3673 
3674  cp = name = ecpyalloc(argname);
3675 
3676  /*
3677  * On MS-Windows systems, do not worry about drive letters or backslashes,
3678  * as this should suffice in practice. Time zone names do not use drive
3679  * letters and backslashes. If the -d option of zic does not name an
3680  * already-existing directory, it can use slashes to separate the
3681  * already-existing ancestor prefix from the to-be-created subdirectories.
3682  */
3683 
3684  /* Do not mkdir a root directory, as it must exist. */
3685  while (*cp == '/')
3686  cp++;
3687 
3688  while (cp && ((cp = strchr(cp, '/')) || !ancestors))
3689  {
3690  if (cp)
3691  *cp = '\0';
3692 
3693  /*
3694  * Try to create it. It's OK if creation fails because the directory
3695  * already exists, perhaps because some other process just created it.
3696  * For simplicity do not check first whether it already exists, as
3697  * that is checked anyway if the mkdir fails.
3698  */
3699  if (mkdir(name, MKDIR_UMASK) != 0)
3700  {
3701  /*
3702  * For speed, skip itsdir if errno == EEXIST. Since mkdirs is
3703  * called only after open fails with ENOENT on a subfile, EEXIST
3704  * implies itsdir here.
3705  */
3706  int err = errno;
3707 
3708  if (err != EEXIST && !itsdir(name))
3709  {
3710  error(_("%s: Cannot create directory %s: %s"),
3711  progname, name, strerror(err));
3712  exit(EXIT_FAILURE);
3713  }
3714  }
3715  if (cp)
3716  *cp++ = '/';
3717  }
3718  free(name);
3719 }
static char * ecpyalloc(char const *str)
Definition: zic.c:431
static bool itsdir(char const *)
Definition: zic.c:1021
static const char * progname
Definition: zic.c:183
#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:489
#define _(x)
Definition: elog.c:84

◆ namecheck()

static bool namecheck ( const char *  name)
static

Definition at line 776 of file zic.c.

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

Referenced by inlink(), and inzsub().

777 {
778  char const *cp;
779 
780  /* Benign characters in a portable file name. */
781  static char const benign[] =
782  "-/_"
783  "abcdefghijklmnopqrstuvwxyz"
784  "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
785 
786  /*
787  * Non-control chars in the POSIX portable character set, excluding the
788  * benign characters.
789  */
790  static char const printable_and_not_benign[] =
791  " !\"#$%&'()*+,.0123456789:;<=>?@[\\]^`{|}~";
792 
793  char const *component = name;
794 
795  for (cp = name; *cp; cp++)
796  {
797  unsigned char c = *cp;
798 
799  if (noise && !strchr(benign, c))
800  {
801  warning((strchr(printable_and_not_benign, c)
802  ? _("file name '%s' contains byte '%c'")
803  : _("file name '%s' contains byte '\\%o'")),
804  name, c);
805  }
806  if (c == '/')
807  {
808  if (!componentcheck(name, component, cp))
809  return false;
810  component = cp + 1;
811  }
812  }
813  return componentcheck(name, component, cp);
814 }
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
static bool componentcheck(char const *name, char const *component, char const *component_end)
Definition: zic.c:732
char * c
static bool noise
Definition: zic.c:178
const char * name
Definition: encode.c:521
#define _(x)
Definition: elog.c:84

◆ newabbr()

static void newabbr ( const char *  abbr)
static

Definition at line 3631 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().

3632 {
3633  int i;
3634 
3635  if (strcmp(string, GRANDPARENTED) != 0)
3636  {
3637  const char *cp;
3638  const char *mp;
3639 
3640  cp = string;
3641  mp = NULL;
3642  while (is_alpha(*cp) || ('0' <= *cp && *cp <= '9')
3643  || *cp == '-' || *cp == '+')
3644  ++cp;
3645  if (noise && cp - string < 3)
3646  mp = _("time zone abbreviation has fewer than 3 characters");
3647  if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN)
3648  mp = _("time zone abbreviation has too many characters");
3649  if (*cp != '\0')
3650  mp = _("time zone abbreviation differs from POSIX standard");
3651  if (mp != NULL)
3652  warning("%s (%s)", mp, string);
3653  }
3654  i = strlen(string) + 1;
3655  if (charcnt + i > TZ_MAX_CHARS)
3656  {
3657  error(_("too many, or too long, time zone abbreviations"));
3658  exit(EXIT_FAILURE);
3659  }
3660  strcpy(&chars[charcnt], string);
3661  charcnt += i;
3662 }
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
#define GRANDPARENTED
Definition: private.h:27
static bool is_alpha(char a)
Definition: zic.c:3218
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:178
static int charcnt
Definition: zic.c:165
int i
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
static char chars[TZ_MAX_CHARS]
Definition: zic.c:386
#define _(x)
Definition: elog.c:84

◆ oadd()

static zic_t oadd ( zic_t  t1,
zic_t  t2 
)
static

Definition at line 3496 of file zic.c.

References time_overflow(), ZIC_MAX, and ZIC_MIN.

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

3497 {
3498  if (t1 < 0 ? t2 < ZIC_MIN - t1 : ZIC_MAX - t1 < t2)
3499  time_overflow();
3500  return t1 + t2;
3501 }
#define ZIC_MAX
Definition: zic.c:25
#define ZIC_MIN
Definition: zic.c:24
static void time_overflow(void)
Definition: zic.c:3489

◆ outzone()

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

Definition at line 2649 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_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_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().

2650 {
2651  const struct zone *zp;
2652  struct rule *rp;
2653  ptrdiff_t i,
2654  j;
2655  bool usestart,
2656  useuntil;
2657  zic_t starttime,
2658  untiltime;
2659  zic_t gmtoff;
2660  zic_t stdoff;
2661  zic_t year;
2662  zic_t startoff;
2663  bool startttisstd;
2664  bool startttisgmt;
2665  int type;
2666  char *startbuf;
2667  char *ab;
2668  char *envvar;
2669  int max_abbr_len;
2670  int max_envvar_len;
2671  bool prodstic; /* all rules are min to max */
2672  int compat;
2673  bool do_extend;
2674  char version;
2675  ptrdiff_t lastatmax = -1;
2676  zic_t one = 1;
2677  zic_t y2038_boundary = one << 31;
2678  zic_t max_year0;
2679 
2680  max_abbr_len = 2 + max_format_len + max_abbrvar_len;
2681  max_envvar_len = 2 * max_abbr_len + 5 * 9;
2682  startbuf = emalloc(max_abbr_len + 1);
2683  ab = emalloc(max_abbr_len + 1);
2684  envvar = emalloc(max_envvar_len + 1);
2685  INITIALIZE(untiltime);
2686  INITIALIZE(starttime);
2687 
2688  /*
2689  * Now. . .finally. . .generate some useful data!
2690  */
2691  timecnt = 0;
2692  typecnt = 0;
2693  charcnt = 0;
2694  prodstic = zonecount == 1;
2695 
2696  /*
2697  * Thanks to Earl Chew for noting the need to unconditionally initialize
2698  * startttisstd.
2699  */
2700  startttisstd = false;
2701  startttisgmt = false;
2703  if (leapseen)
2704  {
2707  }
2708  for (i = 0; i < zonecount; ++i)
2709  {
2710  zp = &zpfirst[i];
2711  if (i < zonecount - 1)
2713  for (j = 0; j < zp->z_nrules; ++j)
2714  {
2715  rp = &zp->z_rules[j];
2716  if (rp->r_lowasnum)
2717  updateminmax(rp->r_loyear);
2718  if (rp->r_hiwasnum)
2719  updateminmax(rp->r_hiyear);
2720  if (rp->r_lowasnum || rp->r_hiwasnum)
2721  prodstic = false;
2722  }
2723  }
2724 
2725  /*
2726  * Generate lots of data if a rule can't cover all future times.
2727  */
2728  compat = stringzone(envvar, zpfirst, zonecount);
2729  version = compat < 2013 ? ZIC_VERSION_PRE_2013 : ZIC_VERSION;
2730  do_extend = compat < 0 || compat == YEAR_BY_YEAR_ZONE;
2731  if (noise)
2732  {
2733  if (!*envvar)
2734  warning("%s %s",
2735  _("no POSIX environment variable for zone"),
2736  zpfirst->z_name);
2737  else if (compat != 0 && compat != YEAR_BY_YEAR_ZONE)
2738  {
2739  /*
2740  * Circa-COMPAT clients, and earlier clients, might not work for
2741  * this zone when given dates before 1970 or after 2038.
2742  */
2743  warning(_("%s: pre-%d clients may mishandle"
2744  " distant timestamps"),
2745  zpfirst->z_name, compat);
2746  }
2747  }
2748  if (do_extend)
2749  {
2750  /*
2751  * Search through a couple of extra years past the obvious 400, to
2752  * avoid edge cases. For example, suppose a non-POSIX rule applies
2753  * from 2012 onwards and has transitions in March and September, plus
2754  * some one-off transitions in November 2013. If zic looked only at
2755  * the last 400 years, it would set max_year=2413, with the intent
2756  * that the 400 years 2014 through 2413 will be repeated. The last
2757  * transition listed in the tzfile would be in 2413-09, less than 400
2758  * years after the last one-off transition in 2013-11. Two years
2759  * might be overkill, but with the kind of edge cases available we're
2760  * not sure that one year would suffice.
2761  */
2762  enum
2763  {
2764  years_of_observations = YEARSPERREPEAT + 2};
2765 
2766  if (min_year >= ZIC_MIN + years_of_observations)
2767  min_year -= years_of_observations;
2768  else
2769  min_year = ZIC_MIN;
2770  if (max_year <= ZIC_MAX - years_of_observations)
2771  max_year += years_of_observations;
2772  else
2773  max_year = ZIC_MAX;
2774 
2775  /*
2776  * Regardless of any of the above, for a "proDSTic" zone which
2777  * specifies that its rules always have and always will be in effect,
2778  * we only need one cycle to define the zone.
2779  */
2780  if (prodstic)
2781  {
2782  min_year = 1900;
2783  max_year = min_year + years_of_observations;
2784  }
2785  }
2786 
2787  /*
2788  * For the benefit of older systems, generate data from 1900 through 2038.
2789  */
2790  if (min_year > 1900)
2791  min_year = 1900;
2792  max_year0 = max_year;
2793  if (max_year < 2038)
2794  max_year = 2038;
2795  for (i = 0; i < zonecount; ++i)
2796  {
2797  /*
2798  * A guess that may well be corrected later.
2799  */
2800  stdoff = 0;
2801  zp = &zpfirst[i];
2802  usestart = i > 0 && (zp - 1)->z_untiltime > early_time;
2803  useuntil = i < (zonecount - 1);
2804  if (useuntil && zp->z_untiltime <= early_time)
2805  continue;
2806  gmtoff = zp->z_gmtoff;
2807  eat(zp->z_filename, zp->z_linenum);
2808  *startbuf = '\0';
2809  startoff = zp->z_gmtoff;
2810  if (zp->z_nrules == 0)
2811  {
2812  stdoff = zp->z_stdoff;
2813  doabbr(startbuf, zp, NULL, stdoff, false);
2814  type = addtype(oadd(zp->z_gmtoff, stdoff),
2815  startbuf, stdoff != 0, startttisstd,
2816  startttisgmt);
2817  if (usestart)
2818  {
2819  addtt(starttime, type);
2820  usestart = false;
2821  }
2822  else
2823  addtt(early_time, type);
2824  }
2825  else
2826  for (year = min_year; year <= max_year; ++year)
2827  {
2828  if (useuntil && year > zp->z_untilrule.r_hiyear)
2829  break;
2830 
2831  /*
2832  * Mark which rules to do in the current year. For those to
2833  * do, calculate rpytime(rp, year);
2834  */
2835  for (j = 0; j < zp->z_nrules; ++j)
2836  {
2837  rp = &zp->z_rules[j];
2838  eats(zp->z_filename, zp->z_linenum,
2839  rp->r_filename, rp->r_linenum);
2840  rp->r_todo = year >= rp->r_loyear &&
2841  year <= rp->r_hiyear &&
2842  yearistype(year, rp->r_yrtype);
2843  if (rp->r_todo)
2844  {
2845  rp->r_temp = rpytime(rp, year);
2846  rp->r_todo
2847  = (rp->r_temp < y2038_boundary
2848  || year <= max_year0);
2849  }
2850  }
2851  for (;;)
2852  {
2853  ptrdiff_t k;
2854  zic_t jtime,
2855  ktime;
2856  zic_t offset;
2857 
2858  INITIALIZE(ktime);
2859  if (useuntil)
2860  {
2861  /*
2862  * Turn untiltime into UT assuming the current gmtoff
2863  * and stdoff values.
2864  */
2865  untiltime = zp->z_untiltime;
2866  if (!zp->z_untilrule.r_todisgmt)
2867  untiltime = tadd(untiltime,
2868  -gmtoff);
2869  if (!zp->z_untilrule.r_todisstd)
2870  untiltime = tadd(untiltime,
2871  -stdoff);
2872  }
2873 
2874  /*
2875  * Find the rule (of those to do, if any) that takes
2876  * effect earliest in the year.
2877  */
2878  k = -1;
2879  for (j = 0; j < zp->z_nrules; ++j)
2880  {
2881  rp = &zp->z_rules[j];
2882  if (!rp->r_todo)
2883  continue;
2884  eats(zp->z_filename, zp->z_linenum,
2885  rp->r_filename, rp->r_linenum);
2886  offset = rp->r_todisgmt ? 0 : gmtoff;
2887  if (!rp->r_todisstd)
2888  offset = oadd(offset, stdoff);
2889  jtime = rp->r_temp;
2890  if (jtime == min_time ||
2891  jtime == max_time)
2892  continue;
2893  jtime = tadd(jtime, -offset);
2894  if (k < 0 || jtime < ktime)
2895  {
2896  k = j;
2897  ktime = jtime;
2898  }
2899  else if (jtime == ktime)
2900  {
2901  char const *dup_rules_msg =
2902  _("two rules for same instant");
2903 
2904  eats(zp->z_filename, zp->z_linenum,
2905  rp->r_filename, rp->r_linenum);
2906  warning("%s", dup_rules_msg);
2907  rp = &zp->z_rules[k];
2908  eats(zp->z_filename, zp->z_linenum,
2909  rp->r_filename, rp->r_linenum);
2910  error("%s", dup_rules_msg);
2911  }
2912  }
2913  if (k < 0)
2914  break; /* go on to next year */
2915  rp = &zp->z_rules[k];
2916  rp->r_todo = false;
2917  if (useuntil && ktime >= untiltime)
2918  break;
2919  stdoff = rp->r_stdoff;
2920  if (usestart && ktime == starttime)
2921  usestart = false;
2922  if (usestart)
2923  {
2924  if (ktime < starttime)
2925  {
2926  startoff = oadd(zp->z_gmtoff,
2927  stdoff);
2928  doabbr(startbuf, zp,
2929  rp->r_abbrvar,
2930  rp->r_stdoff,
2931  false);
2932  continue;
2933  }
2934  if (*startbuf == '\0' &&
2935  startoff == oadd(zp->z_gmtoff,
2936  stdoff))
2937  {
2938  doabbr(startbuf,
2939  zp,
2940  rp->r_abbrvar,
2941  rp->r_stdoff,
2942  false);
2943  }
2944  }
2945  eats(zp->z_filename, zp->z_linenum,
2946  rp->r_filename, rp->r_linenum);
2947  doabbr(ab, zp, rp->r_abbrvar,
2948  rp->r_stdoff, false);
2949  offset = oadd(zp->z_gmtoff, rp->r_stdoff);
2950  type = addtype(offset, ab, rp->r_stdoff != 0,
2951  rp->r_todisstd, rp->r_todisgmt);
2952  if (rp->r_hiyear == ZIC_MAX
2953  && !(0 <= lastatmax
2954  && ktime < attypes[lastatmax].at))
2955  lastatmax = timecnt;
2956  addtt(ktime, type);
2957  }
2958  }
2959  if (usestart)
2960  {
2961  if (*startbuf == '\0' &&
2962  zp->z_format != NULL &&
2963  strchr(zp->z_format, '%') == NULL &&
2964  strchr(zp->z_format, '/') == NULL)
2965  strcpy(startbuf, zp->z_format);
2966  eat(zp->z_filename, zp->z_linenum);
2967  if (*startbuf == '\0')
2968  error(_("cannot determine time zone abbreviation to use just after until time"));
2969  else
2970  addtt(starttime,
2971  addtype(startoff, startbuf,
2972  startoff != zp->z_gmtoff,
2973  startttisstd,
2974  startttisgmt));
2975  }
2976 
2977  /*
2978  * Now we may get to set starttime for the next zone line.
2979  */
2980  if (useuntil)
2981  {
2982  startttisstd = zp->z_untilrule.r_todisstd;
2983  startttisgmt = zp->z_untilrule.r_todisgmt;
2984  starttime = zp->z_untiltime;
2985  if (!startttisstd)
2986  starttime = tadd(starttime, -stdoff);
2987  if (!startttisgmt)
2988  starttime = tadd(starttime, -gmtoff);
2989  }
2990  }
2991  if (0 <= lastatmax)
2992  attypes[lastatmax].dontmerge = true;
2993  if (do_extend)
2994  {
2995  /*
2996  * If we're extending the explicitly listed observations for 400 years
2997  * because we can't fill the POSIX-TZ field, check whether we actually
2998  * ended up explicitly listing observations through that period. If
2999  * there aren't any near the end of the 400-year period, add a
3000  * redundant one at the end of the final year, to make it clear that
3001  * we are claiming to have definite knowledge of the lack of
3002  * transitions up to that point.
3003  */
3004  struct rule xr;
3005  struct attype *lastat;
3006 
3007  xr.r_month = TM_JANUARY;
3008  xr.r_dycode = DC_DOM;
3009  xr.r_dayofmonth = 1;
3010  xr.r_tod = 0;
3011  for (lastat = &attypes[0], i = 1; i < timecnt; i++)
3012  if (attypes[i].at > lastat->at)
3013  lastat = &attypes[i];
3014  if (lastat->at < rpytime(&xr, max_year - 1))
3015  {
3016  addtt(rpytime(&xr, max_year + 1), typecnt - 1);
3017  attypes[timecnt - 1].dontmerge = true;
3018  }
3019  }
3020  writezone(zpfirst->z_name, envvar, version);
3021  free(startbuf);
3022  free(ab);
3023  free(envvar);
3024 }
static bool yearistype(zic_t year, const char *type)
Definition: zic.c:3165
static void writezone(const char *const name, const char *const string, char version)
Definition: zic.c:1867
static zic_t leapmaxyear
Definition: zic.c:172
lineno_t r_linenum
Definition: zic.c:58
static int typecnt
Definition: zic.c:186
static int stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
Definition: zic.c:2514
Definition: zic.c:375
bool r_todisstd
Definition: zic.c:74
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
static void addtt(zic_t starttime, int type)
Definition: zic.c:3027
#define INITIALIZE(x)
Definition: private.h:81
const char * z_format
Definition: zic.c:100
#define DC_DOM
Definition: zic.c:88
zic_t z_untiltime
Definition: zic.c:109
struct rule z_untilrule
Definition: zic.c:108
static zic_t min_year
Definition: zic.c:177
static void updateminmax(const zic_t x)
Definition: zic.c:2371
static int max_format_len
Definition: zic.c:175
Definition: localtime.c:78
static const zic_t early_time
Definition: zic.c:1015
bool r_lowasnum
Definition: zic.c:64
#define ZIC_MAX
Definition: zic.c:25
const char * z_filename
Definition: zic.c:94
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3504
static int addtype(zic_t, char const *, bool, bool, bool)
Definition: zic.c:3052
bool r_todo
Definition: zic.c:80
static size_t doabbr(char *abbr, struct zone const *zp, char const *letters, zic_t stdoff, bool doquotes)
Definition: zic.c:2328
#define ZIC_VERSION_PRE_2013
Definition: zic.c:20
static bool leapseen
Definition: zic.c:170
#define ZIC_VERSION
Definition: zic.c:21
static int max_abbrvar_len
Definition: zic.c:174
int64 zic_t
Definition: zic.c:23
zic_t r_hiyear
Definition: zic.c:62
const char * r_yrtype
Definition: zic.c:63
zic_t r_temp
Definition: zic.c:81
#define ZIC_MIN
Definition: zic.c:24
const char * r_filename
Definition: zic.c:57
enum COMPAT_MODE compat
Definition: ecpg.c:25
zic_t at
Definition: zic.c:377
#define EPOCH_YEAR
Definition: private.h:123
static zic_t rpytime(const struct rule *rp, zic_t wantedy)
Definition: zic.c:3533
static void eat(char const *name, lineno_t num)
Definition: zic.c:467
const char * r_abbrvar
Definition: zic.c:78
static struct attype * attypes
static zic_t const max_time
Definition: zic.c:975
static bool noise
Definition: zic.c:178
ptrdiff_t z_nrules
Definition: zic.c:106
#define TM_JANUARY
Definition: private.h:108
lineno_t z_linenum
Definition: zic.c:95
static zic_t max_year
Definition: zic.c:176
#define free(a)
Definition: header.h:65
zic_t r_stdoff
Definition: zic.c:77
zic_t z_gmtoff
Definition: zic.c:98
static ptrdiff_t timecnt
Definition: zic.c:184
static int charcnt
Definition: zic.c:165
static zic_t leapminyear
Definition: zic.c:171
#define YEARSPERREPEAT
Definition: private.h:88
struct rule * z_rules
Definition: zic.c:105
Definition: zic.c:92
bool r_hiwasnum
Definition: zic.c:65
int i
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
zic_t r_loyear
Definition: zic.c:61
bool r_todisgmt
Definition: zic.c:76
static zic_t const min_time
Definition: zic.c:974
bool dontmerge
Definition: zic.c:378
static void eats(char const *name, lineno_t num, char const *rname, lineno_t rnum)
Definition: zic.c:458
#define _(x)
Definition: elog.c:84
static zic_t oadd(zic_t t1, zic_t t2)
Definition: zic.c:3496
zic_t z_stdoff
Definition: zic.c:103
static void * emalloc(size_t size)
Definition: zic.c:419

◆ puttzcode()

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

Definition at line 1834 of file zic.c.

References buf, and convert().

Referenced by writezone().

1835 {
1836  char buf[4];
1837 
1838  convert(val, buf);
1839  fwrite(buf, sizeof buf, 1, fp);
1840 }
static void convert(const int32 val, char *const buf)
Definition: zic.c:1812
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 1843 of file zic.c.

References buf, and convert64().

Referenced by writezone().

1844 {
1845  char buf[8];
1846 
1847  convert64(val, buf);
1848  fwrite(buf, sizeof buf, 1, fp);
1849 }
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:1823

◆ rcomp()

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

Definition at line 1066 of file zic.c.

References rule::r_name.

Referenced by associate().

1067 {
1068  return strcmp(((const struct rule *) cp1)->r_name,
1069  ((const struct rule *) cp2)->r_name);
1070 }
Definition: localtime.c:78

◆ rpytime()

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

Definition at line 3533 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().

3534 {
3535  int m,
3536  i;
3537  zic_t dayoff; /* with a nod to Margaret O. */
3538  zic_t t,
3539  y;
3540 
3541  if (wantedy == ZIC_MIN)
3542  return min_time;
3543  if (wantedy == ZIC_MAX)
3544  return max_time;
3545  dayoff = 0;
3546  m = TM_JANUARY;
3547  y = EPOCH_YEAR;
3548  while (wantedy != y)
3549  {
3550  if (wantedy > y)
3551  {
3552  i = len_years[isleap(y)];
3553  ++y;
3554  }
3555  else
3556  {
3557  --y;
3558  i = -len_years[isleap(y)];
3559  }
3560  dayoff = oadd(dayoff, i);
3561  }
3562  while (m != rp->r_month)
3563  {
3564  i = len_months[isleap(y)][m];
3565  dayoff = oadd(dayoff, i);
3566  ++m;
3567  }
3568  i = rp->r_dayofmonth;
3569  if (m == TM_FEBRUARY && i == 29 && !isleap(y))
3570  {
3571  if (rp->r_dycode == DC_DOWLEQ)
3572  --i;
3573  else
3574  {
3575  error(_("use of 2/29 in non leap-year"));
3576  exit(EXIT_FAILURE);
3577  }
3578  }
3579  --i;
3580  dayoff = oadd(dayoff, i);
3581  if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ)
3582  {
3583  zic_t wday;
3584 
3585 #define LDAYSPERWEEK ((zic_t) DAYSPERWEEK)
3586  wday = EPOCH_WDAY;
3587 
3588  /*
3589  * Don't trust mod of negative numbers.
3590  */
3591  if (dayoff >= 0)
3592  wday = (wday + dayoff) % LDAYSPERWEEK;
3593  else
3594  {
3595  wday -= ((-dayoff) % LDAYSPERWEEK);
3596  if (wday < 0)
3597  wday += LDAYSPERWEEK;
3598  }
3599  while (wday != rp->r_wday)
3600  if (rp->r_dycode == DC_DOWGEQ)
3601  {
3602  dayoff = oadd(dayoff, 1);
3603  if (++wday >= LDAYSPERWEEK)
3604  wday = 0;
3605  ++i;
3606  }
3607  else
3608  {
3609  dayoff = oadd(dayoff, -1);
3610  if (--wday < 0)
3611  wday = LDAYSPERWEEK - 1;
3612  --i;
3613  }
3614  if (i < 0 || i >= len_months[isleap(y)][m])
3615  {
3616  if (noise)
3617  warning(_("rule goes past start/end of month; \
3618 will not work with pre-2004 versions of zic"));
3619  }
3620  }
3621  if (dayoff < min_time / SECSPERDAY)
3622  return min_time;
3623  if (dayoff > max_time / SECSPERDAY)
3624  return max_time;
3625  t = (zic_t) dayoff * SECSPERDAY;
3626 
3627  return tadd(t, rp->r_tod);
3628 }
zic_t r_tod
Definition: zic.c:73
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
int r_month
Definition: zic.c:67
#define DC_DOWGEQ
Definition: zic.c:89
#define SECSPERDAY
Definition: private.h:97
#define isleap(y)
Definition: datetime.h:273
static const int len_months[2][MONSPERYEAR]
Definition: zic.c:366
#define ZIC_MAX
Definition: zic.c:25
#define LDAYSPERWEEK
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3504
int64 zic_t
Definition: zic.c:23
#define ZIC_MIN
Definition: zic.c:24
int r_dycode
Definition: zic.c:69
#define EPOCH_YEAR
Definition: private.h:123
#define DC_DOWLEQ
Definition: zic.c:90
static zic_t const max_time
Definition: zic.c:975
static bool noise
Definition: zic.c:178
#define TM_JANUARY
Definition: private.h:108
#define TM_FEBRUARY
Definition: private.h:109
int r_dayofmonth
Definition: zic.c:70
int r_wday
Definition: zic.c:71
#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:371
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
static zic_t const min_time
Definition: zic.c:974
#define _(x)
Definition: elog.c:84
static zic_t oadd(zic_t t1, zic_t t2)
Definition: zic.c:3496

◆ rule_cmp()

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

Definition at line 2496 of file zic.c.

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

Referenced by stringzone().

2497 {
2498  if (!a)
2499  return -!!b;
2500  if (!b)
2501  return 1;
2502  if (a->r_hiyear != b->r_hiyear)
2503  return a->r_hiyear < b->r_hiyear ? -1 : 1;
2504  if (a->r_month - b->r_month != 0)
2505  return a->r_month - b->r_month;
2506  return a->r_dayofmonth - b->r_dayofmonth;
2507 }

◆ 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 1636 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().

1639 {
1640  const struct lookup *lp;
1641  const char *cp;
1642  char *dp;
1643  char *ep;
1644  char xs;
1645 
1646  /* PG: year_tmp is to avoid sscanf portability issues */
1647  int year_tmp;
1648 
1649  if ((lp = byword(monthp, mon_names)) == NULL)
1650  {
1651  error(_("invalid month name"));
1652  return;
1653  }
1654  rp->r_month = lp->l_value;
1655  rp->r_todisstd = false;
1656  rp->r_todisgmt = false;
1657  dp = ecpyalloc(timep);
1658  if (*dp != '\0')
1659  {
1660  ep = dp + strlen(dp) - 1;
1661  switch (lowerit(*ep))
1662  {
1663  case 's': /* Standard */
1664  rp->r_todisstd = true;
1665  rp->r_todisgmt = false;
1666  *ep = '\0';
1667  break;
1668  case 'w': /* Wall */
1669  rp->r_todisstd = false;
1670  rp->r_todisgmt = false;
1671  *ep = '\0';
1672  break;
1673  case 'g': /* Greenwich */
1674  case 'u': /* Universal */
1675  case 'z': /* Zulu */
1676  rp->r_todisstd = true;
1677  rp->r_todisgmt = true;
1678  *ep = '\0';
1679  break;
1680  }
1681  }
1682  rp->r_tod = gethms(dp, _("invalid time of day"), false);
1683  free(dp);
1684 
1685  /*
1686  * Year work.
1687  */
1688  cp = loyearp;
1689  lp = byword(cp, begin_years);
1690  rp->r_lowasnum = lp == NULL;
1691  if (!rp->r_lowasnum)
1692  switch (lp->l_value)
1693  {
1694  case YR_MINIMUM:
1695  rp->r_loyear = ZIC_MIN;
1696  break;
1697  case YR_MAXIMUM:
1698  rp->r_loyear = ZIC_MAX;
1699  break;
1700  default: /* "cannot happen" */
1701  fprintf(stderr,
1702  _("%s: panic: Invalid l_value %d\n"),
1703  progname, lp->l_value);
1704  exit(EXIT_FAILURE);
1705  }
1706  else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
1707  rp->r_loyear = year_tmp;
1708  else
1709  {
1710  error(_("invalid starting year"));
1711  return;
1712  }
1713  cp = hiyearp;
1714  lp = byword(cp, end_years);
1715  rp->r_hiwasnum = lp == NULL;
1716  if (!rp->r_hiwasnum)
1717  switch (lp->l_value)
1718  {
1719  case YR_MINIMUM:
1720  rp->r_hiyear = ZIC_MIN;
1721  break;
1722  case YR_MAXIMUM:
1723  rp->r_hiyear = ZIC_MAX;
1724  break;
1725  case YR_ONLY:
1726  rp->r_hiyear = rp->r_loyear;
1727  break;
1728  default: /* "cannot happen" */
1729  fprintf(stderr,
1730  _("%s: panic: Invalid l_value %d\n"),
1731  progname, lp->l_value);
1732  exit(EXIT_FAILURE);
1733  }
1734  else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
1735  rp->r_hiyear = year_tmp;
1736  else
1737  {
1738  error(_("invalid ending year"));
1739  return;
1740  }
1741  if (rp->r_loyear > rp->r_hiyear)
1742  {
1743  error(_("starting year greater than ending year"));
1744  return;
1745  }
1746  if (*typep == '\0')
1747  rp->r_yrtype = NULL;
1748  else
1749  {
1750  if (rp->r_loyear == rp->r_hiyear)
1751  {
1752  error(_("typed single year"));
1753  return;
1754  }
1755  warning(_("year type \"%s\" is obsolete; use \"-\" instead"),
1756  typep);
1757  rp->r_yrtype = ecpyalloc(typep);
1758  }
1759 
1760  /*
1761  * Day work. Accept things such as: 1 lastSunday last-Sunday
1762  * (undocumented; warn about this) Sun<=20 Sun>=7
1763  */
1764  dp = ecpyalloc(dayp);
1765  if ((lp = byword(dp, lasts)) != NULL)
1766  {
1767  rp->r_dycode = DC_DOWLEQ;
1768  rp->r_wday = lp->l_value;
1769  rp->r_dayofmonth = len_months[1][rp->r_month];
1770  }
1771  else
1772  {
1773  if ((ep = strchr(dp, '<')) != NULL)
1774  rp->r_dycode = DC_DOWLEQ;
1775  else if ((ep = strchr(dp, '>')) != NULL)
1776  rp->r_dycode = DC_DOWGEQ;
1777  else
1778  {
1779  ep = dp;
1780  rp->r_dycode = DC_DOM;
1781  }
1782  if (rp->r_dycode != DC_DOM)
1783  {
1784  *ep++ = 0;
1785  if (*ep++ != '=')
1786  {
1787  error(_("invalid day of month"));
1788  free(dp);
1789  return;
1790  }
1791  if ((lp = byword(dp, wday_names)) == NULL)
1792  {
1793  error(_("invalid weekday name"));
1794  free(dp);
1795  return;
1796  }
1797  rp->r_wday = lp->l_value;
1798  }
1799  if (sscanf(ep, "%d%c", &rp->r_dayofmonth, &xs) != 1 ||
1800  rp->r_dayofmonth <= 0 ||
1801  (rp->r_dayofmonth > len_months[1][rp->r_month]))
1802  {
1803  error(_("invalid day of month"));
1804  free(dp);
1805  return;
1806  }
1807  }
1808  free(dp);
1809 }
#define YR_MINIMUM
Definition: zic.c:265
zic_t r_tod
Definition: zic.c:73
bool r_todisstd
Definition: zic.c:74
static char * ecpyalloc(char const *str)
Definition: zic.c:431
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
int r_month
Definition: zic.c:67
#define DC_DOWGEQ
Definition: zic.c:89
static struct lookup const begin_years[]
Definition: zic.c:347
#define DC_DOM
Definition: zic.c:88
static const int len_months[2][MONSPERYEAR]
Definition: zic.c:366
const int l_value
Definition: zic.c:292
bool r_lowasnum
Definition: zic.c:64
#define ZIC_MAX
Definition: zic.c:25
#define YR_ONLY
Definition: zic.c:267
static struct lookup const mon_names[]
Definition: zic.c:309
Definition: zic.c:289
zic_t r_hiyear
Definition: zic.c:62
const char * r_yrtype
Definition: zic.c:63
#define ZIC_MIN
Definition: zic.c:24
static struct lookup const end_years[]
Definition: zic.c:353
int r_dycode
Definition: zic.c:69
#define DC_DOWLEQ
Definition: zic.c:90
static zic_t gethms(const char *string, const char *errstring, bool)
Definition: zic.c:1262
static const char * progname
Definition: zic.c:183
#define free(a)
Definition: header.h:65
int r_dayofmonth
Definition: zic.c:70
int r_wday
Definition: zic.c:71
static struct lookup const * byword(const char *string, const struct lookup *lp)
Definition: zic.c:3383
static char lowerit(char)
Definition: zic.c:3283
#define YR_MAXIMUM
Definition: zic.c:266
static struct lookup const lasts[]
Definition: zic.c:336
bool r_hiwasnum
Definition: zic.c:65
static struct lookup const wday_names[]
Definition: zic.c:325
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
zic_t r_loyear
Definition: zic.c:61
bool r_todisgmt
Definition: zic.c:76
#define _(x)
Definition: elog.c:84

◆ shellquote()

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

Definition at line 3151 of file zic.c.

Referenced by yearistype().

3152 {
3153  *b++ = '\'';
3154  while (*s)
3155  {
3156  if (*s == '\'')
3157  *b++ = '\'', *b++ = '\\', *b++ = '\'';
3158  *b++ = *s++;
3159  }
3160  *b++ = '\'';
3161  return b;
3162 }

◆ size_product()

static size_t size_product ( size_t  nitems,
size_t  itemsize 
)
static

Definition at line 403 of file zic.c.

References _, memory_exhausted(), and SIZE_MAX.

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

404 {
405  if (SIZE_MAX / itemsize < nitems)
406  memory_exhausted(_("size overflow"));
407  return nitems * itemsize;
408 }
#define SIZE_MAX
Definition: c.h:390
static void memory_exhausted(const char *msg) pg_attribute_noreturn()
Definition: zic.c:396
#define _(x)
Definition: elog.c:84

◆ stringoffset()

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

Definition at line 2380 of file zic.c.

References DAYSPERWEEK, HOURSPERDAY, MINSPERHOUR, and SECSPERMIN.

Referenced by stringrule(), and stringzone().

2381 {
2382  int hours;
2383  int minutes;
2384  int seconds;
2385  bool negative = offset < 0;
2386  int len = negative;
2387 
2388  if (negative)
2389  {
2390  offset = -offset;
2391  result[0] = '-';
2392  }
2393  seconds = offset % SECSPERMIN;
2394  offset /= SECSPERMIN;
2395  minutes = offset % MINSPERHOUR;
2396  offset /= MINSPERHOUR;
2397  hours = offset;
2398  if (hours >= HOURSPERDAY * DAYSPERWEEK)
2399  {
2400  result[0] = '\0';
2401  return 0;
2402  }
2403  len += sprintf(result + len, "%d", hours);
2404  if (minutes != 0 || seconds != 0)
2405  {
2406  len += sprintf(result + len, ":%02d", minutes);
2407  if (seconds != 0)
2408  len += sprintf(result + len, ":%02d", seconds);
2409  }
2410  return len;
2411 }
#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 2414 of file zic.c.

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

Referenced by stringzone().

2416 {
2417  zic_t tod = rp->r_tod;
2418  int compat = 0;
2419 
2420  if (rp->r_dycode == DC_DOM)
2421  {
2422  int month,
2423  total;
2424 
2425  if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY)
2426  return -1;
2427  total = 0;
2428  for (month = 0; month < rp->r_month; ++month)
2429  total += len_months[0][month];
2430  /* Omit the "J" in Jan and Feb, as that's shorter. */
2431  if (rp->r_month <= 1)
2432  result += sprintf(result, "%d", total + rp->r_dayofmonth - 1);
2433  else
2434  result += sprintf(result, "J%d", total + rp->r_dayofmonth);
2435  }
2436  else
2437  {
2438  int week;
2439  int wday = rp->r_wday;
2440  int wdayoff;
2441 
2442  if (rp->r_dycode == DC_DOWGEQ)
2443  {
2444  wdayoff = (rp->r_dayofmonth - 1) % DAYSPERWEEK;
2445  if (wdayoff)
2446  compat = 2013;
2447  wday -= wdayoff;
2448  tod += wdayoff * SECSPERDAY;
2449  week = 1 + (rp->r_dayofmonth - 1) / DAYSPERWEEK;
2450  }
2451  else if (rp->r_dycode == DC_DOWLEQ)
2452  {
2453  if (rp->r_dayofmonth == len_months[1][rp->r_month])
2454  week = 5;
2455  else
2456  {
2457  wdayoff = rp->r_dayofmonth % DAYSPERWEEK;
2458  if (wdayoff)
2459  compat = 2013;
2460  wday -= wdayoff;
2461  tod += wdayoff * SECSPERDAY;
2462  week = rp->r_dayofmonth / DAYSPERWEEK;
2463  }
2464  }
2465  else
2466  return -1; /* "cannot happen" */
2467  if (wday < 0)
2468  wday += DAYSPERWEEK;
2469  result += sprintf(result, "M%d.%d.%d",
2470  rp->r_month + 1, week, wday);
2471  }
2472  if (rp->r_todisgmt)
2473  tod += gmtoff;
2474  if (rp->r_todisstd && rp->r_stdoff == 0)
2475  tod += dstoff;
2476  if (tod != 2 * SECSPERMIN * MINSPERHOUR)
2477  {
2478  *result++ = '/';
2479  if (!stringoffset(result, tod))
2480  return -1;
2481  if (tod < 0)
2482  {
2483  if (compat < 2013)
2484  compat = 2013;
2485  }
2486  else if (SECSPERDAY <= tod)
2487  {
2488  if (compat < 1994)
2489  compat = 1994;
2490  }
2491  }
2492  return compat;
2493 }
#define SECSPERMIN
Definition: private.h:90
zic_t r_tod
Definition: zic.c:73
bool r_todisstd
Definition: zic.c:74
int r_month
Definition: zic.c:67
#define DC_DOWGEQ
Definition: zic.c:89
#define SECSPERDAY
Definition: private.h:97
#define DC_DOM
Definition: zic.c:88
static const int len_months[2][MONSPERYEAR]
Definition: zic.c:366
static int stringoffset(char *result, zic_t offset)
Definition: zic.c:2380
#define DAYSPERWEEK
Definition: private.h:93
int64 zic_t
Definition: zic.c:23
enum COMPAT_MODE compat
Definition: ecpg.c:25
int r_dycode
Definition: zic.c:69
#define DC_DOWLEQ
Definition: zic.c:90
#define TM_FEBRUARY
Definition: private.h:109
zic_t r_stdoff
Definition: zic.c:77
int r_dayofmonth
Definition: zic.c:70
int r_wday
Definition: zic.c:71
bool r_todisgmt
Definition: zic.c:76
#define MINSPERHOUR
Definition: private.h:91

◆ stringzone()

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

Definition at line 2514 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_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_nrules, zone::z_rules, zone::z_stdoff, and ZIC_MAX.

Referenced by outzone().

2515 {
2516  const struct zone *zp;
2517  struct rule *rp;
2518  struct rule *stdrp;
2519  struct rule *dstrp;
2520  ptrdiff_t i;
2521  const char *abbrvar;
2522  int compat = 0;
2523  int c;
2524  size_t len;
2525  int offsetlen;
2526  struct rule stdr,
2527  dstr;
2528 
2529  result[0] = '\0';
2530  zp = zpfirst + zonecount - 1;
2531  stdrp = dstrp = NULL;
2532  for (i = 0; i < zp->z_nrules; ++i)
2533  {
2534  rp = &zp->z_rules[i];
2535  if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)
2536  continue;
2537  if (rp->r_yrtype != NULL)
2538  continue;
2539  if (rp->r_stdoff == 0)
2540  {
2541  if (stdrp == NULL)
2542  stdrp = rp;
2543  else
2544  return -1;
2545  }
2546  else
2547  {
2548  if (dstrp == NULL)
2549  dstrp = rp;
2550  else
2551  return -1;
2552  }
2553  }
2554  if (stdrp == NULL && dstrp == NULL)
2555  {
2556  /*
2557  * There are no rules running through "max". Find the latest std rule
2558  * in stdabbrrp and latest rule of any type in stdrp.
2559  */
2560  struct rule *stdabbrrp = NULL;
2561 
2562  for (i = 0; i < zp->z_nrules; ++i)
2563  {
2564  rp = &zp->z_rules[i];
2565  if (rp->r_stdoff == 0 && rule_cmp(stdabbrrp, rp) < 0)
2566  stdabbrrp = rp;
2567  if (rule_cmp(stdrp, rp) < 0)
2568  stdrp = rp;
2569  }
2570 
2571  /*
2572  * Horrid special case: if year is 2037, presume this is a zone
2573  * handled on a year-by-year basis; do not try to apply a rule to the
2574  * zone.
2575  */
2576  if (stdrp != NULL && stdrp->r_hiyear == 2037)
2577  return YEAR_BY_YEAR_ZONE;
2578 
2579  if (stdrp != NULL && stdrp->r_stdoff != 0)
2580  {
2581  /* Perpetual DST. */
2582  dstr.r_month = TM_JANUARY;
2583  dstr.r_dycode = DC_DOM;
2584  dstr.r_dayofmonth = 1;
2585  dstr.r_tod = 0;
2586  dstr.r_todisstd = dstr.r_todisgmt = false;
2587  dstr.r_stdoff = stdrp->r_stdoff;
2588  dstr.r_abbrvar = stdrp->r_abbrvar;
2589  stdr.r_month = TM_DECEMBER;
2590  stdr.r_dycode = DC_DOM;
2591  stdr.r_dayofmonth = 31;
2592  stdr.r_tod = SECSPERDAY + stdrp->r_stdoff;
2593  stdr.r_todisstd = stdr.r_todisgmt = false;
2594  stdr.r_stdoff = 0;
2595  stdr.r_abbrvar
2596  = (stdabbrrp ? stdabbrrp->r_abbrvar : "");
2597  dstrp = &dstr;
2598  stdrp = &stdr;
2599  }
2600  }
2601  if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_stdoff != 0))
2602  return -1;
2603  abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
2604  len = doabbr(result, zp, abbrvar, 0, true);
2605  offsetlen = stringoffset(result + len, -zp->z_gmtoff);
2606  if (!offsetlen)
2607  {
2608  result[0] = '\0';
2609  return -1;
2610  }
2611  len += offsetlen;
2612  if (dstrp == NULL)
2613  return compat;
2614  len += doabbr(result + len, zp, dstrp->r_abbrvar, dstrp->r_stdoff, true);
2615  if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR)
2616  {
2617  offsetlen = stringoffset(result + len,
2618  -(zp->z_gmtoff + dstrp->r_stdoff));
2619  if (!offsetlen)
2620  {
2621  result[0] = '\0';
2622  return -1;
2623  }
2624  len += offsetlen;
2625  }
2626  result[len++] = ',';
2627  c = stringrule(result + len, dstrp, dstrp->r_stdoff, zp->z_gmtoff);
2628  if (c < 0)
2629  {
2630  result[0] = '\0';
2631  return -1;
2632  }
2633  if (compat < c)
2634  compat = c;
2635  len += strlen(result + len);
2636  result[len++] = ',';
2637  c = stringrule(result + len, stdrp, dstrp->r_stdoff, zp->z_gmtoff);
2638  if (c < 0)
2639  {
2640  result[0] = '\0';
2641  return -1;
2642  }
2643  if (compat < c)
2644  compat = c;
2645  return compat;
2646 }
#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:2414
#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:2496
#define DC_DOM
Definition: zic.c:88
static int stringoffset(char *result, zic_t offset)
Definition: zic.c:2380
Definition: localtime.c:78
#define ZIC_MAX
Definition: zic.c:25
static size_t doabbr(char *abbr, struct zone const *zp, char const *letters, zic_t stdoff, bool doquotes)
Definition: zic.c:2328
char * c
zic_t r_hiyear
Definition: zic.c:62
const char * r_yrtype
Definition: zic.c:63
enum COMPAT_MODE compat
Definition: ecpg.c:25
const char * r_abbrvar
Definition: zic.c:78
ptrdiff_t z_nrules
Definition: zic.c:106
#define TM_JANUARY
Definition: private.h:108
zic_t r_stdoff
Definition: zic.c:77
zic_t z_gmtoff
Definition: zic.c:98
struct rule * z_rules
Definition: zic.c:105
Definition: zic.c:92
bool r_hiwasnum
Definition: zic.c:65
int i
#define MINSPERHOUR
Definition: private.h:91
zic_t z_stdoff
Definition: zic.c:103

◆ tadd()

static zic_t tadd ( zic_t  t1,
zic_t  t2 
)
static

Definition at line 3504 of file zic.c.

References max_time, min_time, and time_overflow().

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

3505 {
3506  if (t1 < 0)
3507  {
3508  if (t2 < min_time - t1)
3509  {
3510  if (t1 != min_time)
3511  time_overflow();
3512  return min_time;
3513  }
3514  }
3515  else
3516  {
3517  if (max_time - t1 < t2)
3518  {
3519  if (t1 != max_time)
3520  time_overflow();
3521  return max_time;
3522  }
3523  }
3524  return t1 + t2;
3525 }
static void time_overflow(void)
Definition: zic.c:3489
static zic_t const max_time
Definition: zic.c:975
static zic_t const min_time
Definition: zic.c:974

◆ time_overflow()

static void time_overflow ( void  )
static

Definition at line 3489 of file zic.c.

References _, error(), and EXIT_FAILURE.

Referenced by oadd(), and tadd().

3490 {
3491  error(_("time overflow"));
3492  exit(EXIT_FAILURE);
3493 }
#define EXIT_FAILURE
Definition: settings.h:152
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84

◆ updateminmax()

static void updateminmax ( const zic_t  x)
static

Definition at line 2371 of file zic.c.

Referenced by outzone().

2372 {
2373  if (min_year > x)
2374  min_year = x;
2375  if (max_year < x)
2376  max_year = x;
2377 }
static zic_t min_year
Definition: zic.c:177
static zic_t max_year
Definition: zic.c:176

◆ usage()

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

Definition at line 528 of file zic.c.

References _, close_file(), and EXIT_SUCCESS.

Referenced by main().

529 {
530  fprintf(stream,
531  _("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -P ] \\\n"
532  "\t[ -l localtime ] [ -p posixrules ] [ -d directory ] \\\n"
533  "\t[ -L leapseconds ] [ filename ... ]\n\n"
534  "Report bugs to %s.\n"),
535  progname, progname, PACKAGE_BUGREPORT);
536  if (status == EXIT_SUCCESS)
537  close_file(stream, NULL, NULL);
538  exit(status);
539 }
#define EXIT_SUCCESS
Definition: settings.h:148
static const char * progname
Definition: zic.c:183
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:512
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 473 of file zic.c.

References _.

Referenced by error(), and warning().

474 {
475  /*
476  * Match the format of "cc" to allow sh users to zic ... 2>&1 | error -t
477  * "*" -v on BSD systems.
478  */
479  if (filename)
480  fprintf(stderr, _("\"%s\", line %d: "), filename, linenum);
481  vfprintf(stderr, string, args);
482  if (rfilename != NULL)
483  fprintf(stderr, _(" (rule from \"%s\", line %d)"),
485  fprintf(stderr, "\n");
486 }
static lineno_t rlinenum
Definition: zic.c:182
static const char * filename
Definition: zic.c:168
static lineno_t linenum
Definition: zic.c:173
static const char * rfilename
Definition: zic.c:181
#define _(x)
Definition: elog.c:84

◆ warning()

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

Definition at line 500 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().

501 {
502  va_list args;
503 
504  fprintf(stderr, _("warning: "));
505  va_start(args, string);
506  verror(string, args);
507  va_end(args);
508  warnings = true;
509 }
static bool warnings
Definition: zic.c:167
static void verror(const char *string, va_list args) pg_attribute_printf(1
Definition: zic.c:473
#define _(x)
Definition: elog.c:84

◆ writezone()

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

Definition at line 1867 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().

1868 {
1869  FILE *fp;
1870  ptrdiff_t i,
1871  j;
1872  int leapcnt32,
1873  leapi32;
1874  ptrdiff_t timecnt32,
1875  timei32;
1876  int pass;
1877  static const struct tzhead tzh0;
1878  static struct tzhead tzh;
1879  bool dir_checked = false;
1880  zic_t one = 1;
1881  zic_t y2038_boundary = one << 31;
1882  ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071;
1883  zic_t *ats = emalloc(size_product(nats, sizeof *ats + 1));
1884  void *typesptr = ats + nats;
1885  unsigned char *types = typesptr;
1886 
1887  /*
1888  * Sort.
1889  */
1890  if (timecnt > 1)
1891  qsort(attypes, timecnt, sizeof *attypes, atcomp);
1892 
1893  /*
1894  * Optimize.
1895  */
1896  {
1897  ptrdiff_t fromi,
1898  toi;
1899 
1900  toi = 0;
1901  fromi = 0;
1902  while (fromi < timecnt && attypes[fromi].at < early_time)
1903  ++fromi;
1904  for (; fromi < timecnt; ++fromi)
1905  {
1906  if (toi > 1 && ((attypes[fromi].at +
1907  gmtoffs[attypes[toi - 1].type]) <=
1908  (attypes[toi - 1].at +
1909  gmtoffs[attypes[toi - 2].type])))
1910  {
1911  attypes[toi - 1].type =
1912  attypes[fromi].type;
1913  continue;
1914  }
1915  if (toi == 0
1916  || attypes[fromi].dontmerge
1917  || attypes[toi - 1].type != attypes[fromi].type)
1918  attypes[toi++] = attypes[fromi];
1919  }
1920  timecnt = toi;
1921  }
1922 
1923  if (noise && timecnt > 1200)
1924  {
1925  if (timecnt > TZ_MAX_TIMES)
1926  warning(_("reference clients mishandle"
1927  " more than %d transition times"),
1928  TZ_MAX_TIMES);
1929  else
1930  warning(_("pre-2014 clients may mishandle"
1931  " more than 1200 transition times"));
1932  }
1933 
1934  /*
1935  * Transfer.
1936  */
1937  for (i = 0; i < timecnt; ++i)
1938  {
1939  ats[i] = attypes[i].at;
1940  types[i] = attypes[i].type;
1941  }
1942 
1943  /*
1944  * Work around QTBUG-53071 for time stamps less than y2038_boundary - 1,
1945  * by inserting a no-op transition at time y2038_boundary - 1. This works
1946  * only for timestamps before the boundary, which should be good enough in
1947  * practice as QTBUG-53071 should be long-dead by 2038.
1948  */
1949  if (WORK_AROUND_QTBUG_53071 && timecnt != 0
1950  && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<'))
1951  {
1952  ats[timecnt] = y2038_boundary - 1;
1953  types[timecnt] = types[timecnt - 1];
1954  timecnt++;
1955  }
1956 
1957  /*
1958  * Correct for leap seconds.
1959  */
1960  for (i = 0; i < timecnt; ++i)
1961  {
1962  j = leapcnt;
1963  while (--j >= 0)
1964  if (ats[i] > trans[j] - corr[j])
1965  {
1966  ats[i] = tadd(ats[i], corr[j]);
1967  break;
1968  }
1969  }
1970 
1971  /*
1972  * Figure out 32-bit-limited starts and counts.
1973  */
1974  timecnt32 = timecnt;
1975  timei32 = 0;
1976  leapcnt32 = leapcnt;
1977  leapi32 = 0;
1978  while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
1979  --timecnt32;
1980  while (timecnt32 > 0 && !is32(ats[timei32]))
1981  {
1982  --timecnt32;
1983  ++timei32;
1984  }
1985 
1986  /*
1987  * Output an INT32_MIN "transition" if appropriate; see below.
1988  */
1989  if (timei32 > 0 && ats[timei32] > PG_INT32_MIN)
1990  {
1991  --timei32;
1992  ++timecnt32;
1993  }
1994  while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
1995  --leapcnt32;
1996  while (leapcnt32 > 0 && !is32(trans[leapi32]))
1997  {
1998  --leapcnt32;
1999  ++leapi32;
2000  }
2001 
2002  /*
2003  * Remove old file, if any, to snap links.
2004  */
2005  if (remove(name) == 0)
2006  dir_checked = true;
2007  else if (errno != ENOENT)
2008  {
2009  const char *e = strerror(errno);
2010 
2011  fprintf(stderr, _("%s: Cannot remove %s/%s: %s\n"),
2012  progname, directory, name, e);
2013  exit(EXIT_FAILURE);
2014  }
2015  fp = fopen(name, "wb");
2016  if (!fp)
2017  {
2018  int fopen_errno = errno;
2019 
2020  if (fopen_errno == ENOENT && !dir_checked)
2021  {
2022  mkdirs(name, true);
2023  fp = fopen(name, "wb");
2024  fopen_errno = errno;
2025  }
2026  if (!fp)
2027  {
2028  fprintf(stderr, _("%s: Cannot create %s/%s: %s\n"),
2029  progname, directory, name, strerror(fopen_errno));
2030  exit(EXIT_FAILURE);
2031  }
2032  }
2033  for (pass = 1; pass <= 2; ++pass)
2034  {
2035  ptrdiff_t thistimei,
2036  thistimecnt,
2037  thistimelim;
2038  int thisleapi,
2039  thisleapcnt,
2040  thisleaplim;
2041  int writetype[TZ_MAX_TYPES];
2042  int typemap[TZ_MAX_TYPES];
2043  int thistypecnt;
2044  char thischars[TZ_MAX_CHARS];
2045  int thischarcnt;
2046  bool toomanytimes;
2047  int indmap[TZ_MAX_CHARS];
2048 
2049  if (pass == 1)
2050  {
2051  thistimei = timei32;
2052  thistimecnt = timecnt32;
2053  toomanytimes = thistimecnt >> 31 >> 1 != 0;
2054  thisleapi = leapi32;
2055  thisleapcnt = leapcnt32;
2056  }
2057  else
2058  {
2059  thistimei = 0;
2060  thistimecnt = timecnt;
2061  toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
2062  thisleapi = 0;
2063  thisleapcnt = leapcnt;
2064  }
2065  if (toomanytimes)
2066  error(_("too many transition times"));
2067  thistimelim = thistimei + thistimecnt;
2068  thisleaplim = thisleapi + thisleapcnt;
2069  for (i = 0; i < typecnt; ++i)
2070  writetype[i] = thistimecnt == timecnt;
2071  if (thistimecnt == 0)
2072  {
2073  /*
2074  * No transition times fall in the current (32- or 64-bit) window.
2075  */
2076  if (typecnt != 0)
2077  writetype[typecnt - 1] = true;
2078  }
2079  else
2080  {
2081  for (i = thistimei - 1; i < thistimelim; ++i)
2082  if (i >= 0)
2083  writetype[types[i]] = true;
2084 
2085  /*
2086  * For America/Godthab and Antarctica/Palmer
2087  */
2088  if (thistimei == 0)
2089  writetype[0] = true;
2090  }
2091 #ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH
2092 
2093  /*
2094  * For some pre-2011 systems: if the last-to-be-written standard (or
2095  * daylight) type has an offset different from the most recently used
2096  * offset, append an (unused) copy of the most recently used type (to
2097  * help get global "altzone" and "timezone" variables set correctly).
2098  */
2099  {
2100  int mrudst,
2101  mrustd,
2102  hidst,
2103  histd,
2104  type;
2105 
2106  hidst = histd = mrudst = mrustd = -1;
2107  for (i = thistimei; i < thistimelim; ++i)
2108  if (isdsts[types[i]])
2109  mrudst = types[i];
2110  else
2111  mrustd = types[i];
2112  for (i = 0; i < typecnt; ++i)
2113  if (writetype[i])
2114  {
2115  if (isdsts[i])
2116  hidst = i;
2117  else
2118  histd = i;
2119  }
2120  if (hidst >= 0 && mrudst >= 0 && hidst != mrudst &&
2121  gmtoffs[hidst] != gmtoffs[mrudst])
2122  {
2123  isdsts[mrudst] = -1;
2124  type = addtype(gmtoffs[mrudst],
2125  &chars[abbrinds[mrudst]],
2126  true,
2127  ttisstds[mrudst],
2128  ttisgmts[mrudst]);
2129  isdsts[mrudst] = 1;
2130  writetype[type] = true;
2131  }
2132  if (histd >= 0 && mrustd >= 0 && histd != mrustd &&
2133  gmtoffs[histd] != gmtoffs[mrustd])
2134  {
2135  isdsts[mrustd] = -1;
2136  type = addtype(gmtoffs[mrustd],
2137  &chars[abbrinds[mrustd]],
2138  false,
2139  ttisstds[mrustd],
2140  ttisgmts[mrustd]);
2141  isdsts[mrustd] = 0;
2142  writetype[type] = true;
2143  }
2144  }
2145 #endif /* !defined
2146  * LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */
2147  thistypecnt = 0;
2148  for (i = 0; i < typecnt; ++i)
2149  typemap[i] = writetype[i] ? thistypecnt++ : -1;
2150  for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i)
2151  indmap[i] = -1;
2152  thischarcnt = 0;
2153  for (i = 0; i < typecnt; ++i)
2154  {
2155  char *thisabbr;
2156 
2157  if (!writetype[i])
2158  continue;
2159  if (indmap[abbrinds[i]] >= 0)
2160  continue;
2161  thisabbr = &chars[abbrinds[i]];
2162  for (j = 0; j < thischarcnt; ++j)
2163  if (strcmp(&thischars[j], thisabbr) == 0)
2164  break;
2165  if (j == thischarcnt)
2166  {
2167  strcpy(&thischars[thischarcnt], thisabbr);
2168  thischarcnt += strlen(thisabbr) + 1;
2169  }
2170  indmap[abbrinds[i]] = j;
2171  }
2172 #define DO(field) fwrite(tzh.field, sizeof tzh.field, 1, fp)
2173  tzh = tzh0;
2174  strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
2175  tzh.tzh_version[0] = version;
2176  convert(thistypecnt, tzh.tzh_ttisgmtcnt);
2177  convert(thistypecnt, tzh.tzh_ttisstdcnt);
2178  convert(thisleapcnt, tzh.tzh_leapcnt);
2179  convert(thistimecnt, tzh.tzh_timecnt);
2180  convert(thistypecnt, tzh.tzh_typecnt);
2181  convert(thischarcnt, tzh.tzh_charcnt);
2182  DO(tzh_magic);
2183  DO(tzh_version);
2184  DO(tzh_reserved);
2185  DO(tzh_ttisgmtcnt);
2186  DO(tzh_ttisstdcnt);
2187  DO(tzh_leapcnt);
2188  DO(tzh_timecnt);
2189  DO(tzh_typecnt);
2190  DO(tzh_charcnt);
2191 #undef DO
2192  for (i = thistimei; i < thistimelim; ++i)
2193  if (pass == 1)
2194 
2195  /*
2196  * Output an INT32_MIN "transition" if appropriate; see above.
2197  */
2198  puttzcode(((ats[i] < PG_INT32_MIN) ?
2199  PG_INT32_MIN : ats[i]), fp);
2200  else
2201  {
2202  puttzcode64(ats[i], fp);
2203 
2204  /* Print current timezone abbreviations if requested */
2205  if (print_abbrevs &&
2206  (i == thistimelim - 1 || ats[i + 1] > print_cutoff))
2207  {
2208  unsigned char tm = typemap[types[i]];
2209  char *thisabbrev = &thischars[indmap[abbrinds[tm]]];
2210 
2211  /* filter out assorted junk entries */
2212  if (strcmp(thisabbrev, GRANDPARENTED) != 0 &&
2213  strcmp(thisabbrev, "zzz") != 0)
2214  fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
2215  thisabbrev,
2216  gmtoffs[tm],
2217  isdsts[tm] ? "\tD" : "");
2218  }
2219  }
2220  for (i = thistimei; i < thistimelim; ++i)
2221  {
2222  unsigned char uc;
2223 
2224  uc = typemap[types[i]];
2225  fwrite(&uc, sizeof uc, 1, fp);
2226  }
2227  for (i = 0; i < typecnt; ++i)
2228  if (writetype[i])
2229  {
2230  puttzcode(gmtoffs[i], fp);
2231  putc(isdsts[i], fp);
2232  putc((unsigned char) indmap[abbrinds[i]], fp);
2233  }
2234  if (thischarcnt != 0)
2235  fwrite(thischars, sizeof thischars[0],
2236  thischarcnt, fp);
2237  for (i = thisleapi; i < thisleaplim; ++i)
2238  {
2239  zic_t todo;
2240 
2241  if (roll[i])
2242  {
2243  if (timecnt == 0 || trans[i] < ats[0])
2244  {
2245  j = 0;
2246  while (isdsts[j])
2247  if (++j >= typecnt)
2248  {
2249  j = 0;
2250  break;
2251  }
2252  }
2253  else
2254  {
2255  j = 1;
2256  while (j < timecnt &&
2257  trans[i] >= ats[j])
2258  ++j;
2259  j = types[j - 1];
2260  }
2261  todo = tadd(trans[i], -gmtoffs[j]);
2262  }
2263  else
2264  todo = trans[i];
2265  if (pass == 1)
2266  puttzcode(todo, fp);
2267  else
2268  puttzcode64(todo, fp);
2269  puttzcode(corr[i], fp);
2270  }
2271  for (i = 0; i < typecnt; ++i)
2272  if (writetype[i])
2273  putc(ttisstds[i], fp);
2274  for (i = 0; i < typecnt; ++i)
2275  if (writetype[i])
2276  putc(ttisgmts[i], fp);
2277  }
2278  fprintf(fp, "\n%s\n", string);
2279  close_file(fp, directory, name);
2280  free(ats);
2281 }
static bool ttisstds[TZ_MAX_TYPES]
Definition: zic.c:384
static bool print_abbrevs
Definition: zic.c:179
static zic_t print_cutoff
Definition: zic.c:180
static int typecnt
Definition: zic.c:186
static zic_t gmtoffs[TZ_MAX_TYPES]
Definition: zic.c:381
static unsigned char abbrinds[TZ_MAX_TYPES]
Definition: zic.c:383
struct typedefs * types
Definition: ecpg.c:29
unsigned char type
Definition: zic.c:379
static char isdsts[TZ_MAX_TYPES]
Definition: zic.c:382
static void static void static void warning(const char *string,...) pg_attribute_printf(1
Definition: zic.c:500
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:388
static bool is32(const zic_t x)
Definition: zic.c:1861
#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:385
static void mkdirs(char const *, bool)
Definition: zic.c:3669
#define GRANDPARENTED
Definition: private.h:27
static const zic_t early_time
Definition: zic.c:1015
static struct pg_tm tm
Definition: localtime.c:107
static zic_t tadd(zic_t t1, zic_t t2)
Definition: zic.c:3504
static void convert(const int32 val, char *const buf)
Definition: zic.c:1812
static int addtype(zic_t, char const *, bool, bool, bool)
Definition: zic.c:3052
char tzh_magic[4]
Definition: tzfile.h:35
#define TZ_MAGIC
Definition: tzfile.h:31
static int leapcnt
Definition: zic.c:169
int64 zic_t
Definition: zic.c:23
char tzh_leapcnt[4]
Definition: tzfile.h:40
#define PG_INT32_MIN
Definition: c.h:378
#define TZ_MAX_CHARS
Definition: tzfile.h:98
zic_t at
Definition: zic.c:377
static void puttzcode64(const zic_t val, FILE *const fp)
Definition: zic.c:1843
static struct attype * attypes
static bool noise
Definition: zic.c:178
Definition: tzfile.h:33
char tzh_typecnt[4]
Definition: tzfile.h:42
static const char * progname
Definition: zic.c:183
#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:184
static const char * directory
Definition: zic.c:567
static void close_file(FILE *stream, char const *dir, char const *name)
Definition: zic.c:512
#define INT64_FORMAT
Definition: c.h:338
const char * name
Definition: encode.c:521
static int atcomp(const void *avp, const void *bvp)
Definition: zic.c:1852
e
Definition: preproc-init.c:82
static zic_t trans[TZ_MAX_LEAPS]
Definition: zic.c:387
#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:408
#define DO(field)
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
static char chars[TZ_MAX_CHARS]
Definition: zic.c:386
#define _(x)
Definition: elog.c:84
static size_t size_product(size_t nitems, size_t itemsize)
Definition: zic.c:403
static void puttzcode(const int32 val, FILE *const fp)
Definition: zic.c:1834
static char roll[TZ_MAX_LEAPS]
Definition: zic.c:389
static void * emalloc(size_t size)
Definition: zic.c:419
char tzh_ttisgmtcnt[4]
Definition: tzfile.h:38

◆ yearistype()

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

Definition at line 3165 of file zic.c.

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

Referenced by outzone().

3166 {
3167  char *buf;
3168  char *b;
3169  int result;
3170 
3171  if (type == NULL || *type == '\0')
3172  return true;
3173  buf = emalloc(1 + 4 * strlen(yitcommand) + 2
3174  + INT_STRLEN_MAXIMUM(zic_t) +2 + 4 * strlen(type) + 2);
3175  b = shellquote(buf, yitcommand);
3176  *b++ = ' ';
3177  b += sprintf(b, INT64_FORMAT, year);
3178  *b++ = ' ';
3179  b = shellquote(b, type);
3180  *b = '\0';
3181  result = system(buf);
3182  if (WIFEXITED(result))
3183  {
3184  int status = WEXITSTATUS(result);
3185 
3186  if (status <= 1)
3187  {
3188  free(buf);
3189  return status == 0;
3190  }
3191  }
3192  error(_("Wild result from command execution"));
3193  fprintf(stderr, _("%s: command was '%s', result was %d\n"),
3194  progname, buf, result);
3195  exit(EXIT_FAILURE);
3196 }
#define INT_STRLEN_MAXIMUM(type)
Definition: private.h:74
static const char * yitcommand
Definition: zic.c:569
static char * shellquote(char *b, char const *s)
Definition: zic.c:3151
static char * buf
Definition: pg_test_fsync.c:67
int64 zic_t
Definition: zic.c:23
#define WIFEXITED(w)
Definition: win32_port.h:147
static const char * progname
Definition: zic.c:183
#define free(a)
Definition: header.h:65
#define INT64_FORMAT
Definition: c.h:338
#define EXIT_FAILURE
Definition: settings.h:152
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
static void static void error(const char *string,...) pg_attribute_printf(1
Definition: zic.c:489
#define _(x)
Definition: elog.c:84
#define WEXITSTATUS(w)
Definition: win32_port.h:149
static void * emalloc(size_t size)
Definition: zic.c:419

Variable Documentation

◆ abbrinds

unsigned char abbrinds[TZ_MAX_TYPES]
static

Definition at line 383 of file zic.c.

◆ attypes

struct attype * attypes
static

Referenced by addtt(), outzone(), and writezone().

◆ begin_years

struct lookup const begin_years[]
static
Initial value:
= {
{"minimum", YR_MINIMUM},
{"maximum", YR_MAXIMUM},
{NULL, 0}
}
#define YR_MINIMUM
Definition: zic.c:265
#define YR_MAXIMUM
Definition: zic.c:266

Definition at line 347 of file zic.c.

◆ charcnt

int charcnt
static

Definition at line 165 of file zic.c.

Referenced by addtype(), pg_interpret_timezone_abbrev(), tzloadbody(), and tzparse().

◆ chars

char chars[TZ_MAX_CHARS]
static

Definition at line 386 of file zic.c.

Referenced by getColorInfo().

◆ corr

zic_t corr[TZ_MAX_LEAPS]
static

Definition at line 388 of file zic.c.

Referenced by timesub(), and tzloadbody().

◆ directory

const char* directory
static

Definition at line 567 of file zic.c.

Referenced by main().

◆ early_time

const zic_t early_time
static
Initial value:
#define TIME_T_BITS_IN_FILE
Definition: zic.c:972
#define MINVAL(t, b)
Definition: private.h:61
int64 zic_t
Definition: zic.c:23
#define BIG_BANG
Definition: zic.c:1000

Definition at line 1015 of file zic.c.

◆ end_years

struct lookup const end_years[]
static
Initial value:
= {
{"minimum", YR_MINIMUM},
{"maximum", YR_MAXIMUM},
{"only", YR_ONLY},
{NULL, 0}
}
#define YR_MINIMUM
Definition: zic.c:265
#define YR_ONLY
Definition: zic.c:267
#define YR_MAXIMUM
Definition: zic.c:266

Definition at line 353 of file zic.c.

◆ errors