PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pgtz.h File Reference
#include "pgtime.h"
#include "tzfile.h"
Include dependency graph for pgtz.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ttinfo
 
struct  lsinfo
 
struct  state
 
struct  pg_tz
 

Macros

#define SMALLEST(a, b)   (((a) < (b)) ? (a) : (b))
 
#define BIGGEST(a, b)   (((a) > (b)) ? (a) : (b))
 

Functions

int pg_open_tzfile (const char *name, char *canonname)
 
int tzload (const char *name, char *canonname, struct state *sp, bool doextend)
 
bool tzparse (const char *name, struct state *sp, bool lastditch)
 

Macro Definition Documentation

#define BIGGEST (   a,
 
)    (((a) > (b)) ? (a) : (b))

Definition at line 24 of file pgtz.h.

#define SMALLEST (   a,
 
)    (((a) < (b)) ? (a) : (b))

Definition at line 23 of file pgtz.h.

Function Documentation

int pg_open_tzfile ( const char *  name,
char *  canonname 
)

Definition at line 64 of file findtimezone.c.

References MAXPGPATH, name, NULL, PG_BINARY, pg_TZDIR(), result, scan_directory_ci(), strlcpy(), and TZ_STRLEN_MAX.

Referenced by tzloadbody().

65 {
66  char fullname[MAXPGPATH];
67 
68  if (canonname)
69  strlcpy(canonname, name, TZ_STRLEN_MAX + 1);
70 
71  strlcpy(fullname, pg_TZDIR(), sizeof(fullname));
72  if (strlen(fullname) + 1 + strlen(name) >= MAXPGPATH)
73  return -1; /* not gonna fit */
74  strcat(fullname, "/");
75  strcat(fullname, name);
76 
77  return open(fullname, O_RDONLY | PG_BINARY, 0);
78 }
static const char * pg_TZDIR(void)
Definition: findtimezone.c:36
#define PG_BINARY
Definition: c.h:1038
#define TZ_STRLEN_MAX
Definition: pgtime.h:44
#define MAXPGPATH
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
const char * name
Definition: encode.c:521
int tzload ( const char *  name,
char *  canonname,
struct state sp,
bool  doextend 
)

Definition at line 556 of file localtime.c.

References free, malloc, and tzloadbody().

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

557 {
558  union local_storage *lsp = malloc(sizeof *lsp);
559 
560  if (!lsp)
561  return errno;
562  else
563  {
564  int err = tzloadbody(name, canonname, sp, doextend, lsp);
565 
566  free(lsp);
567  return err;
568  }
569 }
static int tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, union local_storage *lsp)
Definition: localtime.c:218
#define malloc(a)
Definition: header.h:50
#define free(a)
Definition: header.h:65
const char * name
Definition: encode.c:521
bool tzparse ( const char *  name,
struct state sp,
bool  lastditch 
)

Definition at line 897 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, tzdefrules_s, TZDEFRULESTRING, tzload(), and YEARSPERREPEAT.

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

