PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
localtime.c File Reference
#include "c.h"
#include <fcntl.h>
#include "datatype/timestamp.h"
#include "private.h"
#include "pgtz.h"
#include "tzfile.h"
Include dependency graph for localtime.c:

Go to the source code of this file.

Data Structures

struct  rule
 
union  input_buffer
 
union  local_storage
 

Macros

#define WILDABBR   " "
 
#define TZDEFRULESTRING   ",M4.1.0,M10.5.0"
 
#define gmtptr   (&gmtmem)
 

Enumerations

enum  r_type { JULIAN_DAY, DAY_OF_YEAR, MONTH_NTH_DAY_OF_WEEK }
 

Functions

static struct pg_tmgmtsub (pg_time_t const *, int32, struct pg_tm *)
 
static bool increment_overflow (int *, int)
 
static bool increment_overflow_time (pg_time_t *, int32)
 
static struct pg_tmtimesub (pg_time_t const *, int32, struct state const *, struct pg_tm *)
 
static bool typesequiv (struct state const *, int, int)
 
static void init_ttinfo (struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
 
static int32 detzcode (const char *codep)
 
static int64 detzcode64 (const char *codep)
 
static bool differ_by_repeat (const pg_time_t t1, const pg_time_t t0)
 
static int tzloadbody (char const *name, char *canonname, struct state *sp, bool doextend, union local_storage *lsp)
 
int tzload (const char *name, char *canonname, struct state *sp, bool doextend)
 
static const char * getzname (const char *strp)
 
static const char * getqzname (const char *strp, int delim)
 
static const char * getnum (const char *strp, int *nump, int min, int max)
 
static const char * getsecs (const char *strp, int32 *secsp)
 
static const char * getoffset (const char *strp, int32 *offsetp)
 
static const char * getrule (const char *strp, struct rule *rulep)
 
static int32 transtime (int year, const struct rule *rulep, int32 offset)
 
bool tzparse (const char *name, struct state *sp, bool lastditch)
 
static void gmtload (struct state *sp)
 
static struct pg_tmlocalsub (struct state const *sp, pg_time_t const *timep, struct pg_tm *tmp)
 
struct pg_tmpg_localtime (const pg_time_t *timep, const pg_tz *tz)
 
struct pg_tmpg_gmtime (const pg_time_t *timep)
 
static int leaps_thru_end_of (const int y)
 
int pg_next_dst_boundary (const pg_time_t *timep, long int *before_gmtoff, int *before_isdst, pg_time_t *boundary, long int *after_gmtoff, int *after_isdst, const pg_tz *tz)
 
bool pg_interpret_timezone_abbrev (const char *abbrev, const pg_time_t *timep, long int *gmtoff, int *isdst, const pg_tz *tz)
 
bool pg_get_timezone_offset (const pg_tz *tz, long int *gmtoff)
 
const char * pg_get_timezone_name (pg_tz *tz)
 
bool pg_tz_acceptable (pg_tz *tz)
 

Variables

static const char wildabbr [] = WILDABBR
 
static const char gmt [] = "GMT"
 
static const pg_time_t time_t_min = MINVAL(pg_time_t, TYPE_BIT(pg_time_t))
 
static const pg_time_t time_t_max = MAXVAL(pg_time_t, TYPE_BIT(pg_time_t))
 
static struct pg_tm tm
 
static const int mon_lengths [2][MONSPERYEAR]
 
static const int year_lengths [2]
 

Macro Definition Documentation

#define gmtptr   (&gmtmem)

Referenced by gmtsub().

#define TZDEFRULESTRING   ",M4.1.0,M10.5.0"

Definition at line 63 of file localtime.c.

Referenced by tzparse().

#define WILDABBR   " "

Definition at line 45 of file localtime.c.

Enumeration Type Documentation

enum r_type
Enumerator
JULIAN_DAY 
DAY_OF_YEAR 
MONTH_NTH_DAY_OF_WEEK 

Definition at line 67 of file localtime.c.

68 {
69  JULIAN_DAY, /* Jn = Julian day */
70  DAY_OF_YEAR, /* n = day of year */
71  MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
72 };

Function Documentation

static int32 detzcode ( const char *  codep)
static

Definition at line 117 of file localtime.c.

References i, and TWOS_COMPLEMENT.

Referenced by tzloadbody().

118 {
119  int32 result;
120  int i;
121  int32 one = 1;
122  int32 halfmaxval = one << (32 - 2);
123  int32 maxval = halfmaxval - 1 + halfmaxval;
124  int32 minval = -1 - maxval;
125 
126  result = codep[0] & 0x7f;
127  for (i = 1; i < 4; ++i)
128  result = (result << 8) | (codep[i] & 0xff);
129 
130  if (codep[0] & 0x80)
131  {
132  /*
133  * Do two's-complement negation even on non-two's-complement machines.
134  * If the result would be minval - 1, return minval.
135  */
136  result -= !TWOS_COMPLEMENT(int32) &&result != 0;
137  result += minval;
138  }
139  return result;
140 }
signed int int32
Definition: c.h:256
int i
#define TWOS_COMPLEMENT(t)
Definition: private.h:78
static int64 detzcode64 ( const char *  codep)
static

Definition at line 143 of file localtime.c.

References i, and TWOS_COMPLEMENT.

Referenced by tzloadbody().

144 {
145  uint64 result;
146  int i;
147  int64 one = 1;
148  int64 halfmaxval = one << (64 - 2);
149  int64 maxval = halfmaxval - 1 + halfmaxval;
150  int64 minval = -TWOS_COMPLEMENT(int64) -maxval;
151 
152  result = codep[0] & 0x7f;
153  for (i = 1; i < 8; ++i)
154  result = (result << 8) | (codep[i] & 0xff);
155 
156  if (codep[0] & 0x80)
157  {
158  /*
159  * Do two's-complement negation even on non-two's-complement machines.
160  * If the result would be minval - 1, return minval.
161  */
162  result -= !TWOS_COMPLEMENT(int64) &&result != 0;
163  result += minval;
164  }
165  return result;
166 }
int i
#define TWOS_COMPLEMENT(t)
Definition: private.h:78
static bool differ_by_repeat ( const pg_time_t  t1,
const pg_time_t  t0 
)
static

Definition at line 169 of file localtime.c.

References SECSPERREPEAT, SECSPERREPEAT_BITS, TYPE_BIT, and TYPE_SIGNED.

Referenced by tzloadbody().

170 {
172  return 0;
173  return t1 - t0 == SECSPERREPEAT;
174 }
int64 pg_time_t
Definition: pgtime.h:23
#define SECSPERREPEAT_BITS
Definition: private.h:128
#define TYPE_BIT(type)
Definition: private.h:71
#define SECSPERREPEAT
Definition: private.h:124
#define TYPE_SIGNED(type)
Definition: private.h:75
static const char* getnum ( const char *  strp,
int *  nump,
int  min,
int  max 
)
static

Definition at line 626 of file localtime.c.

References is_digit, and NULL.

Referenced by getrule(), and getsecs().

627 {
628  char c;
629  int num;
630 
631  if (strp == NULL || !is_digit(c = *strp))
632  return NULL;
633  num = 0;
634  do
635  {
636  num = num * 10 + (c - '0');
637  if (num > max)
638  return NULL; /* illegal value */
639  c = *++strp;
640  } while (is_digit(c));
641  if (num < min)
642  return NULL; /* illegal value */
643  *nump = num;
644  return strp;
645 }
#define is_digit(c)
Definition: private.h:49
char * c
#define NULL
Definition: c.h:229
static const char* getoffset ( const char *  strp,
int32 offsetp 
)
static

Definition at line 695 of file localtime.c.

References getsecs(), and NULL.

Referenced by getrule(), and tzparse().

696 {
697  bool neg = false;
698 
699  if (*strp == '-')
700  {
701  neg = true;
702  ++strp;
703  }
704  else if (*strp == '+')
705  ++strp;
706  strp = getsecs(strp, offsetp);
707  if (strp == NULL)
708  return NULL; /* illegal time */
709  if (neg)
710  *offsetp = -*offsetp;
711  return strp;
712 }
static const char * getsecs(const char *strp, int32 *secsp)
Definition: localtime.c:655
#define NULL
Definition: c.h:229
static const char* getqzname ( const char *  strp,
int  delim 
)
static

Definition at line 610 of file localtime.c.

Referenced by tzparse().

611 {
612  int c;
613 
614  while ((c = *strp) != '\0' && c != delim)
615  ++strp;
616  return strp;
617 }
char * c
static const char* getrule ( const char *  strp,
struct rule rulep 
)
static

Definition at line 721 of file localtime.c.

References DAY_OF_YEAR, DAYSPERLYEAR, DAYSPERNYEAR, DAYSPERWEEK, getnum(), getoffset(), is_digit, JULIAN_DAY, MONSPERYEAR, MONTH_NTH_DAY_OF_WEEK, NULL, rule::r_day, rule::r_mon, rule::r_time, rule::r_type, rule::r_week, and SECSPERHOUR.

Referenced by tzparse().

722 {
723  if (*strp == 'J')
724  {
725  /*
726  * Julian day.
727  */
728  rulep->r_type = JULIAN_DAY;
729  ++strp;
730  strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
731  }
732  else if (*strp == 'M')
733  {
734  /*
735  * Month, week, day.
736  */
737  rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
738  ++strp;
739  strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
740  if (strp == NULL)
741  return NULL;
742  if (*strp++ != '.')
743  return NULL;
744  strp = getnum(strp, &rulep->r_week, 1, 5);
745  if (strp == NULL)
746  return NULL;
747  if (*strp++ != '.')
748  return NULL;
749  strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
750  }
751  else if (is_digit(*strp))
752  {
753  /*
754  * Day of year.
755  */
756  rulep->r_type = DAY_OF_YEAR;
757  strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
758  }
759  else
760  return NULL; /* invalid format */
761  if (strp == NULL)
762  return NULL;
763  if (*strp == '/')
764  {
765  /*
766  * Time specified.
767  */
768  ++strp;
769  strp = getoffset(strp, &rulep->r_time);
770  }
771  else
772  rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
773  return strp;
774 }
#define DAYSPERLYEAR
Definition: tzfile.h:108
static const char * getoffset(const char *strp, int32 *offsetp)
Definition: localtime.c:695
#define DAYSPERNYEAR
Definition: tzfile.h:107
int r_mon
Definition: localtime.c:79
#define is_digit(c)
Definition: private.h:49
int r_week
Definition: localtime.c:78
#define MONSPERYEAR
Definition: tzfile.h:111
enum r_type r_type
Definition: localtime.c:76
int32 r_time
Definition: localtime.c:80
int r_day
Definition: localtime.c:77
#define DAYSPERWEEK
Definition: tzfile.h:106
#define NULL
Definition: c.h:229
static const char * getnum(const char *strp, int *nump, int min, int max)
Definition: localtime.c:626
#define SECSPERHOUR
Definition: tzfile.h:109
static const char* getsecs ( const char *  strp,
int32 secsp 
)
static

Definition at line 655 of file localtime.c.

References DAYSPERWEEK, getnum(), HOURSPERDAY, MINSPERHOUR, NULL, SECSPERHOUR, and SECSPERMIN.

Referenced by getoffset().

656 {
657  int num;
658 
659  /*
660  * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
661  * "M10.4.6/26", which does not conform to Posix, but which specifies the
662  * equivalent of "02:00 on the first Sunday on or after 23 Oct".
663  */
664  strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
665  if (strp == NULL)
666  return NULL;
667  *secsp = num * (int32) SECSPERHOUR;
668  if (*strp == ':')
669  {
670  ++strp;
671  strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
672  if (strp == NULL)
673  return NULL;
674  *secsp += num * SECSPERMIN;
675  if (*strp == ':')
676  {
677  ++strp;
678  /* 'SECSPERMIN' allows for leap seconds. */
679  strp = getnum(strp, &num, 0, SECSPERMIN);
680  if (strp == NULL)
681  return NULL;
682  *secsp += num;
683  }
684  }
685  return strp;
686 }
#define HOURSPERDAY
Definition: tzfile.h:105
signed int int32
Definition: c.h:256
#define MINSPERHOUR
Definition: tzfile.h:104
#define DAYSPERWEEK
Definition: tzfile.h:106
#define NULL
Definition: c.h:229
#define SECSPERMIN
Definition: tzfile.h:103
static const char * getnum(const char *strp, int *nump, int min, int max)
Definition: localtime.c:626
#define SECSPERHOUR
Definition: tzfile.h:109
static const char* getzname ( const char *  strp)
static

Definition at line 591 of file localtime.c.

References is_digit.

Referenced by tzparse().

592 {
593  char c;
594 
595  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
596  c != '+')
597  ++strp;
598  return strp;
599 }
#define is_digit(c)
Definition: private.h:49
char * c
static void gmtload ( struct state sp)
static

