PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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
 
struct  timerange
 

Macros

#define ZIC_VERSION_PRE_2013   '2'
 
#define ZIC_VERSION   '3'
 
#define ZIC_MIN   INT_FAST64_MIN
 
#define ZIC_MAX   INT_FAST64_MAX
 
#define PRIdZIC   PRIdFAST64
 
#define SCNdZIC   SCNdFAST64
 
#define ZIC_MAX_ABBR_LEN_WO_WARN   6
 
#define MKDIR_UMASK   0755
 
#define _Alignof(type)   offsetof(struct { char a; type b; }, b)
 
#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 linkat(targetdir, target, linknamedir, linkname, flag)    (itssymlink(target) ? (errno = ENOTSUP, -1) : link(target, linkname))
 
#define LC_RULE   0
 
#define LC_ZONE   1
 
#define LC_LINK   2
 
#define LC_LEAP   3
 
#define LC_EXPIRES   4
 
#define ZF_NAME   1
 
#define ZF_STDOFF   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_STDOFF   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_SAVE   8
 
#define RF_ABBRVAR   9
 
#define RULE_FIELDS   10
 
#define LF_TARGET   1
 
#define LF_LINKNAME   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 EXPIRES_FIELDS   5
 
#define YR_MINIMUM   0
 
#define YR_MAXIMUM   1
 
#define YR_ONLY   2
 
#define TIME_T_BITS_IN_FILE   64
 
#define ZIC_BLOAT_DEFAULT   "slim"
 
#define DO(field)   fwrite(tzh.field, sizeof tzh.field, 1, fp)
 
#define LDAYSPERWEEK   ((zic_t) DAYSPERWEEK)
 

Typedefs

typedef int_fast64_t zic_t
 
typedef intmax_t lineno_t
 

Enumerations

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

Functions

int link (const char *target, const char *linkname)
 
static void verror (const char *const string, va_list args) pg_attribute_printf(1
 
static void static void error (const char *const string,...) pg_attribute_printf(1
 
static void static void static void warning (const char *const string,...) pg_attribute_printf(1
 
static void static void static void static void addtt (zic_t starttime, int type)
 
static int addtype (zic_t utoff, char const *abbr, bool isdst, bool ttisstd, bool ttisut)
 
static void leapadd (zic_t t, int correction, int rolling)
 
static void adjleap (void)
 
static void associate (void)
 
static void dolink (const char *target, const char *linkname, bool staysymlink)
 
static char ** getfields (char *cp)
 
static zic_t gethms (const char *string, const char *errstring)
 
static zic_t getsave (char *field, bool *isdst)
 
static void inexpires (char **fields, int nfields)
 
static void infile (const char *name)
 
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 **fields, int nfields, bool iscont)
 
static bool itsdir (char const *name)
 
static bool itssymlink (char const *name)
 
static bool is_alpha (char a)
 
static char lowerit (char a)
 
static void mkdirs (char const *argname, bool ancestors)
 
static void newabbr (const char *string)
 
static zic_t oadd (zic_t t1, zic_t t2)
 
static void outzone (const struct zone *zpfirst, ptrdiff_t zonecount)
 
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 struct lookup constbyword (const char *word, const struct lookup *table)
 
static _Noreturn void memory_exhausted (const char *msg)
 
static size_t size_product (size_t nitems, size_t itemsize)
 
static size_t align_to (size_t size, size_t alignment)
 
static voidmemcheck (void *ptr)
 
static voidemalloc (size_t size)
 
static voiderealloc (void *ptr, size_t size)
 
static charecpyalloc (char const *str)
 
static voidgrowalloc (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 _Noreturn void usage (FILE *stream, int status)
 
static void change_directory (char const *dir)
 
static bool timerange_option (char *timerange)
 
static bool want_bloat (void)
 
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 charrelname (char const *target, char const *linkname)
 
static int hardlinkerr (char const *target, char const *linkname)
 
static int rcomp (const void *cp1, const void *cp2)
 
static zic_t getleapdatetime (char **fields, int nfields, bool expire_line)
 
static void convert (const int_fast32_t val, char *const buf)
 
static void convert64 (const zic_t val, char *const buf)
 
static void puttzcode (const int_fast32_t val, FILE *const fp)
 
static void puttzcodepass (zic_t val, FILE *fp, int pass)
 
static int atcomp (const void *avp, const void *bvp)
 
static struct timerange limitrange (struct timerange r, zic_t lo, zic_t hi, zic_t const *ats, unsigned char const *types)
 
static void writezone (const char *const name, const char *const string, char version, int defaulttype)
 
static char constabbroffset (char *buf, zic_t offset)
 
static size_t doabbr (char *abbr, struct zone const *zp, char const *letters, bool isdst, zic_t save, bool doquotes)
 
static void updateminmax (const zic_t x)
 
static int stringoffset (char *result, zic_t offset)
 
static int stringrule (char *result, struct rule *const rp, zic_t save, zic_t stdoff)
 
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 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 _Noreturn 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 charfilename
 
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 charrfilename
 
static lineno_t rlinenum
 
static const charprogname
 
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 utoffs [TZ_MAX_TYPES]
 
static char isdsts [TZ_MAX_TYPES]
 
static unsigned char desigidx [TZ_MAX_TYPES]
 
static bool ttisstds [TZ_MAX_TYPES]
 
static bool ttisuts [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 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 zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE)
 
static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE)
 
static zic_t leapexpires = -1
 
static zic_t comment_leapexpires = -1
 
static const charpsxrules
 
static const charlcltime
 
static const chardirectory
 
static const charleapsec
 
static const chartzdefault
 
static int bloat
 

Macro Definition Documentation

◆ _Alignof

#define _Alignof (   type)    offsetof(struct { char a; type b; }, b)

Definition at line 54 of file zic.c.

◆ DC_DOM

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

Definition at line 96 of file zic.c.

◆ DC_DOWGEQ

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

Definition at line 97 of file zic.c.

◆ DC_DOWLEQ

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

Definition at line 98 of file zic.c.

◆ DO

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

◆ EXPIRES_FIELDS

#define EXPIRES_FIELDS   5

Definition at line 280 of file zic.c.

◆ LC_EXPIRES

#define LC_EXPIRES   4

Definition at line 213 of file zic.c.

◆ LC_LEAP

#define LC_LEAP   3

Definition at line 212 of file zic.c.

◆ LC_LINK

#define LC_LINK   2

Definition at line 211 of file zic.c.

◆ LC_RULE

#define LC_RULE   0

Definition at line 209 of file zic.c.

◆ LC_ZONE

#define LC_ZONE   1

Definition at line 210 of file zic.c.

◆ LDAYSPERWEEK

#define LDAYSPERWEEK   ((zic_t) DAYSPERWEEK)

◆ LEAP_FIELDS

#define LEAP_FIELDS   7

Definition at line 277 of file zic.c.

◆ LF_LINKNAME

#define LF_LINKNAME   2

Definition at line 264 of file zic.c.

◆ LF_TARGET

#define LF_TARGET   1

Definition at line 263 of file zic.c.

◆ LINK_FIELDS

#define LINK_FIELDS   3

Definition at line 265 of file zic.c.

◆ linkat

#define linkat (   targetdir,
  target,
  linknamedir,
  linkname,
  flag 
)     (itssymlink(target) ? (errno = ENOTSUP, -1) : link(target, linkname))

Definition at line 123 of file zic.c.

124 : link(target, linkname))
static int fb(int x)

◆ LP_CORR

#define LP_CORR   5

Definition at line 275 of file zic.c.

◆ LP_DAY

#define LP_DAY   3

Definition at line 273 of file zic.c.

◆ LP_MONTH

#define LP_MONTH   2

Definition at line 272 of file zic.c.

◆ LP_ROLL

#define LP_ROLL   6

Definition at line 276 of file zic.c.

◆ LP_TIME

#define LP_TIME   4

Definition at line 274 of file zic.c.

◆ LP_YEAR

#define LP_YEAR   1

Definition at line 271 of file zic.c.

◆ MKDIR_UMASK

#define MKDIR_UMASK   0755

Definition at line 39 of file zic.c.

◆ PRIdZIC

#define PRIdZIC   PRIdFAST64

Definition at line 28 of file zic.c.

◆ RF_ABBRVAR

#define RF_ABBRVAR   9

Definition at line 256 of file zic.c.

◆ RF_COMMAND

#define RF_COMMAND   4

Definition at line 251 of file zic.c.

◆ RF_DAY

#define RF_DAY   6

Definition at line 253 of file zic.c.

◆ RF_HIYEAR

#define RF_HIYEAR   3

Definition at line 250 of file zic.c.

◆ RF_LOYEAR

#define RF_LOYEAR   2

Definition at line 249 of file zic.c.

◆ RF_MONTH

#define RF_MONTH   5

Definition at line 252 of file zic.c.

◆ RF_NAME

#define RF_NAME   1

Definition at line 248 of file zic.c.

◆ RF_SAVE

#define RF_SAVE   8

Definition at line 255 of file zic.c.

◆ RF_TOD

#define RF_TOD   7

Definition at line 254 of file zic.c.

◆ RULE_FIELDS

#define RULE_FIELDS   10

Definition at line 257 of file zic.c.

◆ SCNdZIC

#define SCNdZIC   SCNdFAST64

Definition at line 29 of file zic.c.

◆ TIME_T_BITS_IN_FILE

#define TIME_T_BITS_IN_FILE   64

Definition at line 602 of file zic.c.

◆ YR_MAXIMUM

#define YR_MAXIMUM   1

Definition at line 287 of file zic.c.

◆ YR_MINIMUM

#define YR_MINIMUM   0

Definition at line 286 of file zic.c.

◆ YR_ONLY

#define YR_ONLY   2

Definition at line 288 of file zic.c.

◆ ZF_FORMAT

#define ZF_FORMAT   4

Definition at line 222 of file zic.c.

◆ ZF_NAME

#define ZF_NAME   1

Definition at line 219 of file zic.c.

◆ ZF_RULE

#define ZF_RULE   3

Definition at line 221 of file zic.c.

◆ ZF_STDOFF

#define ZF_STDOFF   2

Definition at line 220 of file zic.c.

◆ ZF_TILDAY

#define ZF_TILDAY   7

Definition at line 225 of file zic.c.

◆ ZF_TILMONTH

#define ZF_TILMONTH   6

Definition at line 224 of file zic.c.

◆ ZF_TILTIME

#define ZF_TILTIME   8

Definition at line 226 of file zic.c.

◆ ZF_TILYEAR

#define ZF_TILYEAR   5

Definition at line 223 of file zic.c.

◆ ZFC_FORMAT

#define ZFC_FORMAT   2

Definition at line 236 of file zic.c.

◆ ZFC_RULE

#define ZFC_RULE   1

Definition at line 235 of file zic.c.

◆ ZFC_STDOFF

#define ZFC_STDOFF   0

Definition at line 234 of file zic.c.

◆ ZFC_TILDAY

#define ZFC_TILDAY   5

Definition at line 239 of file zic.c.

◆ ZFC_TILMONTH

#define ZFC_TILMONTH   4

Definition at line 238 of file zic.c.

◆ ZFC_TILTIME

#define ZFC_TILTIME   6

Definition at line 240 of file zic.c.

◆ ZFC_TILYEAR

#define ZFC_TILYEAR   3

Definition at line 237 of file zic.c.

◆ ZIC_BLOAT_DEFAULT

#define ZIC_BLOAT_DEFAULT   "slim"

Definition at line 676 of file zic.c.

◆ ZIC_MAX

#define ZIC_MAX   INT_FAST64_MAX

Definition at line 27 of file zic.c.

◆ ZIC_MAX_ABBR_LEN_WO_WARN

#define ZIC_MAX_ABBR_LEN_WO_WARN   6

Definition at line 32 of file zic.c.

◆ ZIC_MIN

#define ZIC_MIN   INT_FAST64_MIN

Definition at line 26 of file zic.c.

◆ ZIC_VERSION

#define ZIC_VERSION   '3'

Definition at line 23 of file zic.c.

◆ ZIC_VERSION_PRE_2013

#define ZIC_VERSION_PRE_2013   '2'

Definition at line 22 of file zic.c.

◆ ZONE_MAXFIELDS

#define ZONE_MAXFIELDS   9

Definition at line 228 of file zic.c.

◆ ZONE_MINFIELDS

#define ZONE_MINFIELDS   5

Definition at line 227 of file zic.c.

◆ ZONEC_MAXFIELDS

#define ZONEC_MAXFIELDS   7

Definition at line 242 of file zic.c.

◆ ZONEC_MINFIELDS

#define ZONEC_MINFIELDS   3

Definition at line 241 of file zic.c.

Typedef Documentation

◆ lineno_t

Definition at line 62 of file zic.c.

◆ zic_t

Definition at line 25 of file zic.c.

Enumeration Type Documentation

◆ anonymous enum

Enumerator
PERCENT_Z_LEN_BOUND 

Definition at line 165 of file zic.c.

166{
167PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1};
@ PERCENT_Z_LEN_BOUND
Definition zic.c:167

◆ anonymous enum

Enumerator
WORK_AROUND_QTBUG_53071 

Definition at line 177 of file zic.c.