898 {
899  const char *stdname;
900  const char *dstname = NULL;
901  size_t stdlen;
902  size_t dstlen;
903  size_t charcnt;
904  int32 stdoffset;
905  int32 dstoffset;
906  char *cp;
907  bool load_ok;
908 
909  stdname = name;
910  if (lastditch)
911  {
912  /*
913  * This is intentionally somewhat different from the IANA code. We do
914  * not want to invoke tzload() in the lastditch case: we can't assume
915  * pg_open_tzfile() is sane yet, and we don't care about leap seconds
916  * anyway.
917  */
918  stdlen = strlen(name); /* length of standard zone name */
919  name += stdlen;
920  if (stdlen >= sizeof sp->chars)
921  stdlen = (sizeof sp->chars) - 1;
922  charcnt = stdlen + 1;
923  stdoffset = 0;
924  sp->goback = sp->goahead = false; /* simulate failed tzload() */
925  load_ok = false;
926  }
927  else
928  {
929  if (*name == '<')
930  {
931  name++;
932  stdname = name;
933  name = getqzname(name, '>');
934  if (*name != '>')
935  return false;
936  stdlen = name - stdname;
937  name++;
938  }
939  else
940  {
941  name = getzname(name);
942  stdlen = name - stdname;
943  }
944  if (*name == '\0') /* we allow empty STD abbrev, unlike IANA */
945  return false;
946  name = getoffset(name, &stdoffset);
947  if (name == NULL)
948  return false;
949  charcnt = stdlen + 1;
950  if (sizeof sp->chars < charcnt)
951  return false;
952 
953  /*
954  * This bit also differs from the IANA code, which doesn't make any
955  * attempt to avoid repetitive loadings of the TZDEFRULES zone.
956  */
957  if (tzdefrules_loaded == 0)
958  {
959  if (tzload(TZDEFRULES, NULL, &tzdefrules_s, false) == 0)
960  tzdefrules_loaded = 1;
961  else
962  tzdefrules_loaded = -1;
963  }
964  load_ok = (tzdefrules_loaded > 0);
965  if (load_ok)
966  memcpy(sp, &tzdefrules_s, sizeof(struct state));
967  }
968  if (!load_ok)
969  sp->leapcnt = 0; /* so, we're off a little */
970  if (*name != '\0')
971  {
972  if (*name == '<')
973  {
974  dstname = ++name;
975  name = getqzname(name, '>');
976  if (*name != '>')
977  return false;
978  dstlen = name - dstname;
979  name++;
980  }
981  else
982  {
983  dstname = name;
984  name = getzname(name);
985  dstlen = name - dstname; /* length of DST zone name */
986  }
987  if (!dstlen)
988  return false;
989  charcnt += dstlen + 1;
990  if (sizeof sp->chars < charcnt)
991  return false;
992  if (*name != '\0' && *name != ',' && *name != ';')
993  {
994  name = getoffset(name, &dstoffset);
995  if (name == NULL)
996  return false;
997  }
998  else
999  dstoffset = stdoffset - SECSPERHOUR;
1000  if (*name == '\0' && !load_ok)
1002  if (*name == ',' || *name == ';')
1003  {
1004  struct rule start;
1005  struct rule end;
1006  int year;
1007  int yearlim;
1008  int timecnt;
1009  pg_time_t janfirst;
1010  int32 janoffset = 0;
1011  int yearbeg;
1012 
1013  ++name;
1014  if ((name = getrule(name, &start)) == NULL)
1015  return false;
1016  if (*name++ != ',')
1017  return false;
1018  if ((name = getrule(name, &end)) == NULL)
1019  return false;
1020  if (*name != '\0')
1021  return false;
1022  sp->typecnt = 2; /* standard time and DST */
1023 
1024  /*
1025  * Two transitions per year, from EPOCH_YEAR forward.
1026  */
1027  init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
1028  init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
1029  sp->defaulttype = 0;
1030  timecnt = 0;
1031  janfirst = 0;
1032  yearbeg = EPOCH_YEAR;
1033 
1034  do
1035  {
1036  int32 yearsecs
1037  = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
1038 
1039  yearbeg--;
1040  if (increment_overflow_time(&janfirst, -yearsecs))
1041  {
1042  janoffset = -yearsecs;
1043  break;
1044  }
1045  } while (EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1046 
1047  yearlim = yearbeg + YEARSPERREPEAT + 1;
1048  for (year = yearbeg; year < yearlim; year++)
1049  {
1050  int32
1051  starttime = transtime(year, &start, stdoffset),
1052  endtime = transtime(year, &end, dstoffset);
1053  int32
1054  yearsecs = (year_lengths[isleap(year)]
1055  * SECSPERDAY);
1056  bool reversed = endtime < starttime;
1057 
1058  if (reversed)
1059  {
1060  int32 swap = starttime;
1061 
1062  starttime = endtime;
1063  endtime = swap;
1064  }
1065  if (reversed
1066  || (starttime < endtime
1067  && (endtime - starttime
1068  < (yearsecs
1069  + (stdoffset - dstoffset)))))
1070  {
1071  if (TZ_MAX_TIMES - 2 < timecnt)
1072  break;
1073  sp->ats[timecnt] = janfirst;
1075  (&sp->ats[timecnt],
1076  janoffset + starttime))
1077  sp->types[timecnt++] = reversed;
1078  else if (janoffset)
1079  sp->defaulttype = reversed;
1080  sp->ats[timecnt] = janfirst;
1082  (&sp->ats[timecnt],
1083  janoffset + endtime))
1084  {
1085  sp->types[timecnt++] = !reversed;
1086  yearlim = year + YEARSPERREPEAT + 1;
1087  }
1088  else if (janoffset)
1089  sp->defaulttype = !reversed;
1090  }
1092  (&janfirst, janoffset + yearsecs))
1093  break;
1094  janoffset = 0;
1095  }
1096  sp->timecnt = timecnt;
1097  if (!timecnt)
1098  sp->typecnt = 1; /* Perpetual DST. */
1099  else if (YEARSPERREPEAT < year - yearbeg)
1100  sp->goback = sp->goahead = true;
1101  }
1102  else
1103  {
1104  int32 theirstdoffset;
1105  int32 theirdstoffset;
1106  int32 theiroffset;
1107  bool isdst;
1108  int i;
1109  int j;
1110 
1111  if (*name != '\0')
1112  return false;
1113 
1114  /*
1115  * Initial values of theirstdoffset and theirdstoffset.
1116  */
1117  theirstdoffset = 0;
1118  for (i = 0; i < sp->timecnt; ++i)
1119  {
1120  j = sp->types[i];
1121  if (!sp->ttis[j].tt_isdst)
1122  {
1123  theirstdoffset =
1124  -sp->ttis[j].tt_gmtoff;
1125  break;
1126  }
1127  }
1128  theirdstoffset = 0;
1129  for (i = 0; i < sp->timecnt; ++i)
1130  {
1131  j = sp->types[i];
1132  if (sp->ttis[j].tt_isdst)
1133  {
1134  theirdstoffset =
1135  -sp->ttis[j].tt_gmtoff;
1136  break;
1137  }
1138  }
1139 
1140  /*
1141  * Initially we're assumed to be in standard time.
1142  */
1143  isdst = false;
1144  theiroffset = theirstdoffset;
1145 
1146  /*
1147  * Now juggle transition times and types tracking offsets as you
1148  * do.
1149  */
1150  for (i = 0; i < sp->timecnt; ++i)
1151  {
1152  j = sp->types[i];
1153  sp->types[i] = sp->ttis[j].tt_isdst;
1154  if (sp->ttis[j].tt_ttisgmt)
1155  {
1156  /* No adjustment to transition time */
1157  }
1158  else
1159  {
1160  /*
1161  * If summer time is in effect, and the transition time
1162  * was not specified as standard time, add the summer time
1163  * offset to the transition time; otherwise, add the
1164  * standard time offset to the transition time.
1165  */
1166 
1167  /*
1168  * Transitions from DST to DDST will effectively disappear
1169  * since POSIX provides for only one DST offset.
1170  */
1171  if (isdst && !sp->ttis[j].tt_ttisstd)
1172  {
1173  sp->ats[i] += dstoffset -
1174  theirdstoffset;
1175  }
1176  else
1177  {
1178  sp->ats[i] += stdoffset -
1179  theirstdoffset;
1180  }
1181  }
1182  theiroffset = -sp->ttis[j].tt_gmtoff;
1183  if (sp->ttis[j].tt_isdst)
1184  theirdstoffset = theiroffset;
1185  else
1186  theirstdoffset = theiroffset;
1187  }
1188 
1189  /*
1190  * Finally, fill in ttis.
1191  */
1192  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1193  init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1194  sp->typecnt = 2;
1195  sp->defaulttype = 0;
1196  }
1197  }
1198  else
1199  {
1200  dstlen = 0;
1201  sp->typecnt = 1; /* only standard time */
1202  sp->timecnt = 0;
1203  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1204  sp->defaulttype = 0;
1205  }
1206  sp->charcnt = charcnt;
1207  cp = sp->chars;
1208  memcpy(cp, stdname, stdlen);
1209  cp += stdlen;
1210  *cp++ = '\0';
1211  if (dstlen != 0)
1212  {
1213  memcpy(cp, dstname, dstlen);
1214  *(cp + dstlen) = '\0';
1215  }
1216  return true;
1217 }
#define swap(a, b)
Definition: qsort.c:94
static const char * getoffset(const char *strp, int32 *offsetp)
Definition: localtime.c:714
static void init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
Definition: localtime.c:115
int64 pg_time_t
Definition: pgtime.h:23
int tzload(const char *name, char *canonname, struct state *sp, bool doextend)
Definition: localtime.c:556
int charcnt
Definition: pgtz.h:46
bool goback
Definition: pgtz.h:47
int32 tt_gmtoff
Definition: pgtz.h:28
#define SECSPERDAY
Definition: private.h:114
#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:740
#define SECSPERHOUR
Definition: private.h:113
#define TZ_MAX_TIMES
Definition: tzfile.h:93
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
#define TZDEFRULESTRING
Definition: localtime.c:71
Definition: localtime.c:82
signed int int32
Definition: c.h:256
bool tt_isdst
Definition: pgtz.h:29
static struct state tzdefrules_s
Definition: localtime.c:61
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:800
#define EPOCH_YEAR
Definition: private.h:140
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
static int tzdefrules_loaded
Definition: localtime.c:62
#define NULL
Definition: c.h:229
Definition: regguts.h:298
#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:105
static bool increment_overflow_time(pg_time_t *, int32)
Definition: localtime.c:1528
static const int year_lengths[2]
Definition: localtime.c:600
int i
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:629
int typecnt
Definition: pgtz.h:45
int defaulttype
Definition: pgtz.h:55
static const char * getzname(const char *strp)
Definition: localtime.c:610