Definition at line 1160 of file localtime.c.

References gmt, NULL, tzload(), and tzparse().

Referenced by gmtsub().

1161 {
1162  if (tzload(gmt, NULL, sp, true) != 0)
1163  tzparse(gmt, sp, true);
1164 }
int tzload(const char *name, char *canonname, struct state *sp, bool doextend)
Definition: localtime.c:537
bool tzparse(const char *name, struct state *sp, bool lastditch)
Definition: localtime.c:878
#define NULL
Definition: c.h:229
static const char gmt[]
Definition: localtime.c:50
static struct pg_tm * gmtsub ( pg_time_t const *  timep,
int32  offset,
struct pg_tm tmp 
)
static

Definition at line 1266 of file localtime.c.

References gmtload(), gmtptr, timesub(), pg_tm::tm_zone, and wildabbr.

Referenced by localsub(), and pg_gmtime().

1267 {
1268  struct pg_tm *result;
1269 
1270  /* GMT timezone state data is kept here */
1271  static struct state gmtmem;
1272  static bool gmt_is_set = false;
1273 #define gmtptr (&gmtmem)
1274 
1275  if (!gmt_is_set)
1276  {
1277  gmt_is_set = true;
1278  gmtload(gmtptr);
1279  }
1280  result = timesub(timep, offset, gmtptr, tmp);
1281 
1282  /*
1283  * Could get fancy here and deliver something such as "+xx" or "-xx" if
1284  * offset is non-zero, but this is no time for a treasure hunt.
1285  */
1286  if (offset != 0)
1287  tmp->tm_zone = wildabbr;
1288  else
1289  tmp->tm_zone = gmtptr->chars;
1290 
1291  return result;
1292 }
static void gmtload(struct state *sp)
Definition: localtime.c:1160
Definition: pgtime.h:25
static const char wildabbr[]
Definition: localtime.c:48
const char * tm_zone
Definition: pgtime.h:37
Definition: regguts.h:298
#define gmtptr
static struct pg_tm * timesub(pg_time_t const *, int32, struct state const *, struct pg_tm *)
Definition: localtime.c:1312
static bool increment_overflow ( int *  ip,
int  j 
)
static

Definition at line 1450 of file localtime.c.

References i.

Referenced by timesub().

1451 {
1452  int const i = *ip;
1453 
1454  /*----------
1455  * If i >= 0 there can only be overflow if i + j > INT_MAX
1456  * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1457  * If i < 0 there can only be overflow if i + j < INT_MIN
1458  * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1459  *----------
1460  */
1461  if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1462  return true;
1463  *ip += j;
1464  return false;
1465 }
int i
static bool increment_overflow_time ( pg_time_t tp,
int32  j 
)
static

Definition at line 1468 of file localtime.c.

References time_t_min, and TYPE_SIGNED.

Referenced by tzparse().