178{
@ WORK_AROUND_QTBUG_53071
Definition zic.c:179

Function Documentation

◆ abbroffset()

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

Definition at line 2589 of file zic.c.

2590{
2591 char sign = '+';
2592 int seconds,
2593 minutes;
2594
2595 if (offset < 0)
2596 {
2597 offset = -offset;
2598 sign = '-';
2599 }
2600
2601 seconds = offset % SECSPERMIN;
2602 offset /= SECSPERMIN;
2603 minutes = offset % MINSPERHOUR;
2604 offset /= MINSPERHOUR;
2605 if (100 <= offset)
2606 {
2607 error(_("%%z UT offset magnitude exceeds 99:59:59"));
2608 return "%z";
2609 }
2610 else
2611 {
2612 char *p = buf;
2613
2614 *p++ = sign;
2615 *p++ = '0' + offset / 10;
2616 *p++ = '0' + offset % 10;
2617 if (minutes | seconds)
2618 {
2619 *p++ = '0' + minutes / 10;
2620 *p++ = '0' + minutes % 10;
2621 if (seconds)
2622 {
2623 *p++ = '0' + seconds / 10;
2624 *p++ = '0' + seconds % 10;
2625 }
2626 }
2627 *p = '\0';
2628 return buf;
2629 }
2630}
#define _(x)
Definition elog.c:96
char sign
Definition informix.c:693
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define SECSPERMIN
Definition private.h:93
#define MINSPERHOUR
Definition private.h:94
static void error(void)

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

Referenced by doabbr().

◆ addtt()

static void addtt ( zic_t  starttime,
int  type 
)
static

Definition at line 3351 of file zic.c.

3352{
3354 attypes[timecnt].at = starttime;
3355 attypes[timecnt].dontmerge = false;
3357 ++timecnt;
3358}
bool dontmerge
Definition zic.c:400
zic_t at
Definition zic.c:399
unsigned char type
Definition zic.c:401
const char * type
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
Definition zic.c:470
static ptrdiff_t timecnt
Definition zic.c:201
static ptrdiff_t timecnt_alloc
Definition zic.c:202
static struct attype * attypes

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

Referenced by outzone().

◆ addtype()

static int addtype ( zic_t  utoff,
char const abbr,
bool  isdst,
bool  ttisstd,
bool  ttisut 
)
static

Definition at line 3361 of file zic.c.

3362{
3363 int i,
3364 j;
3365
3366 if (!(-1L - 2147483647L <= utoff && utoff <= 2147483647L))
3367 {
3368 error(_("UT offset out of range"));
3370 }
3371 if (!want_bloat())
3372 ttisstd = ttisut = false;
3373
3374 for (j = 0; j < charcnt; ++j)
3375 if (strcmp(&chars[j], abbr) == 0)
3376 break;
3377 if (j == charcnt)
3378 newabbr(abbr);
3379 else
3380 {
3381 /* If there's already an entry, return its index. */
3382 for (i = 0; i < typecnt; i++)
3383 if (utoff == utoffs[i] && isdst == isdsts[i] && j == desigidx[i]
3384 && ttisstd == ttisstds[i] && ttisut == ttisuts[i])
3385 return i;
3386 }
3387
3388 /*
3389 * There isn't one; add a new one, unless there are already too many.
3390 */
3391 if (typecnt >= TZ_MAX_TYPES)
3392 {
3393 error(_("too many local time types"));
3395 }
3396 i = typecnt++;
3397 utoffs[i] = utoff;
3398 isdsts[i] = isdst;
3399 ttisstds[i] = ttisstd;
3400 ttisuts[i] = ttisut;
3401 desigidx[i] = j;
3402 return i;
3403}
int j
Definition isn.c:78
int i
Definition isn.c:77
#define EXIT_FAILURE
Definition settings.h:197
#define TZ_MAX_TYPES
Definition tzfile.h:103
static char chars[TZ_MAX_CHARS]
Definition zic.c:408
static int typecnt
Definition zic.c:203
static unsigned char desigidx[TZ_MAX_TYPES]
Definition zic.c:405
static bool ttisuts[TZ_MAX_TYPES]
Definition zic.c:407
static char isdsts[TZ_MAX_TYPES]
Definition zic.c:404
static bool ttisstds[TZ_MAX_TYPES]
Definition zic.c:406
static bool want_bloat(void)
Definition zic.c:670
static void newabbr(const char *string)
Definition zic.c:3915
static int charcnt
Definition zic.c:182
static zic_t utoffs[TZ_MAX_TYPES]
Definition zic.c:403

References _, charcnt, chars, desigidx, error(), EXIT_FAILURE, fb(), i, isdsts, j, newabbr(), ttisstds, ttisuts, typecnt, TZ_MAX_TYPES, utoffs, and want_bloat().

Referenced by outzone(), and writezone().

◆ adjleap()

static void adjleap ( void  )
static

Definition at line 3428 of file zic.c.

3429{
3430 int i;
3431 zic_t last = 0;
3432 zic_t prevtrans = 0;
3433
3434 /*
3435 * propagate leap seconds forward
3436 */
3437 for (i = 0; i < leapcnt; ++i)
3438 {
3439 if (trans[i] - prevtrans < 28 * SECSPERDAY)
3440 {
3441 error(_("Leap seconds too close together"));
3443 }
3444 prevtrans = trans[i];
3445 trans[i] = tadd(trans[i], last);
3446 last = corr[i] += last;
3447 }
3448
3449 if (leapexpires < 0)
3450 {
3452 if (0 <= leapexpires)
3453 warning(_("\"#expires\" is obsolescent; use \"Expires\""));
3454 }
3455
3456 if (0 <= leapexpires)
3457 {
3458 leapexpires = oadd(leapexpires, last);
3459 if (!(leapcnt == 0 || (trans[leapcnt - 1] < leapexpires)))
3460 {
3461 error(_("last Leap time does not precede Expires time"));
3463 }
3464 if (leapexpires <= hi_time)
3465 hi_time = leapexpires - 1;
3466 }
3467}
#define SECSPERDAY
Definition private.h:100
static zic_t tadd(zic_t t1, zic_t t2)
Definition zic.c:3777
static zic_t comment_leapexpires
Definition zic.c:619
static void static void static void warning(const char *const string,...) pg_attribute_printf(1
Definition zic.c:533
static zic_t leapexpires
Definition zic.c:616
static zic_t oadd(zic_t t1, zic_t t2)
Definition zic.c:3769
static int leapcnt
Definition zic.c:186
int_fast64_t zic_t
Definition zic.c:25
static zic_t hi_time
Definition zic.c:613
static zic_t trans[TZ_MAX_LEAPS]
Definition zic.c:409
static zic_t corr[TZ_MAX_LEAPS]
Definition zic.c:410

References _, comment_leapexpires, corr, error(), EXIT_FAILURE, fb(), hi_time, i, leapcnt, leapexpires, oadd(), SECSPERDAY, tadd(), trans, and warning().

Referenced by main().

◆ align_to()

static size_t align_to ( size_t  size,
size_t  alignment 
)
static

Definition at line 433 of file zic.c.

434{
435 size_t aligned_size = size + alignment - 1;
436
437 aligned_size -= aligned_size % alignment;
438 if (aligned_size < size)
439 memory_exhausted(_("alignment overflow"));
440 return aligned_size;
441}
static _Noreturn void memory_exhausted(const char *msg)
Definition zic.c:418

References _, fb(), and memory_exhausted().

Referenced by writezone().

◆ associate()

static void associate ( void  )
static

Definition at line 1186 of file zic.c.

1187{
1188 struct zone *zp;
1189 struct rule *rp;
1190 ptrdiff_t i,
1191 j,
1192 base,
1193 out;
1194
1195 if (nrules != 0)
1196 {
1197 qsort(rules, nrules, sizeof *rules, rcomp);
1198 for (i = 0; i < nrules - 1; ++i)
1199 {
1200 if (strcmp(rules[i].r_name,
1201 rules[i + 1].r_name) != 0)
1202 continue;
1203 if (strcmp(rules[i].r_filename,
1204 rules[i + 1].r_filename) == 0)
1205 continue;
1207 warning(_("same rule name in multiple files"));
1208 eat(rules[i + 1].r_filename, rules[i + 1].r_linenum);
1209 warning(_("same rule name in multiple files"));
1210 for (j = i + 2; j < nrules; ++j)
1211 {
1212 if (strcmp(rules[i].r_name,
1213 rules[j].r_name) != 0)
1214 break;
1215 if (strcmp(rules[i].r_filename,
1216 rules[j].r_filename) == 0)
1217 continue;
1218 if (strcmp(rules[i + 1].r_filename,
1219 rules[j].r_filename) == 0)
1220 continue;
1221 break;
1222 }
1223 i = j - 1;
1224 }
1225 }
1226 for (i = 0; i < nzones; ++i)
1227 {
1228 zp = &zones[i];
1229 zp->z_rules = NULL;
1230 zp->z_nrules = 0;
1231 }
1232 for (base = 0; base < nrules; base = out)
1233 {
1234 rp = &rules[base];
1235 for (out = base + 1; out < nrules; ++out)
1236 if (strcmp(rp->r_name, rules[out].r_name) != 0)
1237 break;
1238 for (i = 0; i < nzones; ++i)
1239 {
1240 zp = &zones[i];
1241 if (strcmp(zp->z_rule, rp->r_name) != 0)
1242 continue;
1243 zp->z_rules = rp;
1244 zp->z_nrules = out - base;
1245 }
1246 }
1247 for (i = 0; i < nzones; ++i)
1248 {
1249 zp = &zones[i];
1250 if (zp->z_nrules == 0)
1251 {
1252 /*
1253 * Maybe we have a local standard time offset.
1254 */
1255 eat(zp->z_filename, zp->z_linenum);
1256 zp->z_save = getsave(zp->z_rule, &zp->z_isdst);
1257
1258 /*
1259 * Note, though, that if there's no rule, a '%s' in the format is
1260 * a bad thing.
1261 */
1262 if (zp->z_format_specifier == 's')
1263 error("%s", _("%s in ruleless zone"));
1264 }
1265 }
1266 if (errors)
1268}
#define qsort(a, b, c, d)
Definition port.h:496
const char * r_filename
Definition zic.c:66
const char * r_name
Definition zic.c:68
lineno_t r_linenum
Definition zic.c:67
Definition zic.c:101
struct rule * z_rules
Definition zic.c:114
static struct zone * zones
Definition zic.c:294
static void eat(char const *name, lineno_t num)
Definition zic.c:500
static ptrdiff_t nrules
Definition zic.c:291
static struct rule * rules
Definition zic.c:290
static zic_t getsave(char *field, bool *isdst)
Definition zic.c:1454
static bool errors
Definition zic.c:183
static ptrdiff_t nzones
Definition zic.c:295
static int rcomp(const void *cp1, const void *cp2)
Definition zic.c:1179

References _, eat(), error(), errors, EXIT_FAILURE, fb(), getsave(), i, j, nrules, nzones, qsort, rule::r_filename, rule::r_linenum, rule::r_name, rcomp(), rules, warning(), zone::z_rules, and zones.

Referenced by main().

◆ atcomp()

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

Definition at line 2039 of file zic.c.

2040{
2041 const zic_t a = ((const struct attype *) avp)->at;
2042 const zic_t b = ((const struct attype *) bvp)->at;
2043
2044 return (a < b) ? -1 : (a > b);
2045}
int b
Definition isn.c:74
int a
Definition isn.c:73
Definition zic.c:398

References a, b, and fb().

Referenced by writezone().

◆ byword()

static const struct lookup * byword ( const char word,
const struct lookup table 
)
static

Definition at line 3656 of file zic.c.

3657{
3658 const struct lookup *foundlp;
3659 const struct lookup *lp;
3660
3661 if (word == NULL || table == NULL)
3662 return NULL;
3663
3664 /*
3665 * If TABLE is LASTS and the word starts with "last" followed by a
3666 * non-'-', skip the "last" and look in WDAY_NAMES instead. Warn about any
3667 * usage of the undocumented prefix "last-".
3668 */
3669 if (table == lasts && ciprefix("last", word) && word[4])
3670 {
3671 if (word[4] == '-')
3672 warning(_("\"%s\" is undocumented; use \"last%s\" instead"),
3673 word, word + 5);
3674 else
3675 {
3676 word += 4;
3677 table = wday_names;
3678 }
3679 }
3680
3681 /*
3682 * Look for exact match.
3683 */
3684 for (lp = table; lp->l_word != NULL; ++lp)
3685 if (ciequal(word, lp->l_word))
3686 return lp;
3687
3688 /*
3689 * Look for inexact match.
3690 */
3691 foundlp = NULL;
3692 for (lp = table; lp->l_word != NULL; ++lp)
3693 if (ciprefix(word, lp->l_word))
3694 {
3695 if (foundlp == NULL)
3696 foundlp = lp;
3697 else
3698 return NULL; /* multiple inexact matches */
3699 }
3700
3701 if (foundlp && noise)
3702 {
3703 /* Warn about any backward-compatibility issue with pre-2017c zic. */
3704 bool pre_2017c_match = false;
3705
3706 for (lp = table; lp->l_word; lp++)
3707 if (itsabbr(word, lp->l_word))
3708 {
3709 if (pre_2017c_match)
3710 {
3711 warning(_("\"%s\" is ambiguous in pre-2017c zic"), word);
3712 break;
3713 }
3714 pre_2017c_match = true;
3715 }
3716 }
3717
3718 return foundlp;
3719}
static const struct lconv_member_info table[]
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
Definition regcomp.c:1477
Definition zic.c:311
static struct lookup const lasts[]
Definition zic.c:358
static bool ciprefix(char const *abbr, char const *word)
Definition zic.c:3645
static bool ciequal(const char *ap, const char *bp)
Definition zic.c:3619
static bool itsabbr(const char *abbr, const char *word)
Definition zic.c:3628
static struct lookup const wday_names[]
Definition zic.c:347
static bool noise
Definition zic.c:195

References _, ciequal(), ciprefix(), fb(), itsabbr(), lasts, noise, table, warning(), wday_names, and word().

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

◆ change_directory()

static void change_directory ( char const dir)
static

Definition at line 582 of file zic.c.

583{
584 if (chdir(dir) != 0)
585 {
586 int chdir_errno = errno;
587
588 if (chdir_errno == ENOENT)
589 {
590 mkdirs(dir, false);
591 chdir_errno = chdir(dir) == 0 ? 0 : errno;
592 }
593 if (chdir_errno != 0)
594 {
595 fprintf(stderr, _("%s: Can't chdir to %s: %s\n"),
598 }
599 }
600}
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
#define strerror
Definition port.h:274
static void mkdirs(char const *argname, bool ancestors)
Definition zic.c:3955
static const char * progname
Definition zic.c:200

References _, EXIT_FAILURE, fb(), fprintf, mkdirs(), progname, and strerror.

Referenced by main().

◆ ciequal()

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

Definition at line 3619 of file zic.c.

3620{
3621 while (lowerit(*ap) == lowerit(*bp++))
3622 if (*ap++ == '\0')
3623 return true;
3624 return false;
3625}
static char lowerit(char a)
Definition zic.c:3556

References fb(), and lowerit().

Referenced by byword().

◆ ciprefix()

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

Definition at line 3645 of file zic.c.

3646{
3647 do
3648 if (!*abbr)
3649 return true;
3650 while (lowerit(*abbr++) == lowerit(*word++));
3651
3652 return false;
3653}

References fb(), lowerit(), and word().

Referenced by byword().

◆ close_file()

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

Definition at line 545 of file zic.c.

546{
547 char const *e = (ferror(stream) ? _("I/O error")
548 : fclose(stream) != 0 ? strerror(errno) : NULL);
549
550 if (e)
551 {
552 fprintf(stderr, "%s: %s%s%s%s%s\n", progname,
553 dir ? dir : "", dir ? "/" : "",
554 name ? name : "", name ? ": " : "",
555 e);
557 }
558}
e
const char * name

References _, EXIT_FAILURE, fb(), fprintf, name, progname, and strerror.

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

◆ componentcheck()

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

Definition at line 885 of file zic.c.

887{
888 enum
889 {
890 component_len_max = 14};
892
893 if (component_len == 0)
894 {
895 if (!*name)
896 error(_("empty file name"));
897 else
899 ? "file name '%s' begins with '/'"
901 ? "file name '%s' contains '//'"
902 : "file name '%s' ends with '/'"),
903 name);
904 return false;
905 }
906 if (0 < component_len && component_len <= 2
907 && component[0] == '.' && component_end[-1] == '.')
908 {
909 int len = component_len;
910
911 error(_("file name '%s' contains '%.*s' component"),
912 name, len, component);
913 return false;
914 }
915 if (noise)
916 {
917 if (0 < component_len && component[0] == '-')
918 warning(_("file name '%s' component contains leading '-'"),
919 name);
921 warning(_("file name '%s' contains overlength component"
922 " '%.*s...'"),
924 }
925 return true;
926}
const void size_t len

References _, error(), fb(), len, name, noise, and warning().

Referenced by namecheck().

◆ convert()

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

Definition at line 1994 of file zic.c.

1995{
1996 int i;
1997 int shift;
1998 unsigned char *const b = (unsigned char *) buf;
1999
2000 for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
2001 b[i] = val >> shift;
2002}
long val
Definition informix.c:689

References b, buf, i, and val.

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

◆ convert64()

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

Definition at line 2005 of file zic.c.

2006{
2007 int i;
2008 int shift;
2009 unsigned char *const b = (unsigned char *) buf;
2010
2011 for (i = 0, shift = 56; i < 8; ++i, shift -= 8)
2012 b[i] = val >> shift;
2013}

References b, buf, i, and val.

Referenced by puttzcodepass().

◆ doabbr()

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

Definition at line 2633 of file zic.c.

2635{
2636 char *cp;
2637 char const *slashp;
2638 size_t len;
2639 char const *format = zp->z_format;
2640
2641 slashp = strchr(format, '/');
2642 if (slashp == NULL)
2643 {
2645
2646 if (zp->z_format_specifier == 'z')
2647 letters = abbroffset(letterbuf, zp->z_stdoff + save);
2648 else if (!letters)
2649 letters = "%s";
2651 }
2652 else if (isdst)
2653 {
2654 strcpy(abbr, slashp + 1);
2655 }
2656 else
2657 {
2659 abbr[slashp - format] = '\0';
2660 }
2661 len = strlen(abbr);
2662 if (!doquotes)
2663 return len;
2664 for (cp = abbr; is_alpha(*cp); cp++)
2665 continue;
2666 if (len > 0 && *cp == '\0')
2667 return len;
2668 abbr[len + 2] = '\0';
2669 abbr[len + 1] = '>';
2670 memmove(abbr + 1, abbr, len);
2671 abbr[0] = '<';
2672 return len + 2;
2673}
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
static char format
#define sprintf
Definition port.h:263
static char const * abbroffset(char *buf, zic_t offset)
Definition zic.c:2589
static bool is_alpha(char a)
Definition zic.c:3489

References abbroffset(), fb(), format, is_alpha(), len, memcpy(), PERCENT_Z_LEN_BOUND, and sprintf.

Referenced by outzone(), and stringzone().

◆ dolink()

static void dolink ( const char target,
const char linkname,
bool  staysymlink 
)
static

Definition at line 1032 of file zic.c.

1033{
1034 bool remove_only = strcmp(target, "-") == 0;
1035 bool linkdirs_made = false;
1036 int link_errno;
1037
1038 /*
1039 * We get to be careful here since there's a fair chance of root running
1040 * us.
1041 */
1042 if (!remove_only && itsdir(target))
1043 {
1044 fprintf(stderr, _("%s: linking target %s/%s failed: %s\n"),
1045 progname, directory, target, strerror(EPERM));
1047 }
1048 if (staysymlink)
1050 if (remove(linkname) == 0)
1051 linkdirs_made = true;
1052 else if (errno != ENOENT)
1053 {
1054 char const *e = strerror(errno);
1055
1056 fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
1059 }
1060 if (remove_only)
1061 return;
1063 if (link_errno == ENOENT && !linkdirs_made)
1064 {
1065 mkdirs(linkname, true);
1066 linkdirs_made = true;
1067 link_errno = hardlinkerr(target, linkname);
1068 }
1069 if (link_errno != 0)
1070 {
1071#ifdef HAVE_SYMLINK
1072 bool absolute = *target == '/';
1073 char *linkalloc = absolute ? NULL : relname(target, linkname);
1074 char const *contents = absolute ? target : linkalloc;
1075 int symlink_errno = symlink(contents, linkname) == 0 ? 0 : errno;
1076
1077 if (!linkdirs_made
1079 {
1080 mkdirs(linkname, true);
1081 if (symlink_errno == ENOENT)
1082 symlink_errno = symlink(contents, linkname) == 0 ? 0 : errno;
1083 }
1084 free(linkalloc);
1085 if (symlink_errno == 0)
1086 {
1087 if (link_errno != ENOTSUP)
1088 warning(_("symbolic link used because hard link failed: %s"),
1090 }
1091 else
1092#endif /* HAVE_SYMLINK */
1093 {
1094 FILE *fp,
1095 *tp;
1096 int c;
1097
1098 fp = fopen(target, "rb");
1099 if (!fp)
1100 {
1101 char const *e = strerror(errno);
1102
1103 fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
1104 progname, directory, target, e);
1106 }
1107 tp = fopen(linkname, "wb");
1108 if (!tp)
1109 {
1110 char const *e = strerror(errno);
1111
1112 fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
1115 }
1116 while ((c = getc(fp)) != EOF)
1117 putc(c, tp);
1118 close_file(fp, directory, target);
1120 if (link_errno != ENOTSUP)
1121 warning(_("copy used because hard link failed: %s"),
1123#ifdef HAVE_SYMLINK
1124 else if (symlink_errno != ENOTSUP)
1125 warning(_("copy used because symbolic link failed: %s"),
1127#endif
1128 }
1129 }
1130}
NameData relname
Definition pg_class.h:40
char * c
#define ENOTSUP
Definition private.h:38
#define free(a)
#define symlink(oldpath, newpath)
Definition win32_port.h:225
static bool itsdir(char const *name)
Definition zic.c:1134
static int hardlinkerr(char const *target, char const *linkname)
Definition zic.c:1024
static void close_file(FILE *stream, char const *dir, char const *name)
Definition zic.c:545
static bool itssymlink(char const *name)
Definition zic.c:1159
static const char * directory
Definition zic.c:658

References _, close_file(), directory, ENOTSUP, EXIT_FAILURE, fb(), fprintf, free, hardlinkerr(), itsdir(), itssymlink(), mkdirs(), progname, relname, strerror, symlink, and warning().

Referenced by main().

◆ eat()

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

Definition at line 500 of file zic.c.

501{
502 eats(name, num, NULL, -1);
503}
static void eats(char const *name, lineno_t num, char const *rname, lineno_t rnum)
Definition zic.c:491

References eats(), fb(), and name.

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

◆ eats()

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

Definition at line 491 of file zic.c.

492{
493 filename = name;
494 linenum = num;
496 rlinenum = rnum;
497}
static const char * rfilename
Definition zic.c:198
static const char * filename
Definition zic.c:185
static lineno_t rlinenum
Definition zic.c:199
static lineno_t linenum
Definition zic.c:190

References fb(), filename, linenum, name, rfilename, and rlinenum.

Referenced by eat(), and outzone().

◆ ecpyalloc()

static char * ecpyalloc ( char const str)
static

Definition at line 464 of file zic.c.

465{
466 return memcheck(strdup(str));
467}
const char * str
static void * memcheck(void *ptr)
Definition zic.c:444

References fb(), memcheck(), and str.

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

◆ emalloc()

static void * emalloc ( size_t  size)
static

Definition at line 452 of file zic.c.

453{
454 return memcheck(malloc(size));
455}
#define malloc(a)

References malloc, and memcheck().

Referenced by getfields(), itsdir(), outzone(), relname(), and writezone().

◆ erealloc()

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

Definition at line 458 of file zic.c.

459{
460 return memcheck(realloc(ptr, size));
461}
#define realloc(a, b)

References memcheck(), and realloc.

Referenced by growalloc().

◆ error()

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

Definition at line 522 of file zic.c.

523{
525
526 va_start(args, string);
527 verror(string, args);
528 va_end(args);
529 errors = true;
530}
static void verror(const char *const string, va_list args) pg_attribute_printf(1
Definition zic.c:506

References errors, fb(), and verror().

◆ getfields()

static char ** getfields ( char cp)
static

Definition at line 3722 of file zic.c.

3723{
3724 char *dp;
3725 char **array;
3726 int nsubs;
3727
3728 if (cp == NULL)
3729 return NULL;
3730 array = emalloc(size_product(strlen(cp) + 1, sizeof *array));
3731 nsubs = 0;
3732 for (;;)
3733 {
3734 while (is_space(*cp))
3735 ++cp;
3736 if (*cp == '\0' || *cp == '#')
3737 break;
3738 array[nsubs++] = dp = cp;
3739 do
3740 {
3741 if ((*dp = *cp++) != '"')
3742 ++dp;
3743 else
3744 while ((*dp = *cp++) != '"')
3745 if (*dp != '\0')
3746 ++dp;
3747 else
3748 {
3749 error(_("Odd number of quotation marks"));
3751 }
3752 } while (*cp && *cp != '#' && !is_space(*cp));
3753 if (is_space(*cp))
3754 ++cp;
3755 *dp = '\0';
3756 }
3757 array[nsubs] = NULL;
3758 return array;
3759}
static bool is_space(char a)
Definition zic.c:3471
static size_t size_product(size_t nitems, size_t itemsize)
Definition zic.c:425
static void * emalloc(size_t size)
Definition zic.c:452

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

Referenced by infile().

◆ gethms()

static zic_t gethms ( const char string,
const char errstring 
)
static

Definition at line 1380 of file zic.c.

1381{
1382 zic_t hh;
1383 int sign,
1384 mm = 0,
1385 ss = 0;
1386 char hhx,
1387 mmx,
1388 ssx,
1389 xr = '0',
1390 xs;
1391 int tenths = 0;
1392 bool ok = true;
1393
1394 if (string == NULL || *string == '\0')
1395 return 0;
1396 if (*string == '-')
1397 {
1398 sign = -1;
1399 ++string;
1400 }
1401 else
1402 sign = 1;
1403 switch (sscanf(string,
1404 "%" SCNdZIC "%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
1405 &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs))
1406 {
1407 default:
1408 ok = false;
1409 break;
1410 case 8:
1411 ok = '0' <= xr && xr <= '9';
1413 case 7:
1414 ok &= ssx == '.';
1415 if (ok && noise)
1416 warning(_("fractional seconds rejected by"
1417 " pre-2018 versions of zic"));
1419 case 5:
1420 ok &= mmx == ':';
1422 case 3:
1423 ok &= hhx == ':';
1425 case 1:
1426 break;
1427 }
1428 if (!ok)
1429 {
1430 error("%s", errstring);
1431 return 0;
1432 }
1433 if (hh < 0 ||
1436 {
1437 error("%s", errstring);
1438 return 0;
1439 }
1440 if (ZIC_MAX / SECSPERHOUR < hh)
1441 {
1442 error(_("time overflow"));
1443 return 0;
1444 }
1445 ss += 5 + ((ss ^ 1) & (xr == '0')) <= tenths; /* Round to even. */
1446 if (noise && (hh > HOURSPERDAY ||
1447 (hh == HOURSPERDAY && (mm != 0 || ss != 0))))
1448 warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
1449 return oadd(sign * hh * SECSPERHOUR,
1450 sign * (mm * SECSPERMIN + ss));
1451}
#define pg_fallthrough
Definition c.h:161
char string[11]
#define SECSPERHOUR
Definition private.h:99
#define HOURSPERDAY
Definition private.h:95
#define SCNdZIC
Definition zic.c:29
#define ZIC_MAX
Definition zic.c:27

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

Referenced by getleapdatetime(), getsave(), inzsub(), and rulesub().

◆ getleapdatetime()

static zic_t getleapdatetime ( char **  fields,
int  nfields,
bool  expire_line 
)
static

Definition at line 1677 of file zic.c.

1678{
1679 const char *cp;
1680 const struct lookup *lp;
1681 zic_t i,
1682 j;
1683 zic_t year;
1684 int month,
1685 day;
1686 zic_t dayoff,
1687 tod;
1688 zic_t t;
1689 char xs;
1690
1691 dayoff = 0;
1692 cp = fields[LP_YEAR];
1693 if (sscanf(cp, "%" SCNdZIC "%c", &year, &xs) != 1)
1694 {
1695 /*
1696 * Leapin' Lizards!
1697 */
1698 error(_("invalid leaping year"));
1699 return -1;
1700 }
1701 if (!expire_line)
1702 {
1703 if (!leapseen || leapmaxyear < year)
1704 leapmaxyear = year;
1705 if (!leapseen || leapminyear > year)
1706 leapminyear = year;
1707 leapseen = true;
1708 }
1709 j = EPOCH_YEAR;
1710 while (j != year)
1711 {
1712 if (year > j)
1713 {
1714 i = len_years[isleap(j)];
1715 ++j;
1716 }
1717 else
1718 {
1719 --j;
1720 i = -len_years[isleap(j)];
1721 }
1722 dayoff = oadd(dayoff, i);
1723 }
1724 if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL)
1725 {
1726 error(_("invalid month name"));
1727 return -1;
1728 }
1729 month = lp->l_value;
1730 j = TM_JANUARY;
1731 while (j != month)
1732 {
1733 i = len_months[isleap(year)][j];
1734 dayoff = oadd(dayoff, i);
1735 ++j;
1736 }
1737 cp = fields[LP_DAY];
1738 if (sscanf(cp, "%d%c", &day, &xs) != 1 ||
1739 day <= 0 || day > len_months[isleap(year)][month])
1740 {
1741 error(_("invalid day of month"));
1742 return -1;
1743 }
1744 dayoff = oadd(dayoff, day - 1);
1745 if (dayoff < min_time / SECSPERDAY)
1746 {
1747 error(_("time too small"));
1748 return -1;
1749 }
1750 if (dayoff > max_time / SECSPERDAY)
1751 {
1752 error(_("time too large"));
1753 return -1;
1754 }
1755 t = dayoff * SECSPERDAY;
1756 tod = gethms(fields[LP_TIME], _("invalid time of day"));
1757 t = tadd(t, tod);
1758 if (t < 0)
1759 error(_("leap second precedes Epoch"));
1760 return t;
1761}
#define isleap(y)
Definition datetime.h:273
#define TM_JANUARY
Definition private.h:111
#define EPOCH_YEAR
Definition private.h:126
static zic_t gethms(const char *string, const char *errstring)
Definition zic.c:1380
#define LP_MONTH
Definition zic.c:272
static struct lookup const mon_names[]
Definition zic.c:331
static bool leapseen
Definition zic.c:187
#define LP_TIME
Definition zic.c:274
static zic_t leapminyear
Definition zic.c:188
#define LP_YEAR
Definition zic.c:271
static const int len_months[2][MONSPERYEAR]
Definition zic.c:388
static zic_t leapmaxyear
Definition zic.c:189
static struct lookup const * byword(const char *word, const struct lookup *table)
Definition zic.c:3656
static zic_t const max_time
Definition zic.c:606
static zic_t const min_time
Definition zic.c:605
#define LP_DAY
Definition zic.c:273
static const int len_years[2]
Definition zic.c:393

References _, byword(), EPOCH_YEAR, error(), fb(), gethms(), i, isleap, j, leapmaxyear, leapminyear, leapseen, len_months, len_years, LP_DAY, LP_MONTH, LP_TIME, LP_YEAR, max_time, min_time, mon_names, oadd(), SCNdZIC, SECSPERDAY, tadd(), and TM_JANUARY.

Referenced by inexpires(), and inleap().

◆ getsave()

static zic_t getsave ( char field,
bool isdst 
)
static

Definition at line 1454 of file zic.c.

1455{
1456 int dst = -1;
1457 zic_t save;
1458 size_t fieldlen = strlen(field);
1459
1460 if (fieldlen != 0)
1461 {
1462 char *ep = field + fieldlen - 1;
1463
1464 switch (*ep)
1465 {
1466 case 'd':
1467 dst = 1;
1468 *ep = '\0';
1469 break;
1470 case 's':
1471 dst = 0;
1472 *ep = '\0';
1473 break;
1474 }
1475 }
1476 save = gethms(field, _("invalid saved time"));
1477 *isdst = dst < 0 ? save != 0 : dst;
1478 return save;
1479}

References _, fb(), and gethms().

Referenced by associate(), and inrule().

◆ growalloc()

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

Definition at line 470 of file zic.c.

471{
472 if (nitems < *nitems_alloc)
473 return ptr;
474 else
475 {
478
479 if ((amax - 1) / 3 * 2 < *nitems_alloc)
480 memory_exhausted(_("integer overflow"));
481 *nitems_alloc += (*nitems_alloc >> 1) + 1;
483 }
484}
#define nitems(x)
Definition indent.h:31
static ptrdiff_t const PTRDIFF_MAX
Definition zic.c:49
static void * erealloc(void *ptr, size_t size)
Definition zic.c:458

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

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

◆ hardlinkerr()

static int hardlinkerr ( char const target,
char const linkname 
)
static

Definition at line 1024 of file zic.c.

1025{
1027
1028 return r == 0 ? 0 : errno;
1029}
#define linkat(targetdir, target, linknamedir, linkname, flag)
Definition zic.c:123

References fb(), and linkat.

Referenced by dolink().

◆ inexpires()

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

Definition at line 1796 of file zic.c.

1797{
1798 if (nfields != EXPIRES_FIELDS)
1799 error(_("wrong number of fields on Expires line"));
1800 else if (0 <= leapexpires)
1801 error(_("multiple Expires lines"));
1802 else
1803 leapexpires = getleapdatetime(fields, nfields, true);
1804}
static zic_t getleapdatetime(char **fields, int nfields, bool expire_line)
Definition zic.c:1677
#define EXPIRES_FIELDS
Definition zic.c:280

References _, error(), EXPIRES_FIELDS, getleapdatetime(), and leapexpires.

Referenced by infile().

◆ infile()

static void infile ( const char name)
static

Definition at line 1271 of file zic.c.

1272{
1273 FILE *fp;
1274 char **fields;
1275 char *cp;
1276 const struct lookup *lp;
1277 int nfields;
1278 bool wantcont;
1279 lineno_t num;
1280 char buf[BUFSIZ];
1281
1282 if (strcmp(name, "-") == 0)
1283 {
1284 name = _("standard input");
1285 fp = stdin;
1286 }
1287 else if ((fp = fopen(name, "r")) == NULL)
1288 {
1289 const char *e = strerror(errno);
1290
1291 fprintf(stderr, _("%s: Cannot open %s: %s\n"),
1292 progname, name, e);
1294 }
1295 wantcont = false;
1296 for (num = 1;; ++num)
1297 {
1298 eat(name, num);
1299 if (fgets(buf, sizeof buf, fp) != buf)
1300 break;
1301 cp = strchr(buf, '\n');
1302 if (cp == NULL)
1303 {
1304 error(_("line too long"));
1306 }
1307 *cp = '\0';
1308 fields = getfields(buf);
1309 nfields = 0;
1310 while (fields[nfields] != NULL)
1311 {
1312 static char nada;
1313
1314 if (strcmp(fields[nfields], "-") == 0)
1315 fields[nfields] = &nada;
1316 ++nfields;
1317 }
1318 if (nfields == 0)
1319 {
1320 if (name == leapsec && *buf == '#')
1321 sscanf(buf, "#expires %" SCNdZIC, &comment_leapexpires);
1322 }
1323 else if (wantcont)
1324 {
1325 wantcont = inzcont(fields, nfields);
1326 }
1327 else
1328 {
1329 struct lookup const *line_codes
1331
1332 lp = byword(fields[0], line_codes);
1333 if (lp == NULL)
1334 error(_("input line of unknown type"));
1335 else
1336 switch (lp->l_value)
1337 {
1338 case LC_RULE:
1339 inrule(fields, nfields);
1340 wantcont = false;
1341 break;
1342 case LC_ZONE:
1343 wantcont = inzone(fields, nfields);
1344 break;
1345 case LC_LINK:
1346 inlink(fields, nfields);
1347 wantcont = false;
1348 break;
1349 case LC_LEAP:
1350 inleap(fields, nfields);
1351 wantcont = false;
1352 break;
1353 case LC_EXPIRES:
1354 inexpires(fields, nfields);
1355 wantcont = false;
1356 break;
1357 default: /* "cannot happen" */
1359 _("%s: panic: Invalid l_value %d\n"),
1360 progname, lp->l_value);
1362 }
1363 }
1364 free(fields);
1365 }
1366 close_file(fp, NULL, filename);
1367 if (wantcont)
1368 error(_("expected continuation line not found"));
1369}
static const char * leapsec
Definition zic.c:659
#define LC_EXPIRES
Definition zic.c:213
#define LC_LINK
Definition zic.c:211
static void inleap(char **fields, int nfields)
Definition zic.c:1764
static bool inzone(char **fields, int nfields)
Definition zic.c:1529
#define LC_RULE
Definition zic.c:209
static bool inzcont(char **fields, int nfields)
Definition zic.c:1567
static struct lookup const zi_line_codes[]
Definition zic.c:319
static void inexpires(char **fields, int nfields)
Definition zic.c:1796
static void inrule(char **fields, int nfields)
Definition zic.c:1482
intmax_t lineno_t
Definition zic.c:62
#define LC_LEAP
Definition zic.c:212
#define LC_ZONE
Definition zic.c:210
static char ** getfields(char *cp)
Definition zic.c:3722
static struct lookup const leap_line_codes[]
Definition zic.c:325
static void inlink(char **fields, int nfields)
Definition zic.c:1807

References _, buf, byword(), close_file(), comment_leapexpires, eat(), error(), EXIT_FAILURE, fb(), filename, fprintf, free, getfields(), inexpires(), inleap(), inlink(), inrule(), inzcont(), inzone(), LC_EXPIRES, LC_LEAP, LC_LINK, LC_RULE, LC_ZONE, leap_line_codes, leapsec, name, progname, SCNdZIC, strerror, and zi_line_codes.

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

◆ inleap()

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

Definition at line 1764 of file zic.c.

1765{
1766 if (nfields != LEAP_FIELDS)
1767 error(_("wrong number of fields on Leap line"));
1768 else
1769 {
1770 zic_t t = getleapdatetime(fields, nfields, false);
1771
1772 if (0 <= t)
1773 {
1774 struct lookup const *lp = byword(fields[LP_ROLL], leap_types);
1775
1776 if (!lp)
1777 error(_("invalid Rolling/Stationary field on Leap line"));
1778 else
1779 {
1780 int correction = 0;
1781
1782 if (!fields[LP_CORR][0]) /* infile() turns "-" into "". */
1783 correction = -1;
1784 else if (strcmp(fields[LP_CORR], "+") == 0)
1785 correction = 1;
1786 else
1787 error(_("invalid CORRECTION field on Leap line"));
1788 if (correction)
1789 leapadd(t, correction, lp->l_value);
1790 }
1791 }
1792 }
1793}
static struct lookup const leap_types[]
Definition zic.c:382
#define LP_CORR
Definition zic.c:275
#define LEAP_FIELDS
Definition zic.c:277
#define LP_ROLL
Definition zic.c:276
static void leapadd(zic_t t, int correction, int rolling)
Definition zic.c:3406

References _, byword(), error(), fb(), getleapdatetime(), LEAP_FIELDS, leap_types, leapadd(), LP_CORR, and LP_ROLL.

Referenced by infile().

◆ inlink()

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

Definition at line 1807 of file zic.c.

1808{
1809 struct link l;
1810
1811 if (nfields != LINK_FIELDS)
1812 {
1813 error(_("wrong number of fields on Link line"));
1814 return;
1815 }
1816 if (*fields[LF_TARGET] == '\0')
1817 {
1818 error(_("blank TARGET field on Link line"));
1819 return;
1820 }
1821 if (!namecheck(fields[LF_LINKNAME]))
1822 return;
1823 l.l_filename = filename;
1824 l.l_linenum = linenum;
1825 l.l_target = ecpyalloc(fields[LF_TARGET]);
1826 l.l_linkname = ecpyalloc(fields[LF_LINKNAME]);
1828 links[nlinks++] = l;
1829}
static ptrdiff_t nlinks
Definition zic.c:307
#define LINK_FIELDS
Definition zic.c:265
#define LF_LINKNAME
Definition zic.c:264
static ptrdiff_t nlinks_alloc
Definition zic.c:308
#define LF_TARGET
Definition zic.c:263
static char * ecpyalloc(char const *str)
Definition zic.c:464
static bool namecheck(const char *name)
Definition zic.c:929
static struct link * links
Definition zic.c:306

References _, ecpyalloc(), error(), filename, growalloc(), link::l_filename, link::l_linenum, link::l_linkname, link::l_target, LF_LINKNAME, LF_TARGET, linenum, LINK_FIELDS, links, namecheck(), nlinks, and nlinks_alloc.

Referenced by infile().

◆ inrule()

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

Definition at line 1482 of file zic.c.

1483{
1484 static struct rule r;
1485
1486 if (nfields != RULE_FIELDS)
1487 {
1488 error(_("wrong number of fields on Rule line"));
1489 return;
1490 }
1491 switch (*fields[RF_NAME])
1492 {
1493 case '\0':
1494 case ' ':
1495 case '\f':
1496 case '\n':
1497 case '\r':
1498 case '\t':
1499 case '\v':
1500 case '+':
1501 case '-':
1502 case '0':
1503 case '1':
1504 case '2':
1505 case '3':
1506 case '4':
1507 case '5':
1508 case '6':
1509 case '7':
1510 case '8':
1511 case '9':
1512 error(_("Invalid rule name \"%s\""), fields[RF_NAME]);
1513 return;
1514 }
1515 r.r_filename = filename;
1516 r.r_linenum = linenum;
1517 r.r_save = getsave(fields[RF_SAVE], &r.r_isdst);
1518 rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
1519 fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
1520 r.r_name = ecpyalloc(fields[RF_NAME]);
1521 r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
1522 if (max_abbrvar_len < strlen(r.r_abbrvar))
1523 max_abbrvar_len = strlen(r.r_abbrvar);
1525 rules[nrules++] = r;
1526}
#define RF_LOYEAR
Definition zic.c:249
#define RF_SAVE
Definition zic.c:255
#define RF_ABBRVAR
Definition zic.c:256
static int max_abbrvar_len
Definition zic.c:191
#define RF_HIYEAR
Definition zic.c:250
#define RF_TOD
Definition zic.c:254
#define RF_COMMAND
Definition zic.c:251
#define RF_NAME
Definition zic.c:248
static ptrdiff_t nrules_alloc
Definition zic.c:292
#define RF_DAY
Definition zic.c:253
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:1832
#define RULE_FIELDS
Definition zic.c:257
#define RF_MONTH
Definition zic.c:252

References _, ecpyalloc(), error(), fb(), filename, getsave(), growalloc(), linenum, max_abbrvar_len, nrules, nrules_alloc, rule::r_abbrvar, rule::r_filename, rule::r_isdst, rule::r_linenum, rule::r_name, rule::r_save, RF_ABBRVAR, RF_COMMAND, RF_DAY, RF_HIYEAR, RF_LOYEAR, RF_MONTH, RF_NAME, RF_SAVE, RF_TOD, RULE_FIELDS, rules, and rulesub().

Referenced by infile().

◆ inzcont()

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

Definition at line 1567 of file zic.c.

1568{
1570 {
1571 error(_("wrong number of fields on Zone continuation line"));
1572 return false;
1573 }
1574 return inzsub(fields, nfields, true);
1575}
#define ZONEC_MAXFIELDS
Definition zic.c:242
static bool inzsub(char **fields, int nfields, bool iscont)
Definition zic.c:1578

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

Referenced by infile().

◆ inzone()

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

Definition at line 1529 of file zic.c.

1530{
1531 ptrdiff_t i;
1532
1534 {
1535 error(_("wrong number of fields on Zone line"));
1536 return false;
1537 }
1538 if (lcltime != NULL && strcmp(fields[ZF_NAME], tzdefault) == 0)
1539 {
1540 error(
1541 _("\"Zone %s\" line and -l option are mutually exclusive"),
1542 tzdefault);
1543 return false;
1544 }
1545 if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL)
1546 {
1547 error(
1548 _("\"Zone %s\" line and -p option are mutually exclusive"),
1549 TZDEFRULES);
1550 return false;
1551 }
1552 for (i = 0; i < nzones; ++i)
1553 if (zones[i].z_name != NULL &&
1554 strcmp(zones[i].z_name, fields[ZF_NAME]) == 0)
1555 {
1556 error(_("duplicate zone name %s"
1557 " (file \"%s\", line %" PRIdMAX ")"),
1558 fields[ZF_NAME],
1559 zones[i].z_filename,
1560 zones[i].z_linenum);
1561 return false;
1562 }
1563 return inzsub(fields, nfields, false);
1564}
#define TZDEFRULES
Definition tzfile.h:28
#define ZONE_MAXFIELDS
Definition zic.c:228
static const char * lcltime
Definition zic.c:657
static const char * psxrules
Definition zic.c:656
#define ZF_NAME
Definition zic.c:219
static const char * tzdefault
Definition zic.c:660

References _, error(), fb(), i, inzsub(), lcltime, nzones, psxrules, tzdefault, TZDEFRULES, ZF_NAME, ZONE_MAXFIELDS, and zones.

Referenced by infile().

◆ inzsub()

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

Definition at line 1578 of file zic.c.

1579{
1580 char *cp;
1581 char *cp1;
1582 static struct zone z;
1583 int i_stdoff,
1584 i_rule,
1585 i_format;
1586 int i_untilyear,
1588 int i_untilday,
1590 bool hasuntil;
1591
1592 if (iscont)
1593 {
1595 i_rule = ZFC_RULE;
1601 z.z_name = NULL;
1602 }
1603 else if (!namecheck(fields[ZF_NAME]))
1604 return false;
1605 else
1606 {
1608 i_rule = ZF_RULE;
1614 z.z_name = ecpyalloc(fields[ZF_NAME]);
1615 }
1616 z.z_filename = filename;
1617 z.z_linenum = linenum;
1618 z.z_stdoff = gethms(fields[i_stdoff], _("invalid UT offset"));
1619 if ((cp = strchr(fields[i_format], '%')) != NULL)
1620 {
1621 if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
1622 || strchr(fields[i_format], '/'))
1623 {
1624 error(_("invalid abbreviation format"));
1625 return false;
1626 }
1627 }
1628 z.z_rule = ecpyalloc(fields[i_rule]);
1629 z.z_format = cp1 = ecpyalloc(fields[i_format]);
1630 z.z_format_specifier = cp ? *cp : '\0';
1631 if (z.z_format_specifier == 'z')
1632 {
1633 if (noise)
1634 warning(_("format '%s' not handled by pre-2015 versions of zic"),
1635 z.z_format);
1636 cp1[cp - fields[i_format]] = 's';
1637 }
1638 if (max_format_len < strlen(z.z_format))
1639 max_format_len = strlen(z.z_format);
1640 hasuntil = nfields > i_untilyear;
1641 if (hasuntil)
1642 {
1643 z.z_untilrule.r_filename = filename;
1644 z.z_untilrule.r_linenum = linenum;
1645 rulesub(&z.z_untilrule,
1646 fields[i_untilyear],
1647 "only",
1648 "",
1649 (nfields > i_untilmonth) ?
1650 fields[i_untilmonth] : "Jan",
1651 (nfields > i_untilday) ? fields[i_untilday] : "1",
1652 (nfields > i_untiltime) ? fields[i_untiltime] : "0");
1653 z.z_untiltime = rpytime(&z.z_untilrule,
1654 z.z_untilrule.r_loyear);
1655 if (iscont && nzones > 0 &&
1656 z.z_untiltime > min_time &&
1657 z.z_untiltime < max_time &&
1660 zones[nzones - 1].z_untiltime >= z.z_untiltime)
1661 {
1662 error(_("Zone continuation line end time is not after end time of previous line"));
1663 return false;
1664 }
1665 }
1667 zones[nzones++] = z;
1668
1669 /*
1670 * If there was an UNTIL field on this line, there's more information
1671 * about the zone on the next line.
1672 */
1673 return hasuntil;
1674}
zic_t z_untiltime
Definition zic.c:118
const char * z_name
Definition zic.c:105
#define ZF_FORMAT
Definition zic.c:222
#define ZFC_TILDAY
Definition zic.c:239
#define ZFC_TILYEAR
Definition zic.c:237
#define ZF_RULE
Definition zic.c:221
#define ZFC_TILMONTH
Definition zic.c:238
#define ZFC_STDOFF
Definition zic.c:234
#define ZF_TILYEAR
Definition zic.c:223
#define ZF_TILDAY
Definition zic.c:225
#define ZFC_RULE
Definition zic.c:235
static int max_format_len
Definition zic.c:192
static ptrdiff_t nzones_alloc
Definition zic.c:296
#define ZFC_TILTIME
Definition zic.c:240
static zic_t rpytime(const struct rule *rp, zic_t wantedy)
Definition zic.c:3806
#define ZF_STDOFF
Definition zic.c:220
#define ZF_TILMONTH
Definition zic.c:224
#define ZF_TILTIME
Definition zic.c:226
#define ZFC_FORMAT
Definition zic.c:236

References _, ecpyalloc(), error(), fb(), filename, gethms(), growalloc(), linenum, max_format_len, max_time, min_time, namecheck(), noise, nzones, nzones_alloc, rule::r_filename, rule::r_linenum, rule::r_loyear, rpytime(), rulesub(), warning(), zone::z_filename, zone::z_format, zone::z_format_specifier, zone::z_linenum, zone::z_name, zone::z_rule, zone::z_stdoff, zone::z_untilrule, zone::z_untiltime, ZF_FORMAT, ZF_NAME, ZF_RULE, ZF_STDOFF, ZF_TILDAY, ZF_TILMONTH, ZF_TILTIME, ZF_TILYEAR, ZFC_FORMAT, ZFC_RULE, ZFC_STDOFF, ZFC_TILDAY, ZFC_TILMONTH, ZFC_TILTIME, ZFC_TILYEAR, and zones.

Referenced by inzcont(), and inzone().

◆ is_alpha()

static bool is_alpha ( char  a)
static

Definition at line 3489 of file zic.c.

3490{
3491 switch (a)
3492 {
3493 default:
3494 return false;
3495 case 'A':
3496 case 'B':
3497 case 'C':
3498 case 'D':
3499 case 'E':
3500 case 'F':
3501 case 'G':
3502 case 'H':
3503 case 'I':
3504 case 'J':
3505 case 'K':
3506 case 'L':
3507 case 'M':
3508 case 'N':
3509 case 'O':
3510 case 'P':
3511 case 'Q':
3512 case 'R':
3513 case 'S':
3514 case 'T':
3515 case 'U':
3516 case 'V':
3517 case 'W':
3518 case 'X':
3519 case 'Y':
3520 case 'Z':
3521 case 'a':
3522 case 'b':
3523 case 'c':
3524 case 'd':
3525 case 'e':
3526 case 'f':
3527 case 'g':
3528 case 'h':
3529 case 'i':
3530 case 'j':
3531 case 'k':
3532 case 'l':
3533 case 'm':
3534 case 'n':
3535 case 'o':
3536 case 'p':
3537 case 'q':
3538 case 'r':
3539 case 's':
3540 case 't':
3541 case 'u':
3542 case 'v':
3543 case 'w':
3544 case 'x':
3545 case 'y':
3546 case 'z':
3547 return true;
3548 }
3549}

References a.

Referenced by doabbr(), and newabbr().

◆ is_space()

static bool is_space ( char  a)
static

Definition at line 3471 of file zic.c.

3472{
3473 switch (a)
3474 {
3475 default:
3476 return false;
3477 case ' ':
3478 case '\f':
3479 case '\n':
3480 case '\r':
3481 case '\t':
3482 case '\v':
3483 return true;
3484 }
3485}

References a.

Referenced by getfields().

◆ itsabbr()

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

Definition at line 3628 of file zic.c.

3629{
3630 if (lowerit(*abbr) != lowerit(*word))
3631 return false;
3632 ++word;
3633 while (*++abbr != '\0')
3634 do
3635 {
3636 if (*word == '\0')
3637 return false;
3638 } while (lowerit(*word++) != lowerit(*abbr));
3639 return true;
3640}

References fb(), lowerit(), and word().

Referenced by byword().

◆ itsdir()

static bool itsdir ( char const name)
static

Definition at line 1134 of file zic.c.

1135{
1136 struct stat st;
1137 int res = stat(name, &st);
1138#ifdef S_ISDIR
1139 if (res == 0)
1140 return S_ISDIR(st.st_mode) != 0;
1141#endif
1142 if (res == 0 || errno == EOVERFLOW)
1143 {
1144 size_t n = strlen(name);
1145 char *nameslashdot = emalloc(n + 3);
1146 bool dir;
1147
1149 strcpy(&nameslashdot[n], &"/."[!(n && name[n - 1] != '/')]);
1150 dir = stat(nameslashdot, &st) == 0 || errno == EOVERFLOW;
1152 return dir;
1153 }
1154 return false;
1155}
#define EOVERFLOW
Definition private.h:41
#define stat
Definition win32_port.h:74
#define S_ISDIR(m)
Definition win32_port.h:315

References emalloc(), EOVERFLOW, fb(), free, memcpy(), name, S_ISDIR, stat::st_mode, and stat.

Referenced by dolink(), and mkdirs().

◆ itssymlink()

static bool itssymlink ( char const name)
static

Definition at line 1159 of file zic.c.

1160{
1161#ifdef HAVE_SYMLINK
1162 char c;
1163
1164 return 0 <= readlink(name, &c, 1);
1165#else
1166 return false;
1167#endif
1168}
#define readlink(path, buf, size)
Definition win32_port.h:226

References name, and readlink.

Referenced by dolink().

◆ leapadd()

static void leapadd ( zic_t  t,
int  correction,
int  rolling 
)
static

Definition at line 3406 of file zic.c.

3407{
3408 int i;
3409
3410 if (TZ_MAX_LEAPS <= leapcnt)
3411 {
3412 error(_("too many leap seconds"));
3414 }
3415 for (i = 0; i < leapcnt; ++i)
3416 if (t <= trans[i])
3417 break;
3418 memmove(&trans[i + 1], &trans[i], (leapcnt - i) * sizeof *trans);
3419 memmove(&corr[i + 1], &corr[i], (leapcnt - i) * sizeof *corr);
3420 memmove(&roll[i + 1], &roll[i], (leapcnt - i) * sizeof *roll);
3421 trans[i] = t;
3422 corr[i] = correction;
3423 roll[i] = rolling;
3424 ++leapcnt;
3425}
#define TZ_MAX_LEAPS
Definition tzfile.h:108
static char roll[TZ_MAX_LEAPS]
Definition zic.c:411

References _, corr, error(), EXIT_FAILURE, fb(), i, leapcnt, roll, trans, and TZ_MAX_LEAPS.

Referenced by inleap().

◆ limitrange()

static struct timerange limitrange ( struct timerange  r,
zic_t  lo,
zic_t  hi,
zic_t const ats,
unsigned char const types 
)
static

Definition at line 2057 of file zic.c.

2059{
2060 while (0 < r.count && ats[r.base] < lo)
2061 {
2062 r.defaulttype = types[r.base];
2063 r.count--;
2064 r.base++;
2065 }
2066 while (0 < r.leapcount && trans[r.leapbase] < lo)
2067 {
2068 r.leapcount--;
2069 r.leapbase++;
2070 }
2071
2072 if (hi < ZIC_MAX)
2073 {
2074 while (0 < r.count && hi + 1 < ats[r.base + r.count - 1])
2075 r.count--;
2076 while (0 < r.leapcount && hi + 1 < trans[r.leapbase + r.leapcount - 1])
2077 r.leapcount--;
2078 }
2079
2080 return r;
2081}
struct typedefs * types
Definition ecpg.c:30
int leapbase
Definition zic.c:2052
ptrdiff_t count
Definition zic.c:2051
ptrdiff_t base
Definition zic.c:2050
int leapcount
Definition zic.c:2053
int defaulttype
Definition zic.c:2049

References timerange::defaulttype, trans, types, and ZIC_MAX.

Referenced by writezone().

◆ link()

int link ( const char target,
const char linkname 
)
extern

Definition at line 18 of file win32link.c.

19{
20 /*
21 * CreateHardLinkA returns zero for failure
22 * https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createhardlinka
23 */
24 if (CreateHardLinkA(dst, src, NULL) == 0)
25 {
27 return -1;
28 }
29 else
30 return 0;
31}
void _dosmaperr(unsigned long)
Definition win32error.c:177

References _dosmaperr(), and fb().

◆ lowerit()

static char lowerit ( char  a)
static

Definition at line 3556 of file zic.c.

3557{
3558 switch (a)
3559 {
3560 default:
3561 return a;
3562 case 'A':
3563 return 'a';
3564 case 'B':
3565 return 'b';
3566 case 'C':
3567 return 'c';
3568 case 'D':
3569 return 'd';
3570 case 'E':
3571 return 'e';
3572 case 'F':
3573 return 'f';
3574 case 'G':
3575 return 'g';
3576 case 'H':
3577 return 'h';
3578 case 'I':
3579 return 'i';
3580 case 'J':
3581 return 'j';
3582 case 'K':
3583 return 'k';
3584 case 'L':
3585 return 'l';
3586 case 'M':
3587 return 'm';
3588 case 'N':
3589 return 'n';
3590 case 'O':
3591 return 'o';
3592 case 'P':
3593 return 'p';
3594 case 'Q':
3595 return 'q';
3596 case 'R':
3597 return 'r';
3598 case 'S':
3599 return 's';
3600 case 'T':
3601 return 't';
3602 case 'U':
3603 return 'u';
3604 case 'V':
3605 return 'v';
3606 case 'W':
3607 return 'w';
3608 case 'X':
3609 return 'x';
3610 case 'Y':
3611 return 'y';
3612 case 'Z':
3613 return 'z';
3614 }
3615}

References a.

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

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 680 of file zic.c.

681{
682 int c,
683 k;
684 ptrdiff_t i,
685 j;
686 bool timerange_given = false;
687
688#ifndef WIN32
690#endif
691 progname = argv[0];
692 if (TYPE_BIT(zic_t) < 64)
693 {
694 fprintf(stderr, "%s: %s\n", progname,
695 _("wild compilation-time specification of zic_t"));
696 return EXIT_FAILURE;
697 }
698 for (k = 1; k < argc; k++)
699 if (strcmp(argv[k], "--version") == 0)
700 {
701 printf("zic %s\n", PG_VERSION);
702 close_file(stdout, NULL, NULL);
703 return EXIT_SUCCESS;
704 }
705 else if (strcmp(argv[k], "--help") == 0)
706 {
707 usage(stdout, EXIT_SUCCESS);
708 }
709 while ((c = getopt(argc, argv, "b:d:l:L:p:Pr:st:vy:")) != EOF && c != -1)
710 switch (c)
711 {
712 default:
714 case 'b':
715 if (strcmp(optarg, "slim") == 0)
716 {
717 if (0 < bloat)
718 error(_("incompatible -b options"));
719 bloat = -1;
720 }
721 else if (strcmp(optarg, "fat") == 0)
722 {
723 if (bloat < 0)
724 error(_("incompatible -b options"));
725 bloat = 1;
726 }
727 else
728 error(_("invalid option: -b '%s'"), optarg);
729 break;
730 case 'd':
731 if (directory == NULL)
733 else
734 {
736 _("%s: More than one -d option specified\n"),
737 progname);
738 return EXIT_FAILURE;
739 }
740 break;
741 case 'l':
742 if (lcltime == NULL)
744 else
745 {
747 _("%s: More than one -l option specified\n"),
748 progname);
749 return EXIT_FAILURE;
750 }
751 break;
752 case 'p':
753 if (psxrules == NULL)
755 else
756 {
758 _("%s: More than one -p option specified\n"),
759 progname);
760 return EXIT_FAILURE;
761 }
762 break;
763 case 't':
764 if (tzdefault != NULL)
765 {
767 _("%s: More than one -t option"
768 " specified\n"),
769 progname);
770 return EXIT_FAILURE;
771 }
773 break;
774 case 'y':
775 warning(_("-y ignored"));
776 break;
777 case 'L':
778 if (leapsec == NULL)
780 else
781 {
783 _("%s: More than one -L option specified\n"),
784 progname);
785 return EXIT_FAILURE;
786 }
787 break;
788 case 'v':
789 noise = true;
790 break;
791 case 'P':
792 print_abbrevs = true;
793 print_cutoff = time(NULL);
794 break;
795 case 'r':
796 if (timerange_given)
797 {
799 _("%s: More than one -r option specified\n"),
800 progname);
801 return EXIT_FAILURE;
802 }
804 {
806 _("%s: invalid time range: %s\n"),
808 return EXIT_FAILURE;
809 }
810 timerange_given = true;
811 break;
812 case 's':
813 warning(_("-s ignored"));
814 break;
815 }
816 if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
817 usage(stderr, EXIT_FAILURE); /* usage message by request */
818 if (bloat == 0)
819 {
820 static char const bloat_default[] = ZIC_BLOAT_DEFAULT;
821
822 if (strcmp(bloat_default, "slim") == 0)
823 bloat = -1;
824 else if (strcmp(bloat_default, "fat") == 0)
825 bloat = 1;
826 else
827 abort(); /* Configuration error. */
828 }
829 if (directory == NULL)
830 directory = "data";
831 if (tzdefault == NULL)
833
834 if (optind < argc && leapsec != NULL)
835 {
837 adjleap();
838 }
839
840 for (k = optind; k < argc; k++)
841 infile(argv[k]);
842 if (errors)
843 return EXIT_FAILURE;
844 associate();
846 for (i = 0; i < nzones; i = j)
847 {
848 /*
849 * Find the next non-continuation zone entry.
850 */
851 for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
852 continue;
853 outzone(&zones[i], j - i);
854 }
855
856 /*
857 * Make links.
858 */
859 for (i = 0; i < nlinks; ++i)
860 {
861 eat(links[i].l_filename, links[i].l_linenum);
862 dolink(links[i].l_target, links[i].l_linkname, false);
863 if (noise)
864 for (j = 0; j < nlinks; ++j)
865 if (strcmp(links[i].l_linkname,
866 links[j].l_target) == 0)
867 warning(_("link to link"));
868 }
869 if (lcltime != NULL)
870 {
871 eat(_("command line"), 1);
872 dolink(lcltime, tzdefault, true);
873 }
874 if (psxrules != NULL)
875 {
876 eat(_("command line"), 1);
877 dolink(psxrules, TZDEFRULES, true);
878 }
879 if (warnings && (ferror(stderr) || fclose(stderr) != 0))
880 return EXIT_FAILURE;
882}
static void usage(void)
PGDLLIMPORT int optind
Definition getopt.c:47
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition getopt.c:67
PGDLLIMPORT char * optarg
Definition getopt.c:49
#define printf(...)
Definition port.h:267
#define TYPE_BIT(type)
Definition private.h:52
#define EXIT_SUCCESS
Definition settings.h:193
#define TZDEFAULT
Definition tzfile.h:27
#define S_IWOTH
Definition win32_port.h:306
#define S_IWGRP
Definition win32_port.h:294
#define ZIC_BLOAT_DEFAULT
Definition zic.c:676
static void change_directory(char const *dir)
Definition zic.c:582
static bool print_abbrevs
Definition zic.c:196
static zic_t print_cutoff
Definition zic.c:197
static int bloat
Definition zic.c:667
static void outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
Definition zic.c:2949
static void dolink(const char *target, const char *linkname, bool staysymlink)
Definition zic.c:1032
static bool timerange_option(char *timerange)
Definition zic.c:626
static bool warnings
Definition zic.c:184
static void infile(const char *name)
Definition zic.c:1271
static void adjleap(void)
Definition zic.c:3428
static void associate(void)
Definition zic.c:1186

