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, PG_BINARY, pg_TZDIR(), 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 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:45
#define free(a)
Definition: header.h:60
const char * name
Definition: encode.c:521
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:253
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:226
#define TZDEFRULES
Definition: tzfile.h:25
static ptrdiff_t timecnt
Definition: zic.c:183
int timecnt
Definition: pgtz.h:44
static int charcnt
Definition: zic.c:164
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