1469 {
1470  /*----------
1471  * This is like
1472  * 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1473  * except that it does the right thing even if *tp + j would overflow.
1474  *----------
1475  */
1476  if (!(j < 0
1477  ? (TYPE_SIGNED(pg_time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1478  : *tp <= time_t_max - j))
1479  return true;
1480  *tp += j;
1481  return false;
1482 }
int64 pg_time_t
Definition: pgtime.h:23
static const pg_time_t time_t_max
Definition: localtime.c:54
static const pg_time_t time_t_min
Definition: localtime.c:53
#define TYPE_SIGNED(type)
Definition: private.h:75
static void init_ttinfo ( struct ttinfo s,
int32  gmtoff,
bool  isdst,
int  abbrind 
)
static

Definition at line 107 of file localtime.c.

References ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, and ttinfo::tt_ttisstd.

Referenced by tzparse().

108 {
109  s->tt_gmtoff = gmtoff;
110  s->tt_isdst = isdst;
111  s->tt_abbrind = abbrind;
112  s->tt_ttisstd = false;
113  s->tt_ttisgmt = false;
114 }
int32 tt_gmtoff
Definition: pgtz.h:28
bool tt_isdst
Definition: pgtz.h:29
bool tt_ttisstd
Definition: pgtz.h:31
int tt_abbrind
Definition: pgtz.h:30
bool tt_ttisgmt
Definition: pgtz.h:32
static int leaps_thru_end_of ( const int  y)
static

Definition at line 1305 of file localtime.c.

Referenced by timesub().

1306 {
1307  return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1308  -(leaps_thru_end_of(-(y + 1)) + 1);
1309 }
static int leaps_thru_end_of(const int y)
Definition: localtime.c:1305
static struct pg_tm* localsub ( struct state const *  sp,
pg_time_t const *  timep,
struct pg_tm tmp 
)
static

Definition at line 1174 of file localtime.c.

References state::ats, AVGSECSPERYEAR, state::chars, state::defaulttype, gmtsub(), state::goahead, state::goback, i, NULL, SECSPERREPEAT, state::timecnt, timesub(), pg_tm::tm_isdst, pg_tm::tm_year, pg_tm::tm_zone, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, state::types, and YEARSPERREPEAT.

Referenced by pg_localtime().

1176 {
1177  const struct ttinfo *ttisp;
1178  int i;
1179  struct pg_tm *result;
1180  const pg_time_t t = *timep;
1181 
1182  if (sp == NULL)
1183  return gmtsub(timep, 0, tmp);
1184  if ((sp->goback && t < sp->ats[0]) ||
1185  (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1186  {
1187  pg_time_t newt = t;
1188  pg_time_t seconds;
1189  pg_time_t years;
1190 
1191  if (t < sp->ats[0])
1192  seconds = sp->ats[0] - t;
1193  else
1194  seconds = t - sp->ats[sp->timecnt - 1];
1195  --seconds;
1196  years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1197  seconds = years * AVGSECSPERYEAR;
1198  if (t < sp->ats[0])
1199  newt += seconds;
1200  else
1201  newt -= seconds;
1202  if (newt < sp->ats[0] ||
1203  newt > sp->ats[sp->timecnt - 1])
1204  return NULL; /* "cannot happen" */
1205  result = localsub(sp, &newt, tmp);
1206  if (result)
1207  {
1208  int64 newy;
1209 
1210  newy = result->tm_year;
1211  if (t < sp->ats[0])
1212  newy -= years;
1213  else
1214  newy += years;
1215  if (!(INT_MIN <= newy && newy <= INT_MAX))
1216  return NULL;
1217  result->tm_year = newy;
1218  }
1219  return result;
1220  }
1221  if (sp->timecnt == 0 || t < sp->ats[0])
1222  {
1223  i = sp->defaulttype;
1224  }
1225  else
1226  {
1227  int lo = 1;
1228  int hi = sp->timecnt;
1229 
1230  while (lo < hi)
1231  {
1232  int mid = (lo + hi) >> 1;
1233 
1234  if (t < sp->ats[mid])
1235  hi = mid;
1236  else
1237  lo = mid + 1;
1238  }
1239  i = (int) sp->types[lo - 1];
1240  }
1241  ttisp = &sp->ttis[i];
1242 
1243  result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1244  if (result)
1245  {
1246  result->tm_isdst = ttisp->tt_isdst;
1247  result->tm_zone = (char *) &sp->chars[ttisp->tt_abbrind];
1248  }
1249  return result;
1250 }
#define AVGSECSPERYEAR
Definition: private.h:120
int64 pg_time_t
Definition: pgtime.h:23
int tm_isdst
Definition: pgtime.h:35
int32 tt_gmtoff
Definition: pgtz.h:28
Definition: pgtz.h:26
Definition: pgtime.h:25
bool tt_isdst
Definition: pgtz.h:29
const char * tm_zone
Definition: pgtime.h:37
#define NULL
Definition: c.h:229
#define YEARSPERREPEAT
Definition: private.h:112
int tm_year
Definition: pgtime.h:32
int tt_abbrind
Definition: pgtz.h:30
int i
static struct pg_tm * localsub(struct state const *sp, pg_time_t const *timep, struct pg_tm *tmp)
Definition: localtime.c:1174
#define SECSPERREPEAT
Definition: private.h:124
static struct pg_tm * timesub(pg_time_t const *, int32, struct state const *, struct pg_tm *)
Definition: localtime.c:1312
static struct pg_tm * gmtsub(pg_time_t const *, int32, struct pg_tm *)
Definition: localtime.c:1266
const char* pg_get_timezone_name ( pg_tz tz)

Definition at line 1770 of file localtime.c.

References NULL, and pg_tz::TZname.

Referenced by pg_timezone_names(), show_log_timezone(), and show_timezone().

1771 {
1772  if (tz)
1773  return tz->TZname;
1774  return NULL;
1775 }
#define NULL
Definition: c.h:229
char TZname[TZ_STRLEN_MAX+1]
Definition: pgtz.h:62
bool pg_get_timezone_offset ( const pg_tz tz,
long int *  gmtoff 
)

Definition at line 1746 of file localtime.c.

References i, pg_tz::state, ttinfo::tt_gmtoff, state::ttis, and state::typecnt.

Referenced by DecodeTimeOnly().

1747 {
1748  /*
1749  * The zone could have more than one ttinfo, if it's historically used
1750  * more than one abbreviation. We return true as long as they all have
1751  * the same gmtoff.
1752  */
1753  const struct state *sp;
1754  int i;
1755 
1756  sp = &tz->state;
1757  for (i = 1; i < sp->typecnt; i++)
1758  {
1759  if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
1760  return false;
1761  }
1762  *gmtoff = sp->ttis[0].tt_gmtoff;
1763  return true;
1764 }
int32 tt_gmtoff
Definition: pgtz.h:28
struct state state
Definition: pgtz.h:63
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
Definition: regguts.h:298
int i
int typecnt
Definition: pgtz.h:45
struct pg_tm* pg_gmtime ( const pg_time_t timep)

Definition at line 1295 of file localtime.c.

References gmtsub(), and tm.

Referenced by abstime2tm(), and GetEpochTime().

1296 {
1297  return gmtsub(timep, 0, &tm);
1298 }
static struct pg_tm tm
Definition: localtime.c:103
static struct pg_tm * gmtsub(pg_time_t const *, int32, struct pg_tm *)
Definition: localtime.c:1266
bool pg_interpret_timezone_abbrev ( const char *  abbrev,
const pg_time_t timep,
long int *  gmtoff,
int *  isdst,
const pg_tz tz 
)

Definition at line 1652 of file localtime.c.

References state::charcnt, charcnt, state::chars, i, pg_tz::state, state::timecnt, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, and state::types.

Referenced by DetermineTimeZoneAbbrevOffsetInternal().

1657 {
1658  const struct state *sp;
1659  const char *abbrs;
1660  const struct ttinfo *ttisp;
1661  int abbrind;
1662  int cutoff;
1663  int i;
1664  const pg_time_t t = *timep;
1665 
1666  sp = &tz->state;
1667 
1668  /*
1669  * Locate the abbreviation in the zone's abbreviation list. We assume
1670  * there are not duplicates in the list.
1671  */
1672  abbrs = sp->chars;
1673  abbrind = 0;
1674  while (abbrind < sp->charcnt)
1675  {
1676  if (strcmp(abbrev, abbrs + abbrind) == 0)
1677  break;
1678  while (abbrs[abbrind] != '\0')
1679  abbrind++;
1680  abbrind++;
1681  }
1682  if (abbrind >= sp->charcnt)
1683  return false; /* not there! */
1684 
1685  /*
1686  * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1687  * (goback/goahead zones). Finding the newest or oldest meaning of the
1688  * abbreviation should get us what we want, since extrapolation would just
1689  * be repeating the newest or oldest meanings.
1690  *
1691  * Use binary search to locate the first transition > cutoff time.
1692  */
1693  {
1694  int lo = 0;
1695  int hi = sp->timecnt;
1696 
1697  while (lo < hi)
1698  {
1699  int mid = (lo + hi) >> 1;
1700 
1701  if (t < sp->ats[mid])
1702  hi = mid;
1703  else
1704  lo = mid + 1;
1705  }
1706  cutoff = lo;
1707  }
1708 
1709  /*
1710  * Scan backwards to find the latest interval using the given abbrev
1711  * before the cutoff time.
1712  */
1713  for (i = cutoff - 1; i >= 0; i--)
1714  {
1715  ttisp = &sp->ttis[sp->types[i]];
1716  if (ttisp->tt_abbrind == abbrind)
1717  {
1718  *gmtoff = ttisp->tt_gmtoff;
1719  *isdst = ttisp->tt_isdst;
1720  return true;
1721  }
1722  }
1723 
1724  /*
1725  * Not there, so scan forwards to find the first one after.
1726  */
1727  for (i = cutoff; i < sp->timecnt; i++)
1728  {
1729  ttisp = &sp->ttis[sp->types[i]];
1730  if (ttisp->tt_abbrind == abbrind)
1731  {
1732  *gmtoff = ttisp->tt_gmtoff;
1733  *isdst = ttisp->tt_isdst;
1734  return true;
1735  }
1736  }
1737 
1738  return false; /* hm, not actually used in any interval? */
1739 }
int64 pg_time_t
Definition: pgtime.h:23
int charcnt
Definition: pgtz.h:46
int32 tt_gmtoff
Definition: pgtz.h:28
Definition: pgtz.h:26
bool tt_isdst
Definition: pgtz.h:29
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, 3),(2 *(TZ_STRLEN_MAX+1)))]
Definition: pgtz.h:53
struct state state
Definition: pgtz.h:63
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
Definition: regguts.h:298
int timecnt
Definition: pgtz.h:44
static int charcnt
Definition: zic.c:163
int tt_abbrind
Definition: pgtz.h:30
int i
struct pg_tm* pg_localtime ( const pg_time_t timep,
const pg_tz tz 
)

Definition at line 1254 of file localtime.c.

References localsub(), pg_tz::state, and tm.

Referenced by abstime2tm(), do_pg_start_backup(), do_pg_stop_backup(), log_line_prefix(), logfile_getname(), pg_tz_acceptable(), score_timezone(), set_next_rotation_time(), setup_formatted_log_time(), setup_formatted_start_time(), str_time(), timeofday(), timestamp2tm(), and timetz_zone().

1255 {
1256  return localsub(&tz->state, timep, &tm);
1257 }
static struct pg_tm tm
Definition: localtime.c:103
struct state state
Definition: pgtz.h:63
static struct pg_tm * localsub(struct state const *sp, pg_time_t const *timep, struct pg_tm *tmp)
Definition: localtime.c:1174
int pg_next_dst_boundary ( const pg_time_t timep,
long int *  before_gmtoff,
int *  before_isdst,
pg_time_t boundary,
long int *  after_gmtoff,
int *  after_isdst,
const pg_tz tz 
)

Definition at line 1505 of file localtime.c.

References state::ats, AVGSECSPERYEAR, state::goahead, state::goback, i, pg_tz::state, state::timecnt, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, state::typecnt, state::types, and YEARSPERREPEAT.

Referenced by DetermineTimeZoneOffsetInternal().

1512 {
1513  const struct state *sp;
1514  const struct ttinfo *ttisp;
1515  int i;
1516  int j;
1517  const pg_time_t t = *timep;
1518 
1519  sp = &tz->state;
1520  if (sp->timecnt == 0)
1521  {
1522  /* non-DST zone, use lowest-numbered standard type */
1523  i = 0;
1524  while (sp->ttis[i].tt_isdst)
1525  if (++i >= sp->typecnt)
1526  {
1527  i = 0;
1528  break;
1529  }
1530  ttisp = &sp->ttis[i];
1531  *before_gmtoff = ttisp->tt_gmtoff;
1532  *before_isdst = ttisp->tt_isdst;
1533  return 0;
1534  }
1535  if ((sp->goback && t < sp->ats[0]) ||
1536  (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1537  {
1538  /* For values outside the transition table, extrapolate */
1539  pg_time_t newt = t;
1540  pg_time_t seconds;
1541  pg_time_t tcycles;
1542  int64 icycles;
1543  int result;
1544 
1545  if (t < sp->ats[0])
1546  seconds = sp->ats[0] - t;
1547  else
1548  seconds = t - sp->ats[sp->timecnt - 1];
1549  --seconds;
1550  tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1551  ++tcycles;
1552  icycles = tcycles;
1553  if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1554  return -1;
1555  seconds = icycles;
1556  seconds *= YEARSPERREPEAT;
1557  seconds *= AVGSECSPERYEAR;
1558  if (t < sp->ats[0])
1559  newt += seconds;
1560  else
1561  newt -= seconds;
1562  if (newt < sp->ats[0] ||
1563  newt > sp->ats[sp->timecnt - 1])
1564  return -1; /* "cannot happen" */
1565 
1566  result = pg_next_dst_boundary(&newt, before_gmtoff,
1567  before_isdst,
1568  boundary,
1569  after_gmtoff,
1570  after_isdst,
1571  tz);
1572  if (t < sp->ats[0])
1573  *boundary -= seconds;
1574  else
1575  *boundary += seconds;
1576  return result;
1577  }
1578 
1579  if (t >= sp->ats[sp->timecnt - 1])
1580  {
1581  /* No known transition > t, so use last known segment's type */
1582  i = sp->types[sp->timecnt - 1];
1583  ttisp = &sp->ttis[i];
1584  *before_gmtoff = ttisp->tt_gmtoff;
1585  *before_isdst = ttisp->tt_isdst;
1586  return 0;
1587  }
1588  if (t < sp->ats[0])
1589  {
1590  /* For "before", use lowest-numbered standard type */
1591  i = 0;
1592  while (sp->ttis[i].tt_isdst)
1593  if (++i >= sp->typecnt)
1594  {
1595  i = 0;
1596  break;
1597  }
1598  ttisp = &sp->ttis[i];
1599  *before_gmtoff = ttisp->tt_gmtoff;
1600  *before_isdst = ttisp->tt_isdst;
1601  *boundary = sp->ats[0];
1602  /* And for "after", use the first segment's type */
1603  i = sp->types[0];
1604  ttisp = &sp->ttis[i];
1605  *after_gmtoff = ttisp->tt_gmtoff;
1606  *after_isdst = ttisp->tt_isdst;
1607  return 1;
1608  }
1609  /* Else search to find the boundary following t */
1610  {
1611  int lo = 1;
1612  int hi = sp->timecnt - 1;
1613 
1614  while (lo < hi)
1615  {
1616  int mid = (lo + hi) >> 1;
1617 
1618  if (t < sp->ats[mid])
1619  hi = mid;
1620  else
1621  lo = mid + 1;
1622  }
1623  i = lo;
1624  }
1625  j = sp->types[i - 1];
1626  ttisp = &sp->ttis[j];
1627  *before_gmtoff = ttisp->tt_gmtoff;
1628  *before_isdst = ttisp->tt_isdst;
1629  *boundary = sp->ats[i];
1630  j = sp->types[i];
1631  ttisp = &sp->ttis[j];
1632  *after_gmtoff = ttisp->tt_gmtoff;
1633  *after_isdst = ttisp->tt_isdst;
1634  return 1;
1635 }
#define AVGSECSPERYEAR
Definition: private.h:120
int64 pg_time_t
Definition: pgtime.h:23
bool goback
Definition: pgtz.h:47
int32 tt_gmtoff
Definition: pgtz.h:28
Definition: pgtz.h:26
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
bool tt_isdst
Definition: pgtz.h:29
struct state state
Definition: pgtz.h:63
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
int pg_next_dst_boundary(const pg_time_t *timep, long int *before_gmtoff, int *before_isdst, pg_time_t *boundary, long int *after_gmtoff, int *after_isdst, const pg_tz *tz)
Definition: localtime.c:1505
Definition: regguts.h:298
int timecnt
Definition: pgtz.h:44
#define YEARSPERREPEAT
Definition: private.h:112
int i
bool goahead
Definition: pgtz.h:48
int typecnt
Definition: pgtz.h:45
bool pg_tz_acceptable ( pg_tz tz)

Definition at line 1785 of file localtime.c.

References pg_localtime(), POSTGRES_EPOCH_JDATE, SECS_PER_DAY, pg_tm::tm_sec, and UNIX_EPOCH_JDATE.

Referenced by check_log_timezone(), check_timezone(), pg_tzenumerate_next(), score_timezone(), and validate_zone().

1786 {
1787  struct pg_tm *tt;
1788  pg_time_t time2000;
1789 
1790  /*
1791  * To detect leap-second timekeeping, run pg_localtime for what should be
1792  * GMT midnight, 2000-01-01. Insist that the tm_sec value be zero; any
1793  * other result has to be due to leap seconds.
1794  */
1796  tt = pg_localtime(&time2000, tz);
1797  if (!tt || tt->tm_sec != 0)
1798  return false;
1799 
1800  return true;
1801 }
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1254
int64 pg_time_t
Definition: pgtime.h:23
Definition: pgtime.h:25
#define SECS_PER_DAY
Definition: timestamp.h:86
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:162
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
int tm_sec
Definition: pgtime.h:27
static struct pg_tm * timesub ( pg_time_t const *  timep,
int32  offset,
struct state const *  sp,
struct pg_tm tmp 
)
static

Definition at line 1312 of file localtime.c.

References corr, DAYSPERLYEAR, DAYSPERNYEAR, DAYSPERWEEK, EOVERFLOW, EPOCH_WDAY, EPOCH_YEAR, i, increment_overflow(), isleap, state::leapcnt, leaps_thru_end_of(), lsinfo::ls_corr, lsinfo::ls_trans, state::lsis, NULL, SECSPERDAY, SECSPERHOUR, SECSPERMIN, pg_tm::tm_gmtoff, pg_tm::tm_hour, pg_tm::tm_isdst, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_wday, pg_tm::tm_yday, pg_tm::tm_year, TM_YEAR_BASE, and TYPE_SIGNED.

Referenced by gmtsub(), and localsub().

1314 {
1315  const struct lsinfo *lp;
1316  pg_time_t tdays;
1317  int idays; /* unsigned would be so 2003 */
1318  int64 rem;
1319  int y;
1320  const int *ip;
1321  int64 corr;
1322  bool hit;
1323  int i;
1324 
1325  corr = 0;
1326  hit = false;
1327  i = (sp == NULL) ? 0 : sp->leapcnt;
1328  while (--i >= 0)
1329  {
1330  lp = &sp->lsis[i];
1331  if (*timep >= lp->ls_trans)
1332  {
1333  if (*timep == lp->ls_trans)
1334  {
1335  hit = ((i == 0 && lp->ls_corr > 0) ||
1336  lp->ls_corr > sp->lsis[i - 1].ls_corr);
1337  if (hit)
1338  while (i > 0 &&
1339  sp->lsis[i].ls_trans ==
1340  sp->lsis[i - 1].ls_trans + 1 &&
1341  sp->lsis[i].ls_corr ==
1342  sp->lsis[i - 1].ls_corr + 1)
1343  {
1344  ++hit;
1345  --i;
1346  }
1347  }
1348  corr = lp->ls_corr;
1349  break;
1350  }
1351  }
1352  y = EPOCH_YEAR;
1353  tdays = *timep / SECSPERDAY;
1354  rem = *timep % SECSPERDAY;
1355  while (tdays < 0 || tdays >= year_lengths[isleap(y)])
1356  {
1357  int newy;
1358  pg_time_t tdelta;
1359  int idelta;
1360  int leapdays;
1361 
1362  tdelta = tdays / DAYSPERLYEAR;
1363  if (!((!TYPE_SIGNED(pg_time_t) ||INT_MIN <= tdelta)
1364  && tdelta <= INT_MAX))
1365  goto out_of_range;
1366  idelta = tdelta;
1367  if (idelta == 0)
1368  idelta = (tdays < 0) ? -1 : 1;
1369  newy = y;
1370  if (increment_overflow(&newy, idelta))
1371  goto out_of_range;
1372  leapdays = leaps_thru_end_of(newy - 1) -
1373  leaps_thru_end_of(y - 1);
1374  tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1375  tdays -= leapdays;
1376  y = newy;
1377  }
1378 
1379  /*
1380  * Given the range, we can now fearlessly cast...
1381  */
1382  idays = tdays;
1383  rem += offset - corr;
1384  while (rem < 0)
1385  {
1386  rem += SECSPERDAY;
1387  --idays;
1388  }
1389  while (rem >= SECSPERDAY)
1390  {
1391  rem -= SECSPERDAY;
1392  ++idays;
1393  }
1394  while (idays < 0)
1395  {
1396  if (increment_overflow(&y, -1))
1397  goto out_of_range;
1398  idays += year_lengths[isleap(y)];
1399  }
1400  while (idays >= year_lengths[isleap(y)])
1401  {
1402  idays -= year_lengths[isleap(y)];
1403  if (increment_overflow(&y, 1))
1404  goto out_of_range;
1405  }
1406  tmp->tm_year = y;
1408  goto out_of_range;
1409  tmp->tm_yday = idays;
1410 
1411  /*
1412  * The "extra" mods below avoid overflow problems.
1413  */
1414  tmp->tm_wday = EPOCH_WDAY +
1415  ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1417  leaps_thru_end_of(y - 1) -
1419  idays;
1420  tmp->tm_wday %= DAYSPERWEEK;
1421  if (tmp->tm_wday < 0)
1422  tmp->tm_wday += DAYSPERWEEK;
1423  tmp->tm_hour = (int) (rem / SECSPERHOUR);
1424  rem %= SECSPERHOUR;
1425  tmp->tm_min = (int) (rem / SECSPERMIN);
1426 
1427  /*
1428  * A positive leap second requires a special representation. This uses
1429  * "... ??:59:60" et seq.
1430  */
1431  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1432  ip = mon_lengths[isleap(y)];
1433  for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1434  idays -= ip[tmp->tm_mon];
1435  tmp->tm_mday = (int) (idays + 1);
1436  tmp->tm_isdst = 0;
1437  tmp->tm_gmtoff = offset;
1438  return tmp;
1439 
1440 out_of_range:
1441  errno = EOVERFLOW;
1442  return NULL;
1443 }
#define DAYSPERLYEAR
Definition: tzfile.h:108
int64 pg_time_t
Definition: pgtime.h:23
int tm_wday
Definition: pgtime.h:33
#define DAYSPERNYEAR
Definition: tzfile.h:107
int tm_isdst
Definition: pgtime.h:35
int tm_hour
Definition: pgtime.h:29
#define EPOCH_WDAY
Definition: tzfile.h:137
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:383
#define isleap(y)
Definition: datetime.h:273
static const int mon_lengths[2][MONSPERYEAR]
Definition: localtime.c:576
long int tm_gmtoff
Definition: pgtime.h:36
#define SECSPERDAY
Definition: tzfile.h:110
int64 ls_corr
Definition: pgtz.h:38
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
pg_time_t ls_trans
Definition: pgtz.h:37
#define TM_YEAR_BASE
Definition: tzfile.h:134
#define DAYSPERWEEK
Definition: tzfile.h:106
#define NULL
Definition: c.h:229
Definition: pgtz.h:35
static int leaps_thru_end_of(const int y)
Definition: localtime.c:1305
#define SECSPERMIN
Definition: tzfile.h:103
static const int year_lengths[2]
Definition: localtime.c:581
static bool increment_overflow(int *, int)
Definition: localtime.c:1450
int tm_year
Definition: pgtime.h:32
int i
#define EPOCH_YEAR
Definition: tzfile.h:136
int tm_yday
Definition: pgtime.h:34
#define TYPE_SIGNED(type)
Definition: private.h:75
int tm_sec
Definition: pgtime.h:27
#define EOVERFLOW
Definition: private.h:38
#define SECSPERHOUR
Definition: tzfile.h:109
int tm_min
Definition: pgtime.h:28
static int32 transtime ( int  year,
const struct rule rulep,
int32  offset 
)
static

Definition at line 781 of file localtime.c.

References DAY_OF_YEAR, DAYSPERWEEK, i, INITIALIZE, isleap, JULIAN_DAY, MONTH_NTH_DAY_OF_WEEK, rule::r_day, rule::r_mon, rule::r_time, rule::r_type, rule::r_week, SECSPERDAY, and value.

Referenced by tzparse().

783 {
784  bool leapyear;
785  int32 value;
786  int i,
787  d,
788  m1,
789  yy0,
790  yy1,
791  yy2,
792  dow;
793 
794  INITIALIZE(value);
795  leapyear = isleap(year);
796  switch (rulep->r_type)
797  {
798 
799  case JULIAN_DAY:
800 
801  /*
802  * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
803  * years. In non-leap years, or if the day number is 59 or less,
804  * just add SECSPERDAY times the day number-1 to the time of
805  * January 1, midnight, to get the day.
806  */
807  value = (rulep->r_day - 1) * SECSPERDAY;
808  if (leapyear && rulep->r_day >= 60)
809  value += SECSPERDAY;
810  break;
811 
812  case DAY_OF_YEAR:
813 
814  /*
815  * n - day of year. Just add SECSPERDAY times the day number to
816  * the time of January 1, midnight, to get the day.
817  */
818  value = rulep->r_day * SECSPERDAY;
819  break;
820 
822 
823  /*
824  * Mm.n.d - nth "dth day" of month m.
825  */
826 
827  /*
828  * Use Zeller's Congruence to get day-of-week of first day of
829  * month.
830  */
831  m1 = (rulep->r_mon + 9) % 12 + 1;
832  yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
833  yy1 = yy0 / 100;
834  yy2 = yy0 % 100;
835  dow = ((26 * m1 - 2) / 10 +
836  1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
837  if (dow < 0)
838  dow += DAYSPERWEEK;
839 
840  /*
841  * "dow" is the day-of-week of the first day of the month. Get the
842  * day-of-month (zero-origin) of the first "dow" day of the month.
843  */
844  d = rulep->r_day - dow;
845  if (d < 0)
846  d += DAYSPERWEEK;
847  for (i = 1; i < rulep->r_week; ++i)
848  {
849  if (d + DAYSPERWEEK >=
850  mon_lengths[(int) leapyear][rulep->r_mon - 1])
851  break;
852  d += DAYSPERWEEK;
853  }
854 
855  /*
856  * "d" is the day-of-month (zero-origin) of the day we want.
857  */
858  value = d * SECSPERDAY;
859  for (i = 0; i < rulep->r_mon - 1; ++i)
860  value += mon_lengths[(int) leapyear][i] * SECSPERDAY;
861  break;
862  }
863 
864  /*
865  * "value" is the year-relative time of 00:00:00 UT on the day in
866  * question. To get the year-relative time of the specified local time on
867  * that day, add the transition time and the current offset from UT.
868  */
869  return value + rulep->r_time + offset;
870 }
static struct @76 value
#define isleap(y)
Definition: datetime.h:273
#define INITIALIZE(x)
Definition: private.h:106
static const int mon_lengths[2][MONSPERYEAR]
Definition: localtime.c:576
int r_mon
Definition: localtime.c:79
signed int int32
Definition: c.h:256
int r_week
Definition: localtime.c:78
#define SECSPERDAY
Definition: tzfile.h:110
enum r_type r_type
Definition: localtime.c:76
int32 r_time
Definition: localtime.c:80
int r_day
Definition: localtime.c:77
#define DAYSPERWEEK
Definition: tzfile.h:106
int i
static bool typesequiv ( struct state const *  sp,
int  a,
int  b 
)
static

Definition at line 553 of file localtime.c.

References state::chars, NULL, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, ttinfo::tt_ttisstd, state::ttis, and state::typecnt.

Referenced by tzloadbody().

554 {
555  bool result;
556 
557  if (sp == NULL ||
558  a < 0 || a >= sp->typecnt ||
559  b < 0 || b >= sp->typecnt)
560  result = false;
561  else
562  {
563  const struct ttinfo *ap = &sp->ttis[a];
564  const struct ttinfo *bp = &sp->ttis[b];
565 
566  result = ap->tt_gmtoff == bp->tt_gmtoff &&
567  ap->tt_isdst == bp->tt_isdst &&
568  ap->tt_ttisstd == bp->tt_ttisstd &&
569  ap->tt_ttisgmt == bp->tt_ttisgmt &&
570  strcmp(&sp->chars[ap->tt_abbrind],
571  &sp->chars[bp->tt_abbrind]) == 0;
572  }
573  return result;
574 }
int32 tt_gmtoff
Definition: pgtz.h:28
Definition: pgtz.h:26
bool tt_isdst
Definition: pgtz.h:29
#define NULL
Definition: c.h:229
bool tt_ttisstd
Definition: pgtz.h:31
int tt_abbrind
Definition: pgtz.h:30
bool tt_ttisgmt
Definition: pgtz.h:32
int tzload ( const char *  name,
char *  canonname,
struct state sp,
bool  doextend 
)

Definition at line 537 of file localtime.c.

References free, malloc, and tzloadbody().

Referenced by gmtload(), pg_load_tz(), pg_tzenumerate_next(), pg_tzset(), and tzparse().

538 {
539  union local_storage *lsp = malloc(sizeof *lsp);
540 
541  if (!lsp)
542  return errno;
543  else
544  {
545  int err = tzloadbody(name, canonname, sp, doextend, lsp);
546 
547  free(lsp);
548  return err;
549  }
550 }
static int tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, union local_storage *lsp)
Definition: localtime.c:210
#define malloc(a)
Definition: header.h:50
#define free(a)
Definition: header.h:65
const char * name
Definition: encode.c:521
static int tzloadbody ( char const *  name,
char *  canonname,
struct state sp,
bool  doextend,
union local_storage lsp 
)
static

Definition at line 210 of file localtime.c.

References state::ats, input_buffer::buf, state::charcnt, charcnt, state::chars, close, corr, state::defaulttype, detzcode(), detzcode64(), differ_by_repeat(), state::goahead, state::goback, i, state::leapcnt, leapcnt, lsinfo::ls_corr, lsinfo::ls_trans, state::lsis, memmove, name, pg_open_tzfile(), read, time_t_max, time_t_min, state::timecnt, timecnt, trans, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, ttinfo::tt_ttisstd, state::ttis, TYPE_SIGNED, state::typecnt, typecnt, state::types, typesequiv(), TZ_MAX_CHARS, TZ_MAX_LEAPS, TZ_MAX_TIMES, TZ_MAX_TYPES, TZDEFAULT, tzhead::tzh_charcnt, tzhead::tzh_leapcnt, tzhead::tzh_timecnt, tzhead::tzh_ttisgmtcnt, tzhead::tzh_ttisstdcnt, tzhead::tzh_typecnt, tzhead::tzh_version, input_buffer::tzhead, tzparse(), and local_storage::u.

Referenced by tzload().

212 {
213  int i;
214  int fid;
215  int stored;
216  ssize_t nread;
217  union input_buffer *up = &lsp->u.u;
218  int tzheadsize = sizeof(struct tzhead);
219 
220  sp->goback = sp->goahead = false;
221 
222  if (!name)
223  {
224  name = TZDEFAULT;
225  if (!name)
226  return EINVAL;
227  }
228 
229  if (name[0] == ':')
230  ++name;
231 
232  fid = pg_open_tzfile(name, canonname);
233  if (fid < 0)
234  return ENOENT; /* pg_open_tzfile may not set errno */
235 
236  nread = read(fid, up->buf, sizeof up->buf);
237  if (nread < tzheadsize)
238  {
239  int err = nread < 0 ? errno : EINVAL;
240 
241  close(fid);
242  return err;
243  }
244  if (close(fid) < 0)
245  return errno;
246  for (stored = 4; stored <= 8; stored *= 2)
247  {
248  int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
249  int32 ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
254  char const *p = up->buf + tzheadsize;
255 
256  if (!(0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
257  && 0 < typecnt && typecnt < TZ_MAX_TYPES
258  && 0 <= timecnt && timecnt < TZ_MAX_TIMES
259  && 0 <= charcnt && charcnt < TZ_MAX_CHARS
260  && (ttisstdcnt == typecnt || ttisstdcnt == 0)
261  && (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
262  return EINVAL;
263  if (nread
264  < (tzheadsize /* struct tzhead */
265  + timecnt * stored /* ats */
266  + timecnt /* types */
267  + typecnt * 6 /* ttinfos */
268  + charcnt /* chars */
269  + leapcnt * (stored + 4) /* lsinfos */
270  + ttisstdcnt /* ttisstds */
271  + ttisgmtcnt)) /* ttisgmts */
272  return EINVAL;
273  sp->leapcnt = leapcnt;
274  sp->timecnt = timecnt;
275  sp->typecnt = typecnt;
276  sp->charcnt = charcnt;
277 
278  /*
279  * Read transitions, discarding those out of pg_time_t range. But
280  * pretend the last transition before time_t_min occurred at
281  * time_t_min.
282  */
283  timecnt = 0;
284  for (i = 0; i < sp->timecnt; ++i)
285  {
286  int64 at
287  = stored == 4 ? detzcode(p) : detzcode64(p);
288 
289  sp->types[i] = at <= time_t_max;
290  if (sp->types[i])
291  {
292  pg_time_t attime
293  = ((TYPE_SIGNED(pg_time_t) ? at < time_t_min : at < 0)
294  ? time_t_min : at);
295 
296  if (timecnt && attime <= sp->ats[timecnt - 1])
297  {
298  if (attime < sp->ats[timecnt - 1])
299  return EINVAL;
300  sp->types[i - 1] = 0;
301  timecnt--;
302  }
303  sp->ats[timecnt++] = attime;
304  }
305  p += stored;
306  }
307 
308  timecnt = 0;
309  for (i = 0; i < sp->timecnt; ++i)
310  {
311  unsigned char typ = *p++;
312 
313  if (sp->typecnt <= typ)
314  return EINVAL;
315  if (sp->types[i])
316  sp->types[timecnt++] = typ;
317  }
318  sp->timecnt = timecnt;
319  for (i = 0; i < sp->typecnt; ++i)
320  {
321  struct ttinfo *ttisp;
322  unsigned char isdst,
323  abbrind;
324 
325  ttisp = &sp->ttis[i];
326  ttisp->tt_gmtoff = detzcode(p);
327  p += 4;
328  isdst = *p++;
329  if (!(isdst < 2))
330  return EINVAL;
331  ttisp->tt_isdst = isdst;
332  abbrind = *p++;
333  if (!(abbrind < sp->charcnt))
334  return EINVAL;
335  ttisp->tt_abbrind = abbrind;
336  }
337  for (i = 0; i < sp->charcnt; ++i)
338  sp->chars[i] = *p++;
339  sp->chars[i] = '\0'; /* ensure '\0' at end */
340 
341  /* Read leap seconds, discarding those out of pg_time_t range. */
342  leapcnt = 0;
343  for (i = 0; i < sp->leapcnt; ++i)
344  {
345  int64 tr = stored == 4 ? detzcode(p) : detzcode64(p);
346  int32 corr = detzcode(p + stored);
347 
348  p += stored + 4;
349  if (tr <= time_t_max)
350  {
352  = ((TYPE_SIGNED(pg_time_t) ? tr < time_t_min : tr < 0)
353  ? time_t_min : tr);
354 
355  if (leapcnt && trans <= sp->lsis[leapcnt - 1].ls_trans)
356  {
357  if (trans < sp->lsis[leapcnt - 1].ls_trans)
358  return EINVAL;
359  leapcnt--;
360  }
361  sp->lsis[leapcnt].ls_trans = trans;
362  sp->lsis[leapcnt].ls_corr = corr;
363  leapcnt++;
364  }
365  }
366  sp->leapcnt = leapcnt;
367 
368  for (i = 0; i < sp->typecnt; ++i)
369  {
370  struct ttinfo *ttisp;
371 
372  ttisp = &sp->ttis[i];
373  if (ttisstdcnt == 0)
374  ttisp->tt_ttisstd = false;
375  else
376  {
377  if (*p != true && *p != false)
378  return EINVAL;
379  ttisp->tt_ttisstd = *p++;
380  }
381  }
382  for (i = 0; i < sp->typecnt; ++i)
383  {
384  struct ttinfo *ttisp;
385 
386  ttisp = &sp->ttis[i];
387  if (ttisgmtcnt == 0)
388  ttisp->tt_ttisgmt = false;
389  else
390  {
391  if (*p != true && *p != false)
392  return EINVAL;
393  ttisp->tt_ttisgmt = *p++;
394  }
395  }
396 
397  /*
398  * If this is an old file, we're done.
399  */
400  if (up->tzhead.tzh_version[0] == '\0')
401  break;
402  nread -= p - up->buf;
403  memmove(up->buf, p, nread);
404  }
405  if (doextend && nread > 2 &&
406  up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
407  sp->typecnt + 2 <= TZ_MAX_TYPES)
408  {
409  struct state *ts = &lsp->u.st;
410 
411  up->buf[nread - 1] = '\0';
412  if (tzparse(&up->buf[1], ts, false)
413  && ts->typecnt == 2)
414  {
415  /*
416  * Attempt to reuse existing abbreviations. Without this,
417  * America/Anchorage would stop working after 2037 when
418  * TZ_MAX_CHARS is 50, as sp->charcnt equals 42 (for LMT CAT CAWT
419  * CAPT AHST AHDT YST AKDT AKST) and ts->charcnt equals 10 (for
420  * AKST AKDT). Reusing means sp->charcnt can stay 42 in this
421  * example.
422  */
423  int gotabbr = 0;
424  int charcnt = sp->charcnt;
425 
426  for (i = 0; i < 2; i++)
427  {
428  char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
429  int j;
430 
431  for (j = 0; j < charcnt; j++)
432  if (strcmp(sp->chars + j, tsabbr) == 0)
433  {
434  ts->ttis[i].tt_abbrind = j;
435  gotabbr++;
436  break;
437  }
438  if (!(j < charcnt))
439  {
440  int tsabbrlen = strlen(tsabbr);
441 
442  if (j + tsabbrlen < TZ_MAX_CHARS)
443  {
444  strcpy(sp->chars + j, tsabbr);
445  charcnt = j + tsabbrlen + 1;
446  ts->ttis[i].tt_abbrind = j;
447  gotabbr++;
448  }
449  }
450  }
451  if (gotabbr == 2)
452  {
453  sp->charcnt = charcnt;
454  for (i = 0; i < ts->timecnt; i++)
455  if (sp->ats[sp->timecnt - 1] < ts->ats[i])
456  break;
457  while (i < ts->timecnt
458  && sp->timecnt < TZ_MAX_TIMES)
459  {
460  sp->ats[sp->timecnt] = ts->ats[i];
461  sp->types[sp->timecnt] = (sp->typecnt
462  + ts->types[i]);
463  sp->timecnt++;
464  i++;
465  }
466  sp->ttis[sp->typecnt++] = ts->ttis[0];
467  sp->ttis[sp->typecnt++] = ts->ttis[1];
468  }
469  }
470  }
471  if (sp->timecnt > 1)
472  {
473  for (i = 1; i < sp->timecnt; ++i)
474  if (typesequiv(sp, sp->types[i], sp->types[0]) &&
475  differ_by_repeat(sp->ats[i], sp->ats[0]))
476  {
477  sp->goback = true;
478  break;
479  }
480  for (i = sp->timecnt - 2; i >= 0; --i)
481  if (typesequiv(sp, sp->types[sp->timecnt - 1],
482  sp->types[i]) &&
483  differ_by_repeat(sp->ats[sp->timecnt - 1],
484  sp->ats[i]))
485  {
486  sp->goahead = true;
487  break;
488  }
489  }
490 
491  /*
492  * If type 0 is unused in transitions, it's the type to use for early
493  * times.
494  */
495  for (i = 0; i < sp->timecnt; ++i)
496  if (sp->types[i] == 0)
497  break;
498  i = i < sp->timecnt ? -1 : 0;
499 
500  /*
501  * Absent the above, if there are transition times and the first
502  * transition is to a daylight time find the standard type less than and
503  * closest to the type of the first transition.
504  */
505  if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst)
506  {
507  i = sp->types[0];
508  while (--i >= 0)
509  if (!sp->ttis[i].tt_isdst)
510  break;
511  }
512 
513  /*
514  * If no result yet, find the first standard type. If there is none, punt
515  * to type zero.
516  */
517  if (i < 0)
518  {
519  i = 0;
520  while (sp->ttis[i].tt_isdst)
521  if (++i >= sp->typecnt)
522  {
523  i = 0;
524  break;
525  }
526  }
527  sp->defaulttype = i;
528  return 0;
529 }
#define TZDEFAULT
Definition: tzfile.h:24
static int typecnt
Definition: zic.c:184
int64 pg_time_t
Definition: pgtime.h:23
int charcnt
Definition: pgtz.h:46
static int32 detzcode(const char *codep)
Definition: localtime.c:117
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:383
bool goback
Definition: pgtz.h:47
int32 tt_gmtoff
Definition: pgtz.h:28
int leapcnt
Definition: pgtz.h:43
Definition: pgtz.h:26
#define TZ_MAX_TIMES
Definition: tzfile.h:93
struct tzhead tzhead
Definition: localtime.c:180
char tzh_timecnt[4]
Definition: tzfile.h:41
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
signed int int32
Definition: c.h:256
#define TZ_MAX_LEAPS
Definition: tzfile.h:101
bool tt_isdst
Definition: pgtz.h:29
struct lsinfo lsis[TZ_MAX_LEAPS]
Definition: pgtz.h:54
static int64 detzcode64(const char *codep)
Definition: localtime.c:143
static const pg_time_t time_t_max
Definition: localtime.c:54
int64 ls_corr
Definition: pgtz.h:38
#define memmove(d, s, c)
Definition: c.h:1058
static const pg_time_t time_t_min
Definition: localtime.c:53
static int leapcnt
Definition: zic.c:167
pg_time_t ls_trans
Definition: pgtz.h:37
char tzh_leapcnt[4]
Definition: tzfile.h:40
static bool typesequiv(struct state const *, int, int)
Definition: localtime.c:553
bool tzparse(const char *name, struct state *sp, bool lastditch)
Definition: localtime.c:878
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, 3),(2 *(TZ_STRLEN_MAX+1)))]
Definition: pgtz.h:53
#define TZ_MAX_CHARS
Definition: tzfile.h:98
char buf[2 *sizeof(struct tzhead)+2 *sizeof(struct state)+4 *TZ_MAX_TIMES]
Definition: localtime.c:184
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
Definition: tzfile.h:33
char tzh_typecnt[4]
Definition: tzfile.h:42
char tzh_version[1]
Definition: tzfile.h:36
char tzh_charcnt[4]
Definition: tzfile.h:43
Definition: regguts.h:298
static ptrdiff_t timecnt
Definition: zic.c:182
int timecnt
Definition: pgtz.h:44
static int charcnt
Definition: zic.c:163
bool tt_ttisstd
Definition: pgtz.h:31
const char * name
Definition: encode.c:521
union input_buffer u
Definition: localtime.c:196
static zic_t trans[TZ_MAX_LEAPS]
Definition: zic.c:382
#define TZ_MAX_TYPES
Definition: tzfile.h:96
int tt_abbrind
Definition: pgtz.h:30
char tzh_ttisstdcnt[4]
Definition: tzfile.h:39
int i
int pg_open_tzfile(const char *name, char *canonname)
Definition: findtimezone.c:64
bool tt_ttisgmt
Definition: pgtz.h:32
bool goahead
Definition: pgtz.h:48
#define TYPE_SIGNED(type)
Definition: private.h:75
#define close(a)
Definition: win32.h:17
int typecnt
Definition: pgtz.h:45
#define read(a, b, c)
Definition: win32.h:18
static bool differ_by_repeat(const pg_time_t t1, const pg_time_t t0)
Definition: localtime.c:169
int defaulttype
Definition: pgtz.h:55
char tzh_ttisgmtcnt[4]
Definition: tzfile.h:38
bool tzparse ( const char *  name,
struct state sp,
bool  lastditch 
)

Definition at line 878 of file localtime.c.

References state::ats, state::charcnt, charcnt, state::chars, state::defaulttype, EPOCH_YEAR, getoffset(), getqzname(), getrule(), getzname(), state::goahead, state::goback, i, increment_overflow_time(), init_ttinfo(), isleap, state::leapcnt, name, NULL, SECSPERDAY, SECSPERHOUR, swap, state::timecnt, timecnt, transtime(), ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, ttinfo::tt_ttisstd, state::ttis, state::typecnt, state::types, TZ_MAX_TIMES, TZDEFRULES, TZDEFRULESTRING, tzload(), and YEARSPERREPEAT.

Referenced by gmtload(), pg_load_tz(), pg_tzset(), and tzloadbody().

879 {
880  const char *stdname;
881  const char *dstname = NULL;
882  size_t stdlen;
883  size_t dstlen;
884  size_t charcnt;
885  int32 stdoffset;
886  int32 dstoffset;
887  char *cp;
888  bool load_ok;
889 
890  stdname = name;
891  if (lastditch)
892  {
893  /*
894  * This is intentionally somewhat different from the IANA code. We do
895  * not want to invoke tzload() in the lastditch case: we can't assume
896  * pg_open_tzfile() is sane yet, and we don't care about leap seconds
897  * anyway.
898  */
899  stdlen = strlen(name); /* length of standard zone name */
900  name += stdlen;
901  if (stdlen >= sizeof sp->chars)
902  stdlen = (sizeof sp->chars) - 1;
903  charcnt = stdlen + 1;
904  stdoffset = 0;
905  sp->goback = sp->goahead = false; /* simulate failed tzload() */
906  load_ok = false;
907  }
908  else
909  {
910  if (*name == '<')
911  {
912  name++;
913  stdname = name;
914  name = getqzname(name, '>');
915  if (*name != '>')
916  return false;
917  stdlen = name - stdname;
918  name++;
919  }
920  else
921  {
922  name = getzname(name);
923  stdlen = name - stdname;
924  }
925  if (*name == '\0') /* we allow empty STD abbrev, unlike IANA */
926  return false;
927  name = getoffset(name, &stdoffset);
928  if (name == NULL)
929  return false;
930  charcnt = stdlen + 1;
931  if (sizeof sp->chars < charcnt)
932  return false;
933  load_ok = tzload(TZDEFRULES, NULL, sp, false) == 0;
934  }
935  if (!load_ok)
936  sp->leapcnt = 0; /* so, we're off a little */
937  if (*name != '\0')
938  {
939  if (*name == '<')
940  {
941  dstname = ++name;
942  name = getqzname(name, '>');
943  if (*name != '>')
944  return false;
945  dstlen = name - dstname;
946  name++;
947  }
948  else
949  {
950  dstname = name;
951  name = getzname(name);
952  dstlen = name - dstname; /* length of DST zone name */
953  }
954  if (!dstlen)
955  return false;
956  charcnt += dstlen + 1;
957  if (sizeof sp->chars < charcnt)
958  return false;
959  if (*name != '\0' && *name != ',' && *name != ';')
960  {
961  name = getoffset(name, &dstoffset);
962  if (name == NULL)
963  return false;
964  }
965  else
966  dstoffset = stdoffset - SECSPERHOUR;
967  if (*name == '\0' && !load_ok)
969  if (*name == ',' || *name == ';')
970  {
971  struct rule start;
972  struct rule end;
973  int year;
974  int yearlim;
975  int timecnt;
976  pg_time_t janfirst;
977 
978  ++name;
979  if ((name = getrule(name, &start)) == NULL)
980  return false;
981  if (*name++ != ',')
982  return false;
983  if ((name = getrule(name, &end)) == NULL)
984  return false;
985  if (*name != '\0')
986  return false;
987  sp->typecnt = 2; /* standard time and DST */
988 
989  /*
990  * Two transitions per year, from EPOCH_YEAR forward.
991  */
992  init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
993  init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
994  sp->defaulttype = 0;
995  timecnt = 0;
996  janfirst = 0;
997  yearlim = EPOCH_YEAR + YEARSPERREPEAT;
998  for (year = EPOCH_YEAR; year < yearlim; year++)
999  {
1000  int32
1001  starttime = transtime(year, &start, stdoffset),
1002  endtime = transtime(year, &end, dstoffset);
1003  int32
1004  yearsecs = (year_lengths[isleap(year)]
1005  * SECSPERDAY);
1006  bool reversed = endtime < starttime;
1007 
1008  if (reversed)
1009  {
1010  int32 swap = starttime;
1011 
1012  starttime = endtime;
1013  endtime = swap;
1014  }
1015  if (reversed
1016  || (starttime < endtime
1017  && (endtime - starttime
1018  < (yearsecs
1019  + (stdoffset - dstoffset)))))
1020  {
1021  if (TZ_MAX_TIMES - 2 < timecnt)
1022  break;
1023  yearlim = year + YEARSPERREPEAT + 1;
1024  sp->ats[timecnt] = janfirst;
1026  (&sp->ats[timecnt], starttime))
1027  break;
1028  sp->types[timecnt++] = reversed;
1029  sp->ats[timecnt] = janfirst;
1031  (&sp->ats[timecnt], endtime))
1032  break;
1033  sp->types[timecnt++] = !reversed;
1034  }
1035  if (increment_overflow_time(&janfirst, yearsecs))
1036  break;
1037  }
1038  sp->timecnt = timecnt;
1039  if (!timecnt)
1040  sp->typecnt = 1; /* Perpetual DST. */
1041  }
1042  else
1043  {
1044  int32 theirstdoffset;
1045  int32 theirdstoffset;
1046  int32 theiroffset;
1047  bool isdst;
1048  int i;
1049  int j;
1050 
1051  if (*name != '\0')
1052  return false;
1053 
1054  /*
1055  * Initial values of theirstdoffset and theirdstoffset.
1056  */
1057  theirstdoffset = 0;
1058  for (i = 0; i < sp->timecnt; ++i)
1059  {
1060  j = sp->types[i];
1061  if (!sp->ttis[j].tt_isdst)
1062  {
1063  theirstdoffset =
1064  -sp->ttis[j].tt_gmtoff;
1065  break;
1066  }
1067  }
1068  theirdstoffset = 0;
1069  for (i = 0; i < sp->timecnt; ++i)
1070  {
1071  j = sp->types[i];
1072  if (sp->ttis[j].tt_isdst)
1073  {
1074  theirdstoffset =
1075  -sp->ttis[j].tt_gmtoff;
1076  break;
1077  }
1078  }
1079 
1080  /*
1081  * Initially we're assumed to be in standard time.
1082  */
1083  isdst = false;
1084  theiroffset = theirstdoffset;
1085 
1086  /*
1087  * Now juggle transition times and types tracking offsets as you
1088  * do.
1089  */
1090  for (i = 0; i < sp->timecnt; ++i)
1091  {
1092  j = sp->types[i];
1093  sp->types[i] = sp->ttis[j].tt_isdst;
1094  if (sp->ttis[j].tt_ttisgmt)
1095  {
1096  /* No adjustment to transition time */
1097  }
1098  else
1099  {
1100  /*
1101  * If summer time is in effect, and the transition time
1102  * was not specified as standard time, add the summer time
1103  * offset to the transition time; otherwise, add the
1104  * standard time offset to the transition time.
1105  */
1106 
1107  /*
1108  * Transitions from DST to DDST will effectively disappear
1109  * since POSIX provides for only one DST offset.
1110  */
1111  if (isdst && !sp->ttis[j].tt_ttisstd)
1112  {
1113  sp->ats[i] += dstoffset -
1114  theirdstoffset;
1115  }
1116  else
1117  {
1118  sp->ats[i] += stdoffset -
1119  theirstdoffset;
1120  }
1121  }
1122  theiroffset = -sp->ttis[j].tt_gmtoff;
1123  if (sp->ttis[j].tt_isdst)
1124  theirdstoffset = theiroffset;
1125  else
1126  theirstdoffset = theiroffset;
1127  }
1128 
1129  /*
1130  * Finally, fill in ttis.
1131  */
1132  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1133  init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1134  sp->typecnt = 2;
1135  sp->defaulttype = 0;
1136  }
1137  }
1138  else
1139  {
1140  dstlen = 0;
1141  sp->typecnt = 1; /* only standard time */
1142  sp->timecnt = 0;
1143  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1144  sp->defaulttype = 0;
1145  }
1146  sp->charcnt = charcnt;
1147  cp = sp->chars;
1148  memcpy(cp, stdname, stdlen);
1149  cp += stdlen;
1150  *cp++ = '\0';
1151  if (dstlen != 0)
1152  {
1153  memcpy(cp, dstname, dstlen);
1154  *(cp + dstlen) = '\0';
1155  }
1156  return true;
1157 }
#define swap(a, b)
Definition: qsort.c:94
static const char * getoffset(const char *strp, int32 *offsetp)
Definition: localtime.c:695
static void init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
Definition: localtime.c:107
int64 pg_time_t
Definition: pgtime.h:23
int tzload(const char *name, char *canonname, struct state *sp, bool doextend)
Definition: localtime.c:537
int charcnt
Definition: pgtz.h:46
bool goback
Definition: pgtz.h:47
int32 tt_gmtoff
Definition: pgtz.h:28
#define isleap(y)
Definition: datetime.h:273
int leapcnt
Definition: pgtz.h:43
static const char * getrule(const char *strp, struct rule *rulep)
Definition: localtime.c:721
#define TZ_MAX_TIMES
Definition: tzfile.h:93
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
#define TZDEFRULESTRING
Definition: localtime.c:63
Definition: localtime.c:74
signed int int32
Definition: c.h:256
bool tt_isdst
Definition: pgtz.h:29
#define SECSPERDAY
Definition: tzfile.h:110
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, 3),(2 *(TZ_STRLEN_MAX+1)))]
Definition: pgtz.h:53
static int32 transtime(int year, const struct rule *rulep, int32 offset)
Definition: localtime.c:781
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
#define NULL
Definition: c.h:229
#define TZDEFRULES
Definition: tzfile.h:25
static ptrdiff_t timecnt
Definition: zic.c:182
int timecnt
Definition: pgtz.h:44
static int charcnt
Definition: zic.c:163
bool tt_ttisstd
Definition: pgtz.h:31
const char * name
Definition: encode.c:521
#define YEARSPERREPEAT
Definition: private.h:112
static bool increment_overflow_time(pg_time_t *, int32)
Definition: localtime.c:1468
static const int year_lengths[2]
Definition: localtime.c:581
int i
#define EPOCH_YEAR
Definition: tzfile.h:136
bool tt_ttisgmt
Definition: pgtz.h:32
bool goahead
Definition: pgtz.h:48
static const char * getqzname(const char *strp, int delim)
Definition: localtime.c:610
int typecnt
Definition: pgtz.h:45
#define SECSPERHOUR
Definition: tzfile.h:109
int defaulttype
Definition: pgtz.h:55
static const char * getzname(const char *strp)
Definition: localtime.c:591