References _, adjleap(), associate(), bloat, change_directory(), close_file(), directory, dolink(), eat(), error(), errors, EXIT_FAILURE, EXIT_SUCCESS, fb(), fprintf, getopt(), i, infile(), j, lcltime, leapsec, links, nlinks, noise, nzones, optarg, optind, outzone(), print_abbrevs, print_cutoff, printf, progname, psxrules, S_IWGRP, S_IWOTH, timerange_option(), TYPE_BIT, TZDEFAULT, tzdefault, TZDEFRULES, usage(), warning(), warnings, zone::z_name, ZIC_BLOAT_DEFAULT, and zones.

◆ memcheck()

static void * memcheck ( void ptr)
static

Definition at line 444 of file zic.c.

445{
446 if (ptr == NULL)
448 return ptr;
449}

References fb(), memory_exhausted(), and strerror.

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

◆ memory_exhausted()

static _Noreturn void memory_exhausted ( const char msg)
static

Definition at line 418 of file zic.c.

419{
420 fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, msg);
422}

References _, EXIT_FAILURE, fb(), fprintf, and progname.

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

◆ mkdirs()

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

Definition at line 3955 of file zic.c.

3956{
3957 char *name;
3958 char *cp;
3959
3960 cp = name = ecpyalloc(argname);
3961
3962 /*
3963 * On MS-Windows systems, do not worry about drive letters or backslashes,
3964 * as this should suffice in practice. Time zone names do not use drive
3965 * letters and backslashes. If the -d option of zic does not name an
3966 * already-existing directory, it can use slashes to separate the
3967 * already-existing ancestor prefix from the to-be-created subdirectories.
3968 */
3969
3970 /* Do not mkdir a root directory, as it must exist. */
3971 while (*cp == '/')
3972 cp++;
3973
3974 while (cp && ((cp = strchr(cp, '/')) || !ancestors))
3975 {
3976 if (cp)
3977 *cp = '\0';
3978
3979 /*
3980 * Try to create it. It's OK if creation fails because the directory
3981 * already exists, perhaps because some other process just created it.
3982 * For simplicity do not check first whether it already exists, as
3983 * that is checked anyway if the mkdir fails.
3984 */
3985 if (mkdir(name, MKDIR_UMASK) != 0)
3986 {
3987 /*
3988 * For speed, skip itsdir if errno == EEXIST. Since mkdirs is
3989 * called only after open fails with ENOENT on a subfile, EEXIST
3990 * implies itsdir here.
3991 */
3992 int err = errno;
3993
3994 if (err != EEXIST && !itsdir(name))
3995 {
3996 error(_("%s: Cannot create directory %s: %s"),
3999 }
4000 }
4001 if (cp)
4002 *cp++ = '/';
4003 }
4004 free(name);
4005}
void err(int eval, const char *fmt,...)
Definition err.c:43
#define mkdir(a, b)
Definition win32_port.h:80
#define MKDIR_UMASK
Definition zic.c:39

References _, ecpyalloc(), err(), error(), EXIT_FAILURE, fb(), free, itsdir(), mkdir, MKDIR_UMASK, name, progname, and strerror.

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

◆ namecheck()

static bool namecheck ( const char name)
static

Definition at line 929 of file zic.c.

930{
931 char const *cp;
932
933 /* Benign characters in a portable file name. */
934 static char const benign[] =
935 "-/_"
936 "abcdefghijklmnopqrstuvwxyz"
937 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
938
939 /*
940 * Non-control chars in the POSIX portable character set, excluding the
941 * benign characters.
942 */
943 static char const printable_and_not_benign[] =
944 " !\"#$%&'()*+,.0123456789:;<=>?@[\\]^`{|}~";
945
946 char const *component = name;
947
948 for (cp = name; *cp; cp++)
949 {
950 unsigned char c = *cp;
951
952 if (noise && !strchr(benign, c))
953 {
955 ? _("file name '%s' contains byte '%c'")
956 : _("file name '%s' contains byte '\\%o'")),
957 name, c);
958 }
959 if (c == '/')
960 {
962 return false;
963 component = cp + 1;
964 }
965 }
967}
static bool componentcheck(char const *name, char const *component, char const *component_end)
Definition zic.c:885