Variable Documentation

const char gmt[] = "GMT"
static

Definition at line 50 of file localtime.c.

Referenced by gbt_tstz_compress(), and gmtload().

const int mon_lengths[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 576 of file localtime.c.

const pg_time_t time_t_max = MAXVAL(pg_time_t, TYPE_BIT(pg_time_t))
static

Definition at line 54 of file localtime.c.

Referenced by tzloadbody().

const pg_time_t time_t_min = MINVAL(pg_time_t, TYPE_BIT(pg_time_t))
static

Definition at line 53 of file localtime.c.

Referenced by increment_overflow_time(), and tzloadbody().

struct pg_tm tm
static

Definition at line 103 of file localtime.c.

Referenced by abstime_date(), abstime_timestamp(), abstime_timestamptz(), abstimein(), abstimeout(), build_time_t(), createBackupLabel(), date2timestamptz(), date_in(), date_out(), DCH_to_char(), gbt_num_compress(), GetSQLCurrentDate(), GetSQLCurrentTime(), GetSQLLocalTime(), identify_system_timezone(), interval_in(), interval_out(), interval_part(), interval_to_char(), interval_trunc(), locale_date_order(), pg_gmtime(), pg_localtime(), PGTYPESdate_defmt_asc(), PGTYPESdate_fmt_asc(), PGTYPESdate_from_asc(), PGTYPESdate_to_asc(), PGTYPESdate_today(), PGTYPESinterval_from_asc(), PGTYPESinterval_to_asc(), PGTYPEStimestamp_add_interval(), PGTYPEStimestamp_current(), PGTYPEStimestamp_defmt_scan(), PGTYPEStimestamp_fmt_asc(), PGTYPEStimestamp_from_asc(), PGTYPEStimestamp_to_asc(), ReadHead(), reltimein(), reltimeout(), score_timezone(), set_next_rotation_time(), SetEpochTimestamp(), tarOpen(), time_in(), time_out(), time_part(), time_timetz(), timestamp2timestamptz(), timestamp_abstime(), timestamp_age(), timestamp_date(), timestamp_in(), timestamp_out(), timestamp_part(), timestamp_pl_interval(), timestamp_recv(), timestamp_time(), timestamp_to_char(), timestamp_trunc(), timestamptz2timestamp(), timestamptz_abstime(), timestamptz_age(), timestamptz_date(), timestamptz_in(), timestamptz_out(), timestamptz_part(), timestamptz_pl_interval(), timestamptz_recv(), timestamptz_time(), timestamptz_timetz(), timestamptz_to_char(), timestamptz_to_str(), timestamptz_trunc(), timetz_in(), timetz_out(), timetz_part(), timetz_zone(), typenameTypeMod(), WriteHead(), and writezone().

const char wildabbr[] = WILDABBR
static

Definition at line 48 of file localtime.c.

Referenced by gmtsub().

const int year_lengths[2]
static
Initial value:
= {
}
#define DAYSPERLYEAR
Definition: tzfile.h:108
#define DAYSPERNYEAR
Definition: tzfile.h:107

Definition at line 581 of file localtime.c.