References _, componentcheck(), fb(), name, noise, and warning().

Referenced by inlink(), and inzsub().

◆ newabbr()

static void newabbr ( const char string)
static

Definition at line 3915 of file zic.c.

3916{
3917 int i;
3918
3919 if (strcmp(string, GRANDPARENTED) != 0)
3920 {
3921 const char *cp;
3922 const char *mp;
3923
3924 cp = string;
3925 mp = NULL;
3926 while (is_alpha(*cp) || ('0' <= *cp && *cp <= '9')
3927 || *cp == '-' || *cp == '+')
3928 ++cp;
3929 if (noise && cp - string < 3)
3930 mp = _("time zone abbreviation has fewer than 3 characters");
3931 if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN)
3932 mp = _("time zone abbreviation has too many characters");
3933 if (*cp != '\0')
3934 mp = _("time zone abbreviation differs from POSIX standard");
3935 if (mp != NULL)
3936 warning("%s (%s)", mp, string);
3937 }
3938 i = strlen(string) + 1;
3939 if (charcnt + i > TZ_MAX_CHARS)
3940 {
3941 error(_("too many, or too long, time zone abbreviations"));
3943 }
3944 strcpy(&chars[charcnt], string);
3945 charcnt += i;
3946}
#define GRANDPARENTED
Definition private.h:30
#define TZ_MAX_CHARS
Definition tzfile.h:105
#define ZIC_MAX_ABBR_LEN_WO_WARN
Definition zic.c:32

References _, charcnt, chars, error(), EXIT_FAILURE, fb(), GRANDPARENTED, i, is_alpha(), noise, TZ_MAX_CHARS, warning(), and ZIC_MAX_ABBR_LEN_WO_WARN.

Referenced by addtype().

◆ oadd()

static zic_t oadd ( zic_t  t1,
zic_t  t2 
)
static

Definition at line 3769 of file zic.c.

3770{
3771 if (t1 < 0 ? t2 < ZIC_MIN - t1 : ZIC_MAX - t1 < t2)
3772 time_overflow();
3773 return t1 + t2;
3774}
static _Noreturn void time_overflow(void)
Definition zic.c:3762
#define ZIC_MIN
Definition zic.c:26

References fb(), time_overflow(), ZIC_MAX, and ZIC_MIN.

Referenced by adjleap(), gethms(), getleapdatetime(), outzone(), and rpytime().

◆ outzone()

static void outzone ( const struct zone zpfirst,
ptrdiff_t  zonecount 
)
static

Definition at line 2949 of file zic.c.

2950{
2951 const struct zone *zp;
2952 struct rule *rp;
2953 ptrdiff_t i,
2954 j;
2955 bool usestart,
2956 useuntil;
2957 zic_t starttime,
2958 untiltime;
2959 zic_t stdoff;
2960 zic_t save;
2961 zic_t year;
2963 bool startttisstd;
2964 bool startttisut;
2965 int type;
2966 char *startbuf;
2967 char *ab;
2968 char *envvar;
2969 int max_abbr_len;
2970 int max_envvar_len;
2971 bool prodstic; /* all rules are min to max */
2972 int compat;
2973 bool do_extend;
2974 char version;
2975 ptrdiff_t lastatmax = -1;
2976 zic_t one = 1;
2977 zic_t y2038_boundary = one << 31;
2979 int defaulttype = -1;
2980
2982 max_envvar_len = 2 * max_abbr_len + 5 * 9;
2984 ab = emalloc(max_abbr_len + 1);
2985 envvar = emalloc(max_envvar_len + 1);
2987 INITIALIZE(starttime);
2988
2989 /*
2990 * Now. . .finally. . .generate some useful data!
2991 */
2992 timecnt = 0;
2993 typecnt = 0;
2994 charcnt = 0;
2995 prodstic = zonecount == 1;
2996
2997 /*
2998 * Thanks to Earl Chew for noting the need to unconditionally initialize
2999 * startttisstd.
3000 */
3001 startttisstd = false;
3002 startttisut = false;
3004 if (leapseen)
3005 {
3008 }
3009 for (i = 0; i < zonecount; ++i)
3010 {
3011 zp = &zpfirst[i];
3012 if (i < zonecount - 1)
3013 updateminmax(zp->z_untilrule.r_loyear);
3014 for (j = 0; j < zp->z_nrules; ++j)
3015 {
3016 rp = &zp->z_rules[j];
3017 if (rp->r_lowasnum)
3018 updateminmax(rp->r_loyear);
3019 if (rp->r_hiwasnum)
3020 updateminmax(rp->r_hiyear);
3021 if (rp->r_lowasnum || rp->r_hiwasnum)
3022 prodstic = false;
3023 }
3024 }
3025
3026 /*
3027 * Generate lots of data if a rule can't cover all future times.
3028 */
3029 compat = stringzone(envvar, zpfirst, zonecount);
3030 version = compat < 2013 ? ZIC_VERSION_PRE_2013 : ZIC_VERSION;
3031 do_extend = compat < 0;
3032 if (noise)
3033 {
3034 if (!*envvar)
3035 warning("%s %s",
3036 _("no POSIX environment variable for zone"),
3037 zpfirst->z_name);
3038 else if (compat != 0)
3039 {
3040 /*
3041 * Circa-COMPAT clients, and earlier clients, might not work for
3042 * this zone when given dates before 1970 or after 2038.
3043 */
3044 warning(_("%s: pre-%d clients may mishandle"
3045 " distant timestamps"),
3046 zpfirst->z_name, compat);
3047 }
3048 }
3049 if (do_extend)
3050 {
3051 /*
3052 * Search through a couple of extra years past the obvious 400, to
3053 * avoid edge cases. For example, suppose a non-POSIX rule applies
3054 * from 2012 onwards and has transitions in March and September, plus
3055 * some one-off transitions in November 2013. If zic looked only at
3056 * the last 400 years, it would set max_year=2413, with the intent
3057 * that the 400 years 2014 through 2413 will be repeated. The last
3058 * transition listed in the tzfile would be in 2413-09, less than 400
3059 * years after the last one-off transition in 2013-11. Two years
3060 * might be overkill, but with the kind of edge cases available we're
3061 * not sure that one year would suffice.
3062 */
3063 enum
3064 {
3066
3069 else
3070 min_year = ZIC_MIN;
3073 else
3074 max_year = ZIC_MAX;
3075
3076 /*
3077 * Regardless of any of the above, for a "proDSTic" zone which
3078 * specifies that its rules always have and always will be in effect,
3079 * we only need one cycle to define the zone.
3080 */
3081 if (prodstic)
3082 {
3083 min_year = 1900;
3085 }
3086 }
3088 if (want_bloat())
3089 {
3090 /*
3091 * For the benefit of older systems, generate data from 1900 through
3092 * 2038.
3093 */
3094 if (min_year > 1900)
3095 min_year = 1900;
3096 if (max_year < 2038)
3097 max_year = 2038;
3098 }
3099
3100 for (i = 0; i < zonecount; ++i)
3101 {
3102 struct rule *prevrp = NULL;
3103
3104 /*
3105 * A guess that may well be corrected later.
3106 */
3107 save = 0;
3108 zp = &zpfirst[i];
3109 usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
3110 useuntil = i < (zonecount - 1);
3111 if (useuntil && zp->z_untiltime <= min_time)
3112 continue;
3113 stdoff = zp->z_stdoff;
3114 eat(zp->z_filename, zp->z_linenum);
3115 *startbuf = '\0';
3116 startoff = zp->z_stdoff;
3117 if (zp->z_nrules == 0)
3118 {
3119 save = zp->z_save;
3120 doabbr(startbuf, zp, NULL, zp->z_isdst, save, false);
3121 type = addtype(oadd(zp->z_stdoff, save),
3122 startbuf, zp->z_isdst, startttisstd,
3123 startttisut);
3124 if (usestart)
3125 {
3126 addtt(starttime, type);
3127 usestart = false;
3128 }
3129 else
3130 defaulttype = type;
3131 }
3132 else
3133 for (year = min_year; year <= max_year; ++year)
3134 {
3135 if (useuntil && year > zp->z_untilrule.r_hiyear)
3136 break;
3137
3138 /*
3139 * Mark which rules to do in the current year. For those to
3140 * do, calculate rpytime(rp, year); The former TYPE field was
3141 * also considered here.
3142 */
3143 for (j = 0; j < zp->z_nrules; ++j)
3144 {
3145 rp = &zp->z_rules[j];
3146 eats(zp->z_filename, zp->z_linenum,
3147 rp->r_filename, rp->r_linenum);
3148 rp->r_todo = year >= rp->r_loyear &&
3149 year <= rp->r_hiyear;
3150 if (rp->r_todo)
3151 {
3152 rp->r_temp = rpytime(rp, year);
3153 rp->r_todo
3154 = (rp->r_temp < y2038_boundary
3155 || year <= max_year0);
3156 }
3157 }
3158 for (;;)
3159 {
3160 ptrdiff_t k;
3161 zic_t jtime,
3162 ktime;
3163 zic_t offset;
3164
3166 if (useuntil)
3167 {
3168 /*
3169 * Turn untiltime into UT assuming the current stdoff
3170 * and save values.
3171 */
3172 untiltime = zp->z_untiltime;
3173 if (!zp->z_untilrule.r_todisut)
3175 -stdoff);
3176 if (!zp->z_untilrule.r_todisstd)
3178 -save);
3179 }
3180
3181 /*
3182 * Find the rule (of those to do, if any) that takes
3183 * effect earliest in the year.
3184 */
3185 k = -1;
3186 for (j = 0; j < zp->z_nrules; ++j)
3187 {
3188 rp = &zp->z_rules[j];
3189 if (!rp->r_todo)
3190 continue;
3191 eats(zp->z_filename, zp->z_linenum,
3192 rp->r_filename, rp->r_linenum);
3193 offset = rp->r_todisut ? 0 : stdoff;
3194 if (!rp->r_todisstd)
3195 offset = oadd(offset, save);
3196 jtime = rp->r_temp;
3197 if (jtime == min_time ||
3198 jtime == max_time)
3199 continue;
3200 jtime = tadd(jtime, -offset);
3201 if (k < 0 || jtime < ktime)
3202 {
3203 k = j;
3204 ktime = jtime;
3205 }
3206 else if (jtime == ktime)
3207 {
3208 char const *dup_rules_msg =
3209 _("two rules for same instant");
3210
3211 eats(zp->z_filename, zp->z_linenum,
3212 rp->r_filename, rp->r_linenum);
3213 warning("%s", dup_rules_msg);
3214 rp = &zp->z_rules[k];
3215 eats(zp->z_filename, zp->z_linenum,
3216 rp->r_filename, rp->r_linenum);
3217 error("%s", dup_rules_msg);
3218 }
3219 }
3220 if (k < 0)
3221 break; /* go on to next year */
3222 rp = &zp->z_rules[k];
3223 rp->r_todo = false;
3224 if (useuntil && ktime >= untiltime)
3225 break;
3226 save = rp->r_save;
3227 if (usestart && ktime == starttime)
3228 usestart = false;
3229 if (usestart)
3230 {
3231 if (ktime < starttime)
3232 {
3233 startoff = oadd(zp->z_stdoff,
3234 save);
3236 rp->r_abbrvar,
3237 rp->r_isdst,
3238 rp->r_save,
3239 false);
3240 continue;
3241 }
3242 if (*startbuf == '\0'
3243 && startoff == oadd(zp->z_stdoff,
3244 save))
3245 {
3247 zp,
3248 rp->r_abbrvar,
3249 rp->r_isdst,
3250 rp->r_save,
3251 false);
3252 }
3253 }
3254 eats(zp->z_filename, zp->z_linenum,
3255 rp->r_filename, rp->r_linenum);
3256 doabbr(ab, zp, rp->r_abbrvar,
3257 rp->r_isdst, rp->r_save, false);
3258 offset = oadd(zp->z_stdoff, rp->r_save);
3259 if (!want_bloat() && !useuntil && !do_extend
3260 && prevrp
3261 && rp->r_hiyear == ZIC_MAX
3262 && prevrp->r_hiyear == ZIC_MAX)
3263 break;
3264 type = addtype(offset, ab, rp->r_isdst,
3265 rp->r_todisstd, rp->r_todisut);
3267 defaulttype = type;
3268 if (rp->r_hiyear == ZIC_MAX
3269 && !(0 <= lastatmax
3270 && ktime < attypes[lastatmax].at))
3272 addtt(ktime, type);
3273 prevrp = rp;
3274 }
3275 }
3276 if (usestart)
3277 {
3278 if (*startbuf == '\0' &&
3279 zp->z_format != NULL &&
3280 strchr(zp->z_format, '%') == NULL &&
3281 strchr(zp->z_format, '/') == NULL)
3282 strcpy(startbuf, zp->z_format);
3283 eat(zp->z_filename, zp->z_linenum);
3284 if (*startbuf == '\0')
3285 error(_("cannot determine time zone abbreviation to use just after until time"));
3286 else
3287 {
3288 bool isdst = startoff != zp->z_stdoff;
3289
3292 if (defaulttype < 0 && !isdst)
3293 defaulttype = type;
3294 addtt(starttime, type);
3295 }
3296 }
3297
3298 /*
3299 * Now we may get to set starttime for the next zone line.
3300 */
3301 if (useuntil)
3302 {
3303 startttisstd = zp->z_untilrule.r_todisstd;
3304 startttisut = zp->z_untilrule.r_todisut;
3305 starttime = zp->z_untiltime;
3306 if (!startttisstd)
3307 starttime = tadd(starttime, -save);
3308 if (!startttisut)
3309 starttime = tadd(starttime, -stdoff);
3310 }
3311 }
3312 if (defaulttype < 0)
3313 defaulttype = 0;
3314 if (0 <= lastatmax)
3315 attypes[lastatmax].dontmerge = true;
3316 if (do_extend)
3317 {
3318 /*
3319 * If we're extending the explicitly listed observations for 400 years
3320 * because we can't fill the POSIX-TZ field, check whether we actually
3321 * ended up explicitly listing observations through that period. If
3322 * there aren't any near the end of the 400-year period, add a
3323 * redundant one at the end of the final year, to make it clear that
3324 * we are claiming to have definite knowledge of the lack of
3325 * transitions up to that point.
3326 */
3327 struct rule xr;
3328 struct attype *lastat;
3329
3330 xr.r_month = TM_JANUARY;
3331 xr.r_dycode = DC_DOM;
3332 xr.r_dayofmonth = 1;
3333 xr.r_tod = 0;
3334 for (lastat = attypes, i = 1; i < timecnt; i++)
3335 if (attypes[i].at > lastat->at)
3336 lastat = &attypes[i];
3337 if (!lastat || lastat->at < rpytime(&xr, max_year - 1))
3338 {
3339 addtt(rpytime(&xr, max_year + 1),
3340 lastat ? lastat->type : defaulttype);
3341 attypes[timecnt - 1].dontmerge = true;
3342 }
3343 }
3344 writezone(zpfirst->z_name, envvar, version, defaulttype);
3345 free(startbuf);
3346 free(ab);
3347 free(envvar);
3348}
enum COMPAT_MODE compat
Definition ecpg.c:26
#define INITIALIZE(x)
Definition private.h:84
#define YEARSPERREPEAT
Definition private.h:91
bool r_isdst
Definition zic.c:84
#define ZIC_VERSION
Definition zic.c:23
static zic_t min_year
Definition zic.c:194
#define DC_DOM
Definition zic.c:96
#define ZIC_VERSION_PRE_2013
Definition zic.c:22
static zic_t max_year
Definition zic.c:193
static int addtype(zic_t utoff, char const *abbr, bool isdst, bool ttisstd, bool ttisut)
Definition zic.c:3361
static int stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
Definition zic.c:2814
static void writezone(const char *const name, const char *const string, char version, int defaulttype)
Definition zic.c:2084
static void static void static void static void addtt(zic_t starttime, int type)
Definition zic.c:3351
static void updateminmax(const zic_t x)
Definition zic.c:2676
static size_t doabbr(char *abbr, struct zone const *zp, char const *letters, bool isdst, zic_t save, bool doquotes)
Definition zic.c:2633

References _, addtt(), addtype(), attype::at, attypes, charcnt, compat, DC_DOM, doabbr(), attype::dontmerge, eat(), eats(), emalloc(), EPOCH_YEAR, error(), fb(), free, i, INITIALIZE, j, leapmaxyear, leapminyear, leapseen, max_abbrvar_len, max_format_len, max_time, max_year, min_time, min_year, noise, oadd(), rule::r_isdst, rpytime(), stringzone(), tadd(), timecnt, TM_JANUARY, type, typecnt, updateminmax(), want_bloat(), warning(), writezone(), YEARSPERREPEAT, ZIC_MAX, ZIC_MIN, ZIC_VERSION, and ZIC_VERSION_PRE_2013.

Referenced by main().

◆ puttzcode()

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

Definition at line 2016 of file zic.c.

2017{
2018 char buf[4];
2019
2020 convert(val, buf);
2021 fwrite(buf, sizeof buf, 1, fp);
2022}
static void convert(const int_fast32_t val, char *const buf)
Definition zic.c:1994

References buf, convert(), fb(), and val.

Referenced by puttzcodepass(), and writezone().

◆ puttzcodepass()

static void puttzcodepass ( zic_t  val,
FILE fp,
int  pass 
)
static

Definition at line 2025 of file zic.c.

2026{
2027 if (pass == 1)
2028 puttzcode(val, fp);
2029 else
2030 {
2031 char buf[8];
2032
2033 convert64(val, buf);
2034 fwrite(buf, sizeof buf, 1, fp);
2035 }
2036}
static void convert64(const zic_t val, char *const buf)
Definition zic.c:2005
static void puttzcode(const int_fast32_t val, FILE *const fp)
Definition zic.c:2016

References buf, convert64(), fb(), puttzcode(), and val.

Referenced by writezone().

◆ rcomp()

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

Definition at line 1179 of file zic.c.

1180{
1181 return strcmp(((const struct rule *) cp1)->r_name,
1182 ((const struct rule *) cp2)->r_name);
1183}

References fb().

Referenced by associate().

◆ relname()

static char * relname ( char const target,
char const linkname 
)
static

Definition at line 977 of file zic.c.

978{
979 size_t i,
980 taillen,
982 size_t dir_len = 0,
983 dotdots = 0,
985 char const *f = target;
986 char *result = NULL;
987
988 if (*linkname == '/')
989 {
990 /* Make F absolute too. */
991 size_t len = strlen(directory);
992 bool needslash = len && directory[len - 1] != '/';
993
994 linksize = len + needslash + strlen(target) + 1;
995 f = result = emalloc(linksize);
997 result[len] = '/';
998 strcpy(result + len + needslash, target);
999 }
1000 for (i = 0; f[i] && f[i] == linkname[i]; i++)
1001 if (f[i] == '/')
1002 dir_len = i + 1;
1003 for (; linkname[i]; i++)
1004 dotdots += linkname[i] == '/' && linkname[i - 1] != '/';
1005 taillen = strlen(f + dir_len);
1006 dotdotetcsize = 3 * dotdots + taillen + 1;
1007 if (dotdotetcsize <= linksize)
1008 {
1009 if (!result)
1011 for (i = 0; i < dotdots; i++)
1012 memcpy(result + 3 * i, "../", 3);
1013 memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
1014 }
1015 return result;
1016}
uint32 result

References directory, emalloc(), fb(), i, len, memcpy(), and result.

◆ rpytime()

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

Definition at line 3806 of file zic.c.

3807{
3808 int m,
3809 i;
3810 zic_t dayoff; /* with a nod to Margaret O. */
3811 zic_t t,
3812 y;
3813
3814 if (wantedy == ZIC_MIN)
3815 return min_time;
3816 if (wantedy == ZIC_MAX)
3817 return max_time;
3818 dayoff = 0;
3819 m = TM_JANUARY;
3820 y = EPOCH_YEAR;
3821 if (y < wantedy)
3822 {
3823 wantedy -= y;
3826 wantedy += y;
3827 }
3828 else if (wantedy < 0)
3829 {
3832 }
3833 while (wantedy != y)
3834 {
3835 if (wantedy > y)
3836 {
3837 i = len_years[isleap(y)];
3838 ++y;
3839 }
3840 else
3841 {
3842 --y;
3843 i = -len_years[isleap(y)];
3844 }
3845 dayoff = oadd(dayoff, i);
3846 }
3847 while (m != rp->r_month)
3848 {
3849 i = len_months[isleap(y)][m];
3850 dayoff = oadd(dayoff, i);
3851 ++m;
3852 }
3853 i = rp->r_dayofmonth;
3854 if (m == TM_FEBRUARY && i == 29 && !isleap(y))
3855 {
3856 if (rp->r_dycode == DC_DOWLEQ)
3857 --i;
3858 else
3859 {
3860 error(_("use of 2/29 in non leap-year"));
3862 }
3863 }
3864 --i;
3865 dayoff = oadd(dayoff, i);
3866 if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ)
3867 {
3868 zic_t wday;
3869
3870#define LDAYSPERWEEK ((zic_t) DAYSPERWEEK)
3871 wday = EPOCH_WDAY;
3872
3873 /*
3874 * Don't trust mod of negative numbers.
3875 */
3876 if (dayoff >= 0)
3877 wday = (wday + dayoff) % LDAYSPERWEEK;
3878 else
3879 {
3880 wday -= ((-dayoff) % LDAYSPERWEEK);
3881 if (wday < 0)
3882 wday += LDAYSPERWEEK;
3883 }
3884 while (wday != rp->r_wday)
3885 if (rp->r_dycode == DC_DOWGEQ)
3886 {
3887 dayoff = oadd(dayoff, 1);
3888 if (++wday >= LDAYSPERWEEK)
3889 wday = 0;
3890 ++i;
3891 }
3892 else
3893 {
3894 dayoff = oadd(dayoff, -1);
3895 if (--wday < 0)
3896 wday = LDAYSPERWEEK - 1;
3897 --i;
3898 }
3899 if (i < 0 || i >= len_months[isleap(y)][m])
3900 {
3901 if (noise)
3902 warning(_("rule goes past start/end of month; \
3903will not work with pre-2004 versions of zic"));
3904 }
3905 }
3906 if (dayoff < min_time / SECSPERDAY)
3907 return min_time;
3908 if (dayoff > max_time / SECSPERDAY)
3909 return max_time;
3910 t = (zic_t) dayoff * SECSPERDAY;
3911 return tadd(t, rp->r_tod);
3912}
int y
Definition isn.c:76
#define SECSPERREPEAT
Definition private.h:151
#define EPOCH_WDAY
Definition private.h:127
#define TM_FEBRUARY
Definition private.h:112
#define LDAYSPERWEEK
#define DC_DOWGEQ
Definition zic.c:97
#define DC_DOWLEQ
Definition zic.c:98

References _, DC_DOWGEQ, DC_DOWLEQ, EPOCH_WDAY, EPOCH_YEAR, error(), EXIT_FAILURE, fb(), i, isleap, LDAYSPERWEEK, len_months, len_years, max_time, min_time, noise, oadd(), SECSPERDAY, SECSPERREPEAT, tadd(), TM_FEBRUARY, TM_JANUARY, warning(), y, YEARSPERREPEAT, ZIC_MAX, and ZIC_MIN.

Referenced by inzsub(), and outzone().

◆ rule_cmp()

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

Definition at line 2800 of file zic.c.

2801{
2802 if (!a)
2803 return -!!b;
2804 if (!b)
2805 return 1;
2806 if (a->r_hiyear != b->r_hiyear)
2807 return a->r_hiyear < b->r_hiyear ? -1 : 1;
2808 if (a->r_month - b->r_month != 0)
2809 return a->r_month - b->r_month;
2810 return a->r_dayofmonth - b->r_dayofmonth;
2811}

References a, and b.

Referenced by stringzone().

◆ 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 1832 of file zic.c.

1835{
1836 const struct lookup *lp;
1837 const char *cp;
1838 char *dp;
1839 char *ep;
1840 char xs;
1841
1842 if ((lp = byword(monthp, mon_names)) == NULL)
1843 {
1844 error(_("invalid month name"));
1845 return;
1846 }
1847 rp->r_month = lp->l_value;
1848 rp->r_todisstd = false;
1849 rp->r_todisut = false;
1850 dp = ecpyalloc(timep);
1851 if (*dp != '\0')
1852 {
1853 ep = dp + strlen(dp) - 1;
1854 switch (lowerit(*ep))
1855 {
1856 case 's': /* Standard */
1857 rp->r_todisstd = true;
1858 rp->r_todisut = false;
1859 *ep = '\0';
1860 break;
1861 case 'w': /* Wall */
1862 rp->r_todisstd = false;
1863 rp->r_todisut = false;
1864 *ep = '\0';
1865 break;
1866 case 'g': /* Greenwich */
1867 case 'u': /* Universal */
1868 case 'z': /* Zulu */
1869 rp->r_todisstd = true;
1870 rp->r_todisut = true;
1871 *ep = '\0';
1872 break;
1873 }
1874 }
1875 rp->r_tod = gethms(dp, _("invalid time of day"));
1876 free(dp);
1877
1878 /*
1879 * Year work.
1880 */
1881 cp = loyearp;
1882 lp = byword(cp, begin_years);
1883 rp->r_lowasnum = lp == NULL;
1884 if (!rp->r_lowasnum)
1885 switch (lp->l_value)
1886 {
1887 case YR_MINIMUM:
1888 rp->r_loyear = ZIC_MIN;
1889 break;
1890 case YR_MAXIMUM:
1891 rp->r_loyear = ZIC_MAX;
1892 break;
1893 default: /* "cannot happen" */
1895 _("%s: panic: Invalid l_value %d\n"),
1896 progname, lp->l_value);
1898 }
1899 else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_loyear, &xs) != 1)
1900 {
1901 error(_("invalid starting year"));
1902 return;
1903 }
1904 cp = hiyearp;
1905 lp = byword(cp, end_years);
1906 rp->r_hiwasnum = lp == NULL;
1907 if (!rp->r_hiwasnum)
1908 switch (lp->l_value)
1909 {
1910 case YR_MINIMUM:
1911 rp->r_hiyear = ZIC_MIN;
1912 break;
1913 case YR_MAXIMUM:
1914 rp->r_hiyear = ZIC_MAX;
1915 break;
1916 case YR_ONLY:
1917 rp->r_hiyear = rp->r_loyear;
1918 break;
1919 default: /* "cannot happen" */
1921 _("%s: panic: Invalid l_value %d\n"),
1922 progname, lp->l_value);
1924 }
1925 else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_hiyear, &xs) != 1)
1926 {
1927 error(_("invalid ending year"));
1928 return;
1929 }
1930 if (rp->r_loyear > rp->r_hiyear)
1931 {
1932 error(_("starting year greater than ending year"));
1933 return;
1934 }
1935 if (*typep != '\0')
1936 {
1937 error(_("year type \"%s\" is unsupported; use \"-\" instead"),
1938 typep);
1939 return;
1940 }
1941
1942 /*
1943 * Day work. Accept things such as: 1 lastSunday last-Sunday
1944 * (undocumented; warn about this) Sun<=20 Sun>=7
1945 */
1946 dp = ecpyalloc(dayp);
1947 if ((lp = byword(dp, lasts)) != NULL)
1948 {
1949 rp->r_dycode = DC_DOWLEQ;
1950 rp->r_wday = lp->l_value;
1951 rp->r_dayofmonth = len_months[1][rp->r_month];
1952 }
1953 else
1954 {
1955 if ((ep = strchr(dp, '<')) != NULL)
1956 rp->r_dycode = DC_DOWLEQ;
1957 else if ((ep = strchr(dp, '>')) != NULL)
1958 rp->r_dycode = DC_DOWGEQ;
1959 else
1960 {
1961 ep = dp;
1962 rp->r_dycode = DC_DOM;
1963 }
1964 if (rp->r_dycode != DC_DOM)
1965 {
1966 *ep++ = 0;
1967 if (*ep++ != '=')
1968 {
1969 error(_("invalid day of month"));
1970 free(dp);
1971 return;
1972 }
1973 if ((lp = byword(dp, wday_names)) == NULL)
1974 {
1975 error(_("invalid weekday name"));
1976 free(dp);
1977 return;
1978 }
1979 rp->r_wday = lp->l_value;
1980 }
1981 if (sscanf(ep, "%d%c", &rp->r_dayofmonth, &xs) != 1 ||
1982 rp->r_dayofmonth <= 0 ||
1983 (rp->r_dayofmonth > len_months[1][rp->r_month]))
1984 {
1985 error(_("invalid day of month"));
1986 free(dp);
1987 return;
1988 }
1989 }
1990 free(dp);
1991}
#define YR_MAXIMUM
Definition zic.c:287
#define YR_ONLY
Definition zic.c:288
static struct lookup const begin_years[]
Definition zic.c:369
#define YR_MINIMUM
Definition zic.c:286
static struct lookup const end_years[]
Definition zic.c:375

References _, begin_years, byword(), DC_DOM, DC_DOWGEQ, DC_DOWLEQ, ecpyalloc(), end_years, error(), EXIT_FAILURE, fb(), fprintf, free, gethms(), lasts, len_months, lowerit(), mon_names, progname, SCNdZIC, wday_names, YR_MAXIMUM, YR_MINIMUM, YR_ONLY, ZIC_MAX, and ZIC_MIN.

Referenced by inrule(), and inzsub().

◆ size_product()

static size_t size_product ( size_t  nitems,
size_t  itemsize 
)
static

Definition at line 425 of file zic.c.

426{
427 if (SIZE_MAX / itemsize < nitems)
428 memory_exhausted(_("size overflow"));
429 return nitems * itemsize;
430}

References _, fb(), memory_exhausted(), and nitems.

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

◆ stringoffset()

static int stringoffset ( char result,
zic_t  offset 
)
static

Definition at line 2685 of file zic.c.

2686{
2687 int hours;
2688 int minutes;
2689 int seconds;
2690 bool negative = offset < 0;
2691 int len = negative;
2692
2693 if (negative)
2694 {
2695 offset = -offset;
2696 result[0] = '-';
2697 }
2698 seconds = offset % SECSPERMIN;
2699 offset /= SECSPERMIN;
2700 minutes = offset % MINSPERHOUR;
2701 offset /= MINSPERHOUR;
2702 hours = offset;
2703 if (hours >= HOURSPERDAY * DAYSPERWEEK)
2704 {
2705 result[0] = '\0';
2706 return 0;
2707 }
2708 len += sprintf(result + len, "%d", hours);
2709 if (minutes != 0 || seconds != 0)
2710 {
2711 len += sprintf(result + len, ":%02d", minutes);
2712 if (seconds != 0)
2713 len += sprintf(result + len, ":%02d", seconds);
2714 }
2715 return len;
2716}
#define DAYSPERWEEK
Definition private.h:96

References DAYSPERWEEK, fb(), HOURSPERDAY, len, MINSPERHOUR, result, SECSPERMIN, and sprintf.

Referenced by stringrule(), and stringzone().

◆ stringrule()

static int stringrule ( char result,
struct rule *const  rp,
zic_t  save,
zic_t  stdoff 
)
static

Definition at line 2719 of file zic.c.

2720{
2721 zic_t tod = rp->r_tod;
2722 int compat = 0;
2723
2724 if (rp->r_dycode == DC_DOM)
2725 {
2726 int month,
2727 total;
2728
2729 if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY)
2730 return -1;
2731 total = 0;
2732 for (month = 0; month < rp->r_month; ++month)
2733 total += len_months[0][month];
2734 /* Omit the "J" in Jan and Feb, as that's shorter. */
2735 if (rp->r_month <= 1)
2736 result += sprintf(result, "%d", total + rp->r_dayofmonth - 1);
2737 else
2738 result += sprintf(result, "J%d", total + rp->r_dayofmonth);
2739 }
2740 else
2741 {
2742 int week;
2743 int wday = rp->r_wday;
2744 int wdayoff;
2745
2746 if (rp->r_dycode == DC_DOWGEQ)
2747 {
2748 wdayoff = (rp->r_dayofmonth - 1) % DAYSPERWEEK;
2749 if (wdayoff)
2750 compat = 2013;
2751 wday -= wdayoff;
2752 tod += wdayoff * SECSPERDAY;
2753 week = 1 + (rp->r_dayofmonth - 1) / DAYSPERWEEK;
2754 }
2755 else if (rp->r_dycode == DC_DOWLEQ)
2756 {
2757 if (rp->r_dayofmonth == len_months[1][rp->r_month])
2758 week = 5;
2759 else
2760 {
2761 wdayoff = rp->r_dayofmonth % DAYSPERWEEK;
2762 if (wdayoff)
2763 compat = 2013;
2764 wday -= wdayoff;
2765 tod += wdayoff * SECSPERDAY;
2766 week = rp->r_dayofmonth / DAYSPERWEEK;
2767 }
2768 }
2769 else
2770 return -1; /* "cannot happen" */
2771 if (wday < 0)
2772 wday += DAYSPERWEEK;
2773 result += sprintf(result, "M%d.%d.%d",
2774 rp->r_month + 1, week, wday);
2775 }
2776 if (rp->r_todisut)
2777 tod += stdoff;
2778 if (rp->r_todisstd && !rp->r_isdst)
2779 tod += save;
2780 if (tod != 2 * SECSPERMIN * MINSPERHOUR)
2781 {
2782 *result++ = '/';
2783 if (!stringoffset(result, tod))
2784 return -1;
2785 if (tod < 0)
2786 {
2787 if (compat < 2013)
2788 compat = 2013;
2789 }
2790 else if (SECSPERDAY <= tod)
2791 {
2792 if (compat < 1994)
2793 compat = 1994;
2794 }
2795 }
2796 return compat;
2797}
static int stringoffset(char *result, zic_t offset)
Definition zic.c:2685

References compat, DAYSPERWEEK, DC_DOM, DC_DOWGEQ, DC_DOWLEQ, fb(), len_months, MINSPERHOUR, result, SECSPERDAY, SECSPERMIN, sprintf, stringoffset(), and TM_FEBRUARY.

Referenced by stringzone().

◆ stringzone()

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

Definition at line 2814 of file zic.c.

2815{
2816 const struct zone *zp;
2817 struct rule *rp;
2818 struct rule *stdrp;
2819 struct rule *dstrp;
2820 ptrdiff_t i;
2821 const char *abbrvar;
2822 int compat = 0;
2823 int c;
2824 size_t len;
2825 int offsetlen;
2826 struct rule stdr,
2827 dstr;
2828
2829 result[0] = '\0';
2830
2831 /*
2832 * Internet RFC 8536 section 5.1 says to use an empty TZ string if future
2833 * timestamps are truncated.
2834 */
2835 if (hi_time < max_time)
2836 return -1;
2837
2838 zp = zpfirst + zonecount - 1;
2839 stdrp = dstrp = NULL;
2840 for (i = 0; i < zp->z_nrules; ++i)
2841 {
2842 rp = &zp->z_rules[i];
2843 if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)
2844 continue;
2845 if (!rp->r_isdst)
2846 {
2847 if (stdrp == NULL)
2848 stdrp = rp;
2849 else
2850 return -1;
2851 }
2852 else
2853 {
2854 if (dstrp == NULL)
2855 dstrp = rp;
2856 else
2857 return -1;
2858 }
2859 }
2860 if (stdrp == NULL && dstrp == NULL)
2861 {
2862 /*
2863 * There are no rules running through "max". Find the latest std rule
2864 * in stdabbrrp and latest rule of any type in stdrp.
2865 */
2866 struct rule *stdabbrrp = NULL;
2867
2868 for (i = 0; i < zp->z_nrules; ++i)
2869 {
2870 rp = &zp->z_rules[i];
2871 if (!rp->r_isdst && rule_cmp(stdabbrrp, rp) < 0)
2872 stdabbrrp = rp;
2873 if (rule_cmp(stdrp, rp) < 0)
2874 stdrp = rp;
2875 }
2876 if (stdrp != NULL && stdrp->r_isdst)
2877 {
2878 /* Perpetual DST. */
2880 dstr.r_dycode = DC_DOM;
2881 dstr.r_dayofmonth = 1;
2882 dstr.r_tod = 0;
2883 dstr.r_todisstd = dstr.r_todisut = false;
2884 dstr.r_isdst = stdrp->r_isdst;
2885 dstr.r_save = stdrp->r_save;
2886 dstr.r_abbrvar = stdrp->r_abbrvar;
2887 stdr.r_month = TM_DECEMBER;
2888 stdr.r_dycode = DC_DOM;
2889 stdr.r_dayofmonth = 31;
2890 stdr.r_tod = SECSPERDAY + stdrp->r_save;
2891 stdr.r_todisstd = stdr.r_todisut = false;
2892 stdr.r_isdst = false;
2893 stdr.r_save = 0;
2894 stdr.r_abbrvar
2895 = (stdabbrrp ? stdabbrrp->r_abbrvar : "");
2896 dstrp = &dstr;
2897 stdrp = &stdr;
2898 }
2899 }
2900 if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_isdst))
2901 return -1;
2902 abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
2903 len = doabbr(result, zp, abbrvar, false, 0, true);
2904 offsetlen = stringoffset(result + len, -zp->z_stdoff);
2905 if (!offsetlen)
2906 {
2907 result[0] = '\0';
2908 return -1;
2909 }
2910 len += offsetlen;
2911 if (dstrp == NULL)
2912 return compat;
2913 len += doabbr(result + len, zp, dstrp->r_abbrvar,
2914 dstrp->r_isdst, dstrp->r_save, true);
2915 if (dstrp->r_save != SECSPERMIN * MINSPERHOUR)
2916 {
2918 -(zp->z_stdoff + dstrp->r_save));
2919 if (!offsetlen)
2920 {
2921 result[0] = '\0';
2922 return -1;
2923 }
2924 len += offsetlen;
2925 }
2926 result[len++] = ',';
2927 c = stringrule(result + len, dstrp, dstrp->r_save, zp->z_stdoff);
2928 if (c < 0)
2929 {
2930 result[0] = '\0';
2931 return -1;
2932 }
2933 if (compat < c)
2934 compat = c;
2935 len += strlen(result + len);
2936 result[len++] = ',';
2937 c = stringrule(result + len, stdrp, dstrp->r_save, zp->z_stdoff);
2938 if (c < 0)
2939 {
2940 result[0] = '\0';
2941 return -1;
2942 }
2943 if (compat < c)
2944 compat = c;
2945 return compat;
2946}
#define TM_DECEMBER
Definition private.h:122
int r_month
Definition zic.c:75
const char * r_abbrvar
Definition zic.c:86
static int stringrule(char *result, struct rule *const rp, zic_t save, zic_t stdoff)
Definition zic.c:2719
static int rule_cmp(struct rule const *a, struct rule const *b)
Definition zic.c:2800

References compat, DC_DOM, doabbr(), fb(), hi_time, i, len, max_time, MINSPERHOUR, rule::r_month, result, rule_cmp(), SECSPERDAY, SECSPERMIN, stringoffset(), stringrule(), TM_DECEMBER, TM_JANUARY, and ZIC_MAX.

Referenced by outzone().

◆ tadd()

static zic_t tadd ( zic_t  t1,
zic_t  t2 
)
static

Definition at line 3777 of file zic.c.

3778{
3779 if (t1 < 0)
3780 {
3781 if (t2 < min_time - t1)
3782 {
3783 if (t1 != min_time)
3784 time_overflow();
3785 return min_time;
3786 }
3787 }
3788 else
3789 {
3790 if (max_time - t1 < t2)
3791 {
3792 if (t1 != max_time)
3793 time_overflow();
3794 return max_time;
3795 }
3796 }
3797 return t1 + t2;
3798}

References fb(), max_time, min_time, and time_overflow().

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

◆ time_overflow()

static _Noreturn void time_overflow ( void  )
static

Definition at line 3762 of file zic.c.

3763{
3764 error(_("time overflow"));
3766}

References _, error(), EXIT_FAILURE, and fb().

Referenced by oadd(), and tadd().

◆ timerange_option()

static bool timerange_option ( char timerange)
static

Definition at line 626 of file zic.c.

627{
628 intmax_t lo = min_time,
629 hi = max_time;
630 char *lo_end = timerange,
631 *hi_end;
632
633 if (*timerange == '@')
634 {
635 errno = 0;
636 lo = strtoimax(timerange + 1, &lo_end, 10);
637 if (lo_end == timerange + 1 || (lo == INTMAX_MAX && errno == ERANGE))
638 return false;
639 }
640 hi_end = lo_end;
641 if (lo_end[0] == '/' && lo_end[1] == '@')
642 {
643 errno = 0;
644 hi = strtoimax(lo_end + 2, &hi_end, 10);
645 if (hi_end == lo_end + 2 || hi == INTMAX_MIN)
646 return false;
647 hi -= !(hi == INTMAX_MAX && errno == ERANGE);
648 }
649 if (*hi_end || hi < lo || max_time < lo || hi < min_time)
650 return false;
651 lo_time = lo < min_time ? min_time : lo;
652 hi_time = max_time < hi ? max_time : hi;
653 return true;
654}
static zic_t lo_time
Definition zic.c:612

References fb(), hi_time, lo_time, max_time, and min_time.

Referenced by main().

◆ updateminmax()

static void updateminmax ( const zic_t  x)
static

Definition at line 2676 of file zic.c.

2677{
2678 if (min_year > x)
2679 min_year = x;
2680 if (max_year < x)
2681 max_year = x;
2682}
int x
Definition isn.c:75

References max_year, min_year, and x.

Referenced by outzone().

◆ usage()

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

Definition at line 561 of file zic.c.

562{
563 fprintf(stream,
564 _("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -P ] \\\n"
565 "\t[ -b {slim|fat} ] [ -d directory ] [ -l localtime ]"
566 " [ -L leapseconds ] \\\n"
567 "\t[ -p posixrules ] [ -r '[@lo][/@hi]' ] [ -t localtime-link ] \\\n"
568 "\t[ filename ... ]\n\n"
569 "Report bugs to %s.\n"),
571 if (status == EXIT_SUCCESS)
572 close_file(stream, NULL, NULL);
573 exit(status);
574}

References _, close_file(), EXIT_SUCCESS, fb(), fprintf, and progname.

◆ verror()

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

Definition at line 506 of file zic.c.

507{
508 /*
509 * Match the format of "cc" to allow sh users to zic ... 2>&1 | error -t
510 * "*" -v on BSD systems.
511 */
512 if (filename)
513 fprintf(stderr, _("\"%s\", line %" PRIdMAX ": "), filename, linenum);
514 vfprintf(stderr, string, args);
515 if (rfilename != NULL)
516 fprintf(stderr, _(" (rule from \"%s\", line %" PRIdMAX ")"),
518 fprintf(stderr, "\n");
519}
#define vfprintf
Definition port.h:264

References _, fb(), filename, fprintf, linenum, rfilename, rlinenum, and vfprintf.

Referenced by error(), and warning().

◆ want_bloat()

static bool want_bloat ( void  )
static

Definition at line 670 of file zic.c.

671{
672 return 0 <= bloat;
673}

References bloat.

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

◆ warning()

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

Definition at line 533 of file zic.c.

534{
536
537 fprintf(stderr, _("warning: "));
538 va_start(args, string);
539 verror(string, args);
540 va_end(args);
541 warnings = true;
542}

References _, fb(), fprintf, verror(), and warnings.

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

◆ writezone()

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

Definition at line 2084 of file zic.c.

2086{
2087 FILE *fp;
2088 ptrdiff_t i,
2089 j;
2090 int pass;
2091 static const struct tzhead tzh0;
2092 static struct tzhead tzh;
2093 bool dir_checked = false;
2094 zic_t one = 1;
2095 zic_t y2038_boundary = one << 31;
2097
2098 /*
2099 * Allocate the ATS and TYPES arrays via a single malloc, as this is a bit
2100 * faster.
2101 */
2102 zic_t *ats = emalloc(align_to(size_product(nats, sizeof *ats + 1),
2103 _Alignof(zic_t)));
2104 void *typesptr = ats + nats;
2105 unsigned char *types = typesptr;
2106 struct timerange rangeall,
2107 range32,
2108 range64;
2109
2110 /*
2111 * Sort.
2112 */
2113 if (timecnt > 1)
2114 qsort(attypes, timecnt, sizeof *attypes, atcomp);
2115
2116 /*
2117 * Optimize.
2118 */
2119 {
2121 toi;
2122
2123 toi = 0;
2124 fromi = 0;
2125 for (; fromi < timecnt; ++fromi)
2126 {
2127 if (toi != 0
2128 && ((attypes[fromi].at
2129 + utoffs[attypes[toi - 1].type])
2130 <= (attypes[toi - 1].at
2131 + utoffs[toi == 1 ? 0
2132 : attypes[toi - 2].type])))
2133 {
2134 attypes[toi - 1].type =
2136 continue;
2137 }
2138 if (toi == 0
2139 || attypes[fromi].dontmerge
2140 || (utoffs[attypes[toi - 1].type]
2141 != utoffs[attypes[fromi].type])
2142 || (isdsts[attypes[toi - 1].type]
2143 != isdsts[attypes[fromi].type])
2144 || (desigidx[attypes[toi - 1].type]
2145 != desigidx[attypes[fromi].type]))
2146 attypes[toi++] = attypes[fromi];
2147 }
2148 timecnt = toi;
2149 }
2150
2151 if (noise && timecnt > 1200)
2152 {
2153 if (timecnt > TZ_MAX_TIMES)
2154 warning(_("reference clients mishandle"
2155 " more than %d transition times"),
2156 TZ_MAX_TIMES);
2157 else
2158 warning(_("pre-2014 clients may mishandle"
2159 " more than 1200 transition times"));
2160 }
2161
2162 /*
2163 * Transfer.
2164 */
2165 for (i = 0; i < timecnt; ++i)
2166 {
2167 ats[i] = attypes[i].at;
2168 types[i] = attypes[i].type;
2169 }
2170
2171 /*
2172 * Correct for leap seconds.
2173 */
2174 for (i = 0; i < timecnt; ++i)
2175 {
2176 j = leapcnt;
2177 while (--j >= 0)
2178 if (ats[i] > trans[j] - corr[j])
2179 {
2180 ats[i] = tadd(ats[i], corr[j]);
2181 break;
2182 }
2183 }
2184
2185 /*
2186 * Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, by
2187 * inserting a no-op transition at time y2038_boundary - 1. This works
2188 * only for timestamps before the boundary, which should be good enough in
2189 * practice as QTBUG-53071 should be long-dead by 2038. Do this after
2190 * correcting for leap seconds, as the idea is to insert a transition just
2191 * before 32-bit pg_time_t rolls around, and this occurs at a slightly
2192 * different moment if transitions are leap-second corrected.
2193 */
2195 && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<'))
2196 {
2197 ats[timecnt] = y2038_boundary - 1;
2198 types[timecnt] = types[timecnt - 1];
2199 timecnt++;
2200 }
2201
2202 rangeall.defaulttype = defaulttype;
2203 rangeall.base = rangeall.leapbase = 0;
2204 rangeall.count = timecnt;
2205 rangeall.leapcount = leapcnt;
2208
2209 /*
2210 * Remove old file, if any, to snap links.
2211 */
2212 if (remove(name) == 0)
2213 dir_checked = true;
2214 else if (errno != ENOENT)
2215 {
2216 const char *e = strerror(errno);
2217
2218 fprintf(stderr, _("%s: Cannot remove %s/%s: %s\n"),
2221 }
2222 fp = fopen(name, "wb");
2223 if (!fp)
2224 {
2225 int fopen_errno = errno;
2226
2227 if (fopen_errno == ENOENT && !dir_checked)
2228 {
2229 mkdirs(name, true);
2230 fp = fopen(name, "wb");
2232 }
2233 if (!fp)
2234 {
2235 fprintf(stderr, _("%s: Cannot create %s/%s: %s\n"),
2238 }
2239 }
2240 for (pass = 1; pass <= 2; ++pass)
2241 {
2245 int thisleapi,
2248 int currenttype,
2250 bool locut,
2251 hicut;
2252 zic_t lo;
2253 int old0;
2254 char omittype[TZ_MAX_TYPES];
2255 int typemap[TZ_MAX_TYPES];
2256 int thistypecnt,
2257 stdcnt,
2258 utcnt;
2259 char thischars[TZ_MAX_CHARS];
2260 int thischarcnt;
2261 bool toomanytimes;
2262 int indmap[TZ_MAX_CHARS];
2263
2264 if (pass == 1)
2265 {
2266 /*
2267 * Arguably the default time type in the 32-bit data should be
2268 * range32.defaulttype, which is suited for timestamps just before
2269 * INT32_MIN. However, zic traditionally used the time type of
2270 * the indefinite past instead. Internet RFC 8532 says readers
2271 * should ignore 32-bit data, so this discrepancy matters only to
2272 * obsolete readers where the traditional type might be more
2273 * appropriate even if it's "wrong". So, use the historical zic
2274 * value, unless -r specifies a low cutoff that excludes some
2275 * 32-bit timestamps.
2276 */
2278 ? range64.defaulttype
2279 : range32.defaulttype);
2280
2281 thistimei = range32.base;
2282 thistimecnt = range32.count;
2283 toomanytimes = thistimecnt >> 31 >> 1 != 0;
2284 thisleapi = range32.leapbase;
2285 thisleapcnt = range32.leapcount;
2288 }
2289 else
2290 {
2291 thisdefaulttype = range64.defaulttype;
2292 thistimei = range64.base;
2293 thistimecnt = range64.count;
2294 toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
2295 thisleapi = range64.leapbase;
2296 thisleapcnt = range64.leapcount;
2299 }
2300 if (toomanytimes)
2301 error(_("too many transition times"));
2302
2303 /*
2304 * Keep the last too-low transition if no transition is exactly at LO.
2305 * The kept transition will be output as a LO "transition"; see
2306 * "Output a LO_TIME transition" below. This is needed when the
2307 * output is truncated at the start, and is also useful when catering
2308 * to buggy 32-bit clients that do not use time type 0 for timestamps
2309 * before the first transition.
2310 */
2311 if (0 < thistimei && ats[thistimei] != lo_time)
2312 {
2313 thistimei--;
2314 thistimecnt++;
2315 locut = false;
2316 }
2317
2320 if (thistimecnt != 0)
2321 {
2322 if (ats[thistimei] == lo_time)
2323 locut = false;
2324 if (hi_time < ZIC_MAX && ats[thistimelim - 1] == hi_time + 1)
2325 hicut = false;
2326 }
2327 memset(omittype, true, typecnt);
2328 omittype[thisdefaulttype] = false;
2329 for (i = thistimei; i < thistimelim; i++)
2330 omittype[types[i]] = false;
2331
2332 /*
2333 * Reorder types to make THISDEFAULTTYPE type 0. Use TYPEMAP to swap
2334 * OLD0 and THISDEFAULTTYPE so that THISDEFAULTTYPE appears as type 0
2335 * in the output instead of OLD0. TYPEMAP also omits unused types.
2336 */
2337 old0 = strlen(omittype);
2338
2339#ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH
2340
2341 /*
2342 * For some pre-2011 systems: if the last-to-be-written standard (or
2343 * daylight) type has an offset different from the most recently used
2344 * offset, append an (unused) copy of the most recently used type (to
2345 * help get global "altzone" and "timezone" variables set correctly).
2346 */
2347 if (want_bloat())
2348 {
2349 int mrudst,
2350 mrustd,
2351 hidst,
2352 histd,
2353 type;
2354
2355 hidst = histd = mrudst = mrustd = -1;
2356 for (i = thistimei; i < thistimelim; ++i)
2357 if (isdsts[types[i]])
2358 mrudst = types[i];
2359 else
2360 mrustd = types[i];
2361 for (i = old0; i < typecnt; i++)
2362 {
2363 int h = (i == old0 ? thisdefaulttype
2364 : i == thisdefaulttype ? old0 : i);
2365
2366 if (!omittype[h])
2367 {
2368 if (isdsts[h])
2369 hidst = i;
2370 else
2371 histd = i;
2372 }
2373 }
2374 if (hidst >= 0 && mrudst >= 0 && hidst != mrudst &&
2376 {
2377 isdsts[mrudst] = -1;
2380 true,
2382 ttisuts[mrudst]);
2383 isdsts[mrudst] = 1;
2384 omittype[type] = false;
2385 }
2386 if (histd >= 0 && mrustd >= 0 && histd != mrustd &&
2388 {
2389 isdsts[mrustd] = -1;
2392 false,
2394 ttisuts[mrustd]);
2395 isdsts[mrustd] = 0;
2396 omittype[type] = false;
2397 }
2398 }
2399#endif /* !defined
2400 * LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */
2401 thistypecnt = 0;
2402 for (i = old0; i < typecnt; i++)
2403 if (!omittype[i])
2405 : i == thisdefaulttype ? old0 : i]
2406 = thistypecnt++;
2407
2408 for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i)
2409 indmap[i] = -1;
2410 thischarcnt = stdcnt = utcnt = 0;
2411 for (i = old0; i < typecnt; i++)
2412 {
2413 char *thisabbr;
2414
2415 if (omittype[i])
2416 continue;
2417 if (ttisstds[i])
2419 if (ttisuts[i])
2421 if (indmap[desigidx[i]] >= 0)
2422 continue;
2423 thisabbr = &chars[desigidx[i]];
2424 for (j = 0; j < thischarcnt; ++j)
2425 if (strcmp(&thischars[j], thisabbr) == 0)
2426 break;
2427 if (j == thischarcnt)
2428 {
2430 thischarcnt += strlen(thisabbr) + 1;
2431 }
2432 indmap[desigidx[i]] = j;
2433 }
2434 if (pass == 1 && !want_bloat())
2435 {
2436 utcnt = stdcnt = thisleapcnt = 0;
2437 thistimecnt = -(locut + hicut);
2440 }
2441#define DO(field) fwrite(tzh.field, sizeof tzh.field, 1, fp)
2442 tzh = tzh0;
2443 memcpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
2444 tzh.tzh_version[0] = version;
2445 convert(utcnt, tzh.tzh_ttisutcnt);
2446 convert(stdcnt, tzh.tzh_ttisstdcnt);
2447 convert(thisleapcnt, tzh.tzh_leapcnt);
2448 convert(locut + thistimecnt + hicut, tzh.tzh_timecnt);
2449 convert(thistypecnt, tzh.tzh_typecnt);
2450 convert(thischarcnt, tzh.tzh_charcnt);
2451 DO(tzh_magic);
2452 DO(tzh_version);
2453 DO(tzh_reserved);
2454 DO(tzh_ttisutcnt);
2455 DO(tzh_ttisstdcnt);
2456 DO(tzh_leapcnt);
2457 DO(tzh_timecnt);
2458 DO(tzh_typecnt);
2459 DO(tzh_charcnt);
2460#undef DO
2461 if (pass == 1 && !want_bloat())
2462 {
2463 /* Output a minimal data block with just one time type. */
2464 puttzcode(0, fp); /* utoff */
2465 putc(0, fp); /* dst */
2466 putc(0, fp); /* index of abbreviation */
2467 putc(0, fp); /* empty-string abbreviation */
2468 continue;
2469 }
2470
2471 /* PG: print current timezone abbreviations if requested */
2472 if (print_abbrevs && pass == 2)
2473 {
2474 /* Print "type" data for periods ending after print_cutoff */
2475 for (i = thistimei; i < thistimelim; ++i)
2476 {
2477 if (i == thistimelim - 1 || ats[i + 1] > print_cutoff)
2478 {
2479 unsigned char tm = types[i];
2481
2482 fprintf(stdout, "%s\t%" PRIdFAST64 "%s\n",
2483 thisabbrev,
2484 utoffs[tm],
2485 isdsts[tm] ? "\tD" : "");
2486 }
2487 }
2488 /* Print the default type if we have no transitions at all */
2489 if (thistimei >= thistimelim)
2490 {
2491 unsigned char tm = defaulttype;
2493
2494 fprintf(stdout, "%s\t%" PRIdFAST64 "%s\n",
2495 thisabbrev,
2496 utoffs[tm],
2497 isdsts[tm] ? "\tD" : "");
2498 }
2499 }
2500
2501 /*
2502 * Output a LO_TIME transition if needed; see limitrange. But do not
2503 * go below the minimum representable value for this pass.
2504 */
2505 lo = pass == 1 && lo_time < INT32_MIN ? INT32_MIN : lo_time;
2506
2507 if (locut)
2508 puttzcodepass(lo, fp, pass);
2509 for (i = thistimei; i < thistimelim; ++i)
2510 {
2511 zic_t at = ats[i] < lo ? lo : ats[i];
2512
2513 puttzcodepass(at, fp, pass);
2514 }
2515 if (hicut)
2516 puttzcodepass(hi_time + 1, fp, pass);
2517 currenttype = 0;
2518 if (locut)
2519 putc(currenttype, fp);
2520 for (i = thistimei; i < thistimelim; ++i)
2521 {
2523 putc(currenttype, fp);
2524 }
2525 if (hicut)
2526 putc(currenttype, fp);
2527
2528 for (i = old0; i < typecnt; i++)
2529 {
2530 int h = (i == old0 ? thisdefaulttype
2531 : i == thisdefaulttype ? old0 : i);
2532
2533 if (!omittype[h])
2534 {
2535 puttzcode(utoffs[h], fp);
2536 putc(isdsts[h], fp);
2537 putc(indmap[desigidx[h]], fp);
2538 }
2539 }
2540 if (thischarcnt != 0)
2541 fwrite(thischars, sizeof thischars[0],
2542 thischarcnt, fp);
2543 for (i = thisleapi; i < thisleaplim; ++i)
2544 {
2545 zic_t todo;
2546
2547 if (roll[i])
2548 {
2549 if (timecnt == 0 || trans[i] < ats[0])
2550 {
2551 j = 0;
2552 while (isdsts[j])
2553 if (++j >= typecnt)
2554 {
2555 j = 0;
2556 break;
2557 }
2558 }
2559 else
2560 {
2561 j = 1;
2562 while (j < timecnt &&
2563 trans[i] >= ats[j])
2564 ++j;
2565 j = types[j - 1];
2566 }
2567 todo = tadd(trans[i], -utoffs[j]);
2568 }
2569 else
2570 todo = trans[i];
2571 puttzcodepass(todo, fp, pass);
2572 puttzcode(corr[i], fp);
2573 }
2574 if (stdcnt != 0)
2575 for (i = old0; i < typecnt; i++)
2576 if (!omittype[i])
2577 putc(ttisstds[i], fp);
2578 if (utcnt != 0)
2579 for (i = old0; i < typecnt; i++)
2580 if (!omittype[i])
2581 putc(ttisuts[i], fp);
2582 }
2583 fprintf(fp, "\n%s\n", string);
2585 free(ats);
2586}
static struct pg_tm tm
Definition localtime.c:104
#define TZ_MAGIC
Definition tzfile.h:37
#define TZ_MAX_TIMES
Definition tzfile.h:100
#define DO(field)
static int atcomp(const void *avp, const void *bvp)
Definition zic.c:2039
static void puttzcodepass(zic_t val, FILE *fp, int pass)
Definition zic.c:2025
static size_t align_to(size_t size, size_t alignment)
Definition zic.c:433
#define _Alignof(type)
Definition zic.c:54
static struct timerange limitrange(struct timerange r, zic_t lo, zic_t hi, zic_t const *ats, unsigned char const *types)
Definition zic.c:2057

References _, _Alignof, addtype(), align_to(), attype::at, atcomp(), attypes, chars, close_file(), convert(), corr, timerange::defaulttype, desigidx, directory, DO, emalloc(), error(), EXIT_FAILURE, fb(), fprintf, free, hi_time, i, isdsts, j, leapcnt, limitrange(), lo_time, max_time, memcpy(), min_time, mkdirs(), name, noise, print_abbrevs, print_cutoff, progname, puttzcode(), puttzcodepass(), qsort, roll, size_product(), strerror, tadd(), timecnt, tm, trans, ttisstds, ttisuts, 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_timecnt, tzhead::tzh_ttisstdcnt, tzhead::tzh_ttisutcnt, tzhead::tzh_typecnt, tzhead::tzh_version, utoffs, want_bloat(), warning(), WORK_AROUND_QTBUG_53071, and ZIC_MAX.

Referenced by outzone().

Variable Documentation

◆ 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}
}

Definition at line 369 of file zic.c.

369 {
370 {"minimum", YR_MINIMUM},
371 {"maximum", YR_MAXIMUM},
372 {NULL, 0}
373};

Referenced by rulesub().

◆ bloat

int bloat
static

Definition at line 667 of file zic.c.

Referenced by main(), and want_bloat().

◆ charcnt

int charcnt
static

◆ chars

char chars[TZ_MAX_CHARS]
static

◆ comment_leapexpires

zic_t comment_leapexpires = -1
static

Definition at line 619 of file zic.c.

Referenced by adjleap(), and infile().

◆ corr

zic_t corr[TZ_MAX_LEAPS]
static

Definition at line 410 of file zic.c.

Referenced by adjleap(), import_pg_statistic(), leapadd(), timesub(), tzloadbody(), and writezone().

◆ desigidx

unsigned char desigidx[TZ_MAX_TYPES]
static

Definition at line 405 of file zic.c.

Referenced by addtype(), init_ttinfo(), tzloadbody(), and writezone().

◆ directory

◆ end_years

struct lookup const end_years[]
static
Initial value:
= {
{"minimum", YR_MINIMUM},
{"maximum", YR_MAXIMUM},
{"only", YR_ONLY},
{NULL, 0}
}

Definition at line 375 of file zic.c.

375 {
376 {"minimum", YR_MINIMUM},
377 {"maximum", YR_MAXIMUM},
378 {"only", YR_ONLY},
379 {NULL, 0}
380};

Referenced by rulesub().

◆ errors

bool errors
static

Definition at line 183 of file zic.c.

Referenced by associate(), error(), and main().

◆ filename

const char* filename
static

Definition at line 185 of file zic.c.

Referenced by eats(), infile(), inlink(), inrule(), inzsub(), and verror().

◆ hi_time

zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE)
static

Definition at line 613 of file zic.c.

Referenced by adjleap(), stringzone(), timerange_option(), and writezone().

◆ isdsts

char isdsts[TZ_MAX_TYPES]
static

Definition at line 404 of file zic.c.

Referenced by addtype(), and writezone().

◆ lasts

struct lookup const lasts[]
static
Initial value:
= {
{"last-Sunday", TM_SUNDAY},
{"last-Monday", TM_MONDAY},
{"last-Tuesday", TM_TUESDAY},
{"last-Wednesday", TM_WEDNESDAY},
{"last-Thursday", TM_THURSDAY},
{"last-Friday", TM_FRIDAY},
{"last-Saturday", TM_SATURDAY},
{NULL, 0}
}
#define TM_THURSDAY
Definition private.h:107
#define TM_TUESDAY
Definition private.h:105
#define TM_FRIDAY
Definition private.h:108
#define TM_SATURDAY
Definition private.h:109
#define TM_WEDNESDAY
Definition private.h:106
#define TM_MONDAY
Definition private.h:104
#define TM_SUNDAY
Definition private.h:103

Definition at line 358 of file zic.c.

358 {
359 {"last-Sunday", TM_SUNDAY},
360 {"last-Monday", TM_MONDAY},
361 {"last-Tuesday", TM_TUESDAY},
362 {"last-Wednesday", TM_WEDNESDAY},
363 {"last-Thursday", TM_THURSDAY},
364 {"last-Friday", TM_FRIDAY},
365 {"last-Saturday", TM_SATURDAY},
366 {NULL, 0}
367};

Referenced by byword(), and rulesub().

◆ lcltime

const char* lcltime
static

Definition at line 657 of file zic.c.

Referenced by inzone(), and main().

◆ leap_line_codes

struct lookup const leap_line_codes[]
static
Initial value:
= {
{"Leap", LC_LEAP},
{"Expires", LC_EXPIRES},
{NULL, 0}
}

Definition at line 325 of file zic.c.

325 {
326 {"Leap", LC_LEAP},
327 {"Expires", LC_EXPIRES},
328 {NULL, 0}
329};

Referenced by infile().

◆ leap_types

struct lookup const leap_types[]
static
Initial value:
= {
{"Rolling", true},
{"Stationary", false},
{NULL, 0}
}

Definition at line 382 of file zic.c.

382 {
383 {"Rolling", true},
384 {"Stationary", false},
385 {NULL, 0}
386};

Referenced by inleap().

◆ leapcnt

int leapcnt
static

Definition at line 186 of file zic.c.

Referenced by adjleap(), leapadd(), tzloadbody(), and writezone().

◆ leapexpires

zic_t leapexpires = -1
static

Definition at line 616 of file zic.c.

Referenced by adjleap(), and inexpires().

◆ leapmaxyear

zic_t leapmaxyear
static

Definition at line 189 of file zic.c.

Referenced by getleapdatetime(), and outzone().

◆ leapminyear

zic_t leapminyear
static

Definition at line 188 of file zic.c.

Referenced by getleapdatetime(), and outzone().

◆ leapsec

const char* leapsec
static

Definition at line 659 of file zic.c.

Referenced by infile(), and main().

◆ leapseen

bool leapseen
static

Definition at line 187 of file zic.c.

Referenced by getleapdatetime(), and outzone().

◆ len_months

const int len_months[2][MONSPERYEAR]
static
Initial value:
= {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
}

Definition at line 388 of file zic.c.

388 {
389 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
390 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
391};

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

◆ len_years

const int len_years[2]
static
Initial value:
= {
}
#define DAYSPERNYEAR
Definition private.h:97
#define DAYSPERLYEAR
Definition private.h:98

Definition at line 393 of file zic.c.

393 {
395};

Referenced by getleapdatetime(), and rpytime().

◆ linenum

lineno_t linenum
static

Definition at line 190 of file zic.c.

Referenced by eats(), inlink(), inrule(), inzsub(), and verror().

◆ links

struct link* links
static

Definition at line 306 of file zic.c.

Referenced by inlink(), and main().

◆ lo_time

zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE)
static

Definition at line 612 of file zic.c.

Referenced by timerange_option(), and writezone().

◆ max_abbrvar_len

int max_abbrvar_len = PERCENT_Z_LEN_BOUND
static

Definition at line 191 of file zic.c.

Referenced by inrule(), and outzone().

◆ max_format_len

int max_format_len
static

Definition at line 192 of file zic.c.

Referenced by inzsub(), and outzone().

◆ max_time

◆ max_year

zic_t max_year
static

Definition at line 193 of file zic.c.

Referenced by outzone(), and updateminmax().

◆ min_time

Definition at line 605 of file zic.c.

Referenced by getleapdatetime(), inzsub(), outzone(), rpytime(), tadd(), timerange_option(), and writezone().

◆ min_year

zic_t min_year
static

Definition at line 194 of file zic.c.

Referenced by outzone(), and updateminmax().

◆ mon_names

struct lookup const mon_names[]
static
Initial value:
= {
{"January", TM_JANUARY},
{"February", TM_FEBRUARY},
{"March", TM_MARCH},
{"April", TM_APRIL},
{"May", TM_MAY},
{"June", TM_JUNE},
{"July", TM_JULY},
{"August", TM_AUGUST},
{"September", TM_SEPTEMBER},
{"October", TM_OCTOBER},
{"November", TM_NOVEMBER},
{"December", TM_DECEMBER},
{NULL, 0}
}
#define TM_AUGUST
Definition private.h:118
#define TM_SEPTEMBER
Definition private.h:119
#define TM_MARCH
Definition private.h:113
#define TM_NOVEMBER
Definition private.h:121
#define TM_JULY
Definition private.h:117
#define TM_APRIL
Definition private.h:114
#define TM_OCTOBER
Definition private.h:120
#define TM_MAY
Definition private.h:115
#define TM_JUNE
Definition private.h:116

Definition at line 331 of file zic.c.

331 {
332 {"January", TM_JANUARY},
333 {"February", TM_FEBRUARY},
334 {"March", TM_MARCH},
335 {"April", TM_APRIL},
336 {"May", TM_MAY},
337 {"June", TM_JUNE},
338 {"July", TM_JULY},
339 {"August", TM_AUGUST},
340 {"September", TM_SEPTEMBER},
341 {"October", TM_OCTOBER},
342 {"November", TM_NOVEMBER},
343 {"December", TM_DECEMBER},
344 {NULL, 0}
345};

Referenced by getleapdatetime(), and rulesub().

◆ nlinks

ptrdiff_t nlinks
static

Definition at line 307 of file zic.c.

Referenced by inlink(), and main().

◆ nlinks_alloc

ptrdiff_t nlinks_alloc
static

Definition at line 308 of file zic.c.

Referenced by inlink().

◆ noise

bool noise
static

Definition at line 195 of file zic.c.

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

◆ nrules

ptrdiff_t nrules
static

Definition at line 291 of file zic.c.

Referenced by associate(), and inrule().

◆ nrules_alloc

ptrdiff_t nrules_alloc
static

Definition at line 292 of file zic.c.

Referenced by inrule().

◆ nzones

ptrdiff_t nzones
static

Definition at line 295 of file zic.c.

Referenced by associate(), inzone(), inzsub(), and main().

◆ nzones_alloc

ptrdiff_t nzones_alloc
static

Definition at line 296 of file zic.c.

Referenced by inzsub().

◆ print_abbrevs

bool print_abbrevs
static

Definition at line 196 of file zic.c.

Referenced by main(), and writezone().

◆ print_cutoff

zic_t print_cutoff
static

Definition at line 197 of file zic.c.

Referenced by main(), and writezone().

◆ progname

const char* progname
static

◆ psxrules

const char* psxrules
static

Definition at line 656 of file zic.c.

Referenced by inzone(), and main().

◆ PTRDIFF_MAX

ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t))
static

Definition at line 49 of file zic.c.

Referenced by growalloc().

◆ rfilename

const char* rfilename
static

Definition at line 198 of file zic.c.

Referenced by eats(), and verror().

◆ rlinenum

lineno_t rlinenum
static

Definition at line 199 of file zic.c.

Referenced by eats(), and verror().

◆ roll

char roll[TZ_MAX_LEAPS]
static

Definition at line 411 of file zic.c.

Referenced by leapadd(), and writezone().

◆ rules

struct rule* rules
static

Definition at line 290 of file zic.c.

Referenced by associate(), fireRIRrules(), inrule(), and RelationBuildRuleLock().

◆ timecnt

ptrdiff_t timecnt
static

Definition at line 201 of file zic.c.

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

◆ timecnt_alloc

ptrdiff_t timecnt_alloc
static

Definition at line 202 of file zic.c.

Referenced by addtt().

◆ trans

◆ ttisstds

bool ttisstds[TZ_MAX_TYPES]
static

Definition at line 406 of file zic.c.

Referenced by addtype(), and writezone().

◆ ttisuts

bool ttisuts[TZ_MAX_TYPES]
static

Definition at line 407 of file zic.c.

Referenced by addtype(), and writezone().

◆ typecnt

int typecnt
static

Definition at line 203 of file zic.c.

Referenced by addtype(), outzone(), tzloadbody(), and writezone().

◆ tzdefault

const char* tzdefault
static

Definition at line 660 of file zic.c.

Referenced by inzone(), and main().

◆ utoffs

zic_t utoffs[TZ_MAX_TYPES]
static

Definition at line 403 of file zic.c.

Referenced by addtype(), and writezone().

◆ warnings

bool warnings
static

Definition at line 184 of file zic.c.

Referenced by main(), and warning().

◆ wday_names

struct lookup const wday_names[]
static
Initial value:
= {
{"Sunday", TM_SUNDAY},
{"Monday", TM_MONDAY},
{"Tuesday", TM_TUESDAY},
{"Wednesday", TM_WEDNESDAY},
{"Thursday", TM_THURSDAY},
{"Friday", TM_FRIDAY},
{"Saturday", TM_SATURDAY},
{NULL, 0}
}

Definition at line 347 of file zic.c.

347 {
348 {"Sunday", TM_SUNDAY},
349 {"Monday", TM_MONDAY},
350 {"Tuesday", TM_TUESDAY},
351 {"Wednesday", TM_WEDNESDAY},
352 {"Thursday", TM_THURSDAY},
353 {"Friday", TM_FRIDAY},
354 {"Saturday", TM_SATURDAY},
355 {NULL, 0}
356};

Referenced by byword(), and rulesub().

◆ zi_line_codes

struct lookup const zi_line_codes[]
static
Initial value:
= {
{"Rule", LC_RULE},
{"Zone", LC_ZONE},
{"Link", LC_LINK},
{NULL, 0}
}

Definition at line 319 of file zic.c.

319 {
320 {"Rule", LC_RULE},
321 {"Zone", LC_ZONE},
322 {"Link", LC_LINK},
323 {NULL, 0}
324};

Referenced by infile().

◆ zones

struct zone* zones
static

Definition at line 294 of file zic.c.

Referenced by associate(), inzone(), inzsub(), and main().