PostgreSQL Source Code  git master
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

◆ BIGGEST

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

Definition at line 24 of file pgtz.h.

◆ SMALLEST

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

Definition at line 23 of file pgtz.h.

Function Documentation

◆ pg_open_tzfile()

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

Definition at line 65 of file findtimezone.c.

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

Referenced by tzloadbody().

66 {
67  char fullname[MAXPGPATH];
68 
69  if (canonname)
70  strlcpy(canonname, name, TZ_STRLEN_MAX + 1);
71 
72  strlcpy(fullname, pg_TZDIR(), sizeof(fullname));
73  if (strlen(fullname) + 1 + strlen(name) >= MAXPGPATH)
74  return -1; /* not gonna fit */
75  strcat(fullname, "/");
76  strcat(fullname, name);
77 
78  return open(fullname, O_RDONLY | PG_BINARY, 0);
79 }
static const char * pg_TZDIR(void)
Definition: findtimezone.c:37
#define PG_BINARY
Definition: c.h:1233
#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:561

◆ tzload()

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

Definition at line 584 of file localtime.c.

References free, malloc, and tzloadbody().

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

585 {
586  union local_storage *lsp = malloc(sizeof *lsp);
587 
588  if (!lsp)
589  return errno;
590  else
591  {
592  int err = tzloadbody(name, canonname, sp, doextend, lsp);
593 
594  free(lsp);
595  return err;
596  }
597 }
static int tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, union local_storage *lsp)
Definition: localtime.c:209
#define malloc(a)
Definition: header.h:50
#define free(a)
Definition: header.h:65
const char * name
Definition: encode.c:561

◆ tzparse()

bool tzparse ( const char *  name,
struct state sp,
bool  lastditch 
)

Definition at line 934 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, SECSPERDAY, SECSPERHOUR, swap, state::timecnt, timecnt, transtime(), ttinfo::tt_isdst, ttinfo::tt_ttisstd, ttinfo::tt_ttisut, ttinfo::tt_utoff, state::ttis, state::typecnt, state::types, TZ_MAX_TIMES, TZDEFRULESTRING, year_lengths, and YEARSPERREPEAT.

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

935 {
936  const char *stdname;
937  const char *dstname = NULL;
938  size_t stdlen;
939  size_t dstlen;
940  size_t charcnt;
941  int32 stdoffset;
942  int32 dstoffset;
943  char *cp;
944  bool load_ok;
945 
946  stdname = name;
947  if (lastditch)
948  {
949  /* Unlike IANA, don't assume name is exactly "GMT" */
950  stdlen = strlen(name); /* length of standard zone name */
951  name += stdlen;
952  stdoffset = 0;
953  }
954  else
955  {
956  if (*name == '<')
957  {
958  name++;
959  stdname = name;
960  name = getqzname(name, '>');
961  if (*name != '>')
962  return false;
963  stdlen = name - stdname;
964  name++;
965  }
966  else
967  {
968  name = getzname(name);
969  stdlen = name - stdname;
970  }
971  if (*name == '\0') /* we allow empty STD abbrev, unlike IANA */
972  return false;
973  name = getoffset(name, &stdoffset);
974  if (name == NULL)
975  return false;
976  }
977  charcnt = stdlen + 1;
978  if (sizeof sp->chars < charcnt)
979  return false;
980 
981  /*
982  * The IANA code always tries to tzload(TZDEFRULES) here. We do not want
983  * to do that; it would be bad news in the lastditch case, where we can't
984  * assume pg_open_tzfile() is sane yet. Moreover, if we did load it and
985  * it contains leap-second-dependent info, that would cause problems too.
986  * Finally, IANA has deprecated the TZDEFRULES feature, so it presumably
987  * will die at some point. Desupporting it now seems like good
988  * future-proofing.
989  */
990  load_ok = false;
991  sp->goback = sp->goahead = false; /* simulate failed tzload() */
992  sp->leapcnt = 0; /* intentionally assume no leap seconds */
993 
994  if (*name != '\0')
995  {
996  if (*name == '<')
997  {
998  dstname = ++name;
999  name = getqzname(name, '>');
1000  if (*name != '>')
1001  return false;
1002  dstlen = name - dstname;
1003  name++;
1004  }
1005  else
1006  {
1007  dstname = name;
1008  name = getzname(name);
1009  dstlen = name - dstname; /* length of DST abbr. */
1010  }
1011  if (!dstlen)
1012  return false;
1013  charcnt += dstlen + 1;
1014  if (sizeof sp->chars < charcnt)
1015  return false;
1016  if (*name != '\0' && *name != ',' && *name != ';')
1017  {
1018  name = getoffset(name, &dstoffset);
1019  if (name == NULL)
1020  return false;
1021  }
1022  else
1023  dstoffset = stdoffset - SECSPERHOUR;
1024  if (*name == '\0' && !load_ok)
1026  if (*name == ',' || *name == ';')
1027  {
1028  struct rule start;
1029  struct rule end;
1030  int year;
1031  int yearlim;
1032  int timecnt;
1033  pg_time_t janfirst;
1034  int32 janoffset = 0;
1035  int yearbeg;
1036 
1037  ++name;
1038  if ((name = getrule(name, &start)) == NULL)
1039  return false;
1040  if (*name++ != ',')
1041  return false;
1042  if ((name = getrule(name, &end)) == NULL)
1043  return false;
1044  if (*name != '\0')
1045  return false;
1046  sp->typecnt = 2; /* standard time and DST */
1047 
1048  /*
1049  * Two transitions per year, from EPOCH_YEAR forward.
1050  */
1051  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1052  init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1053  sp->defaulttype = 0;
1054  timecnt = 0;
1055  janfirst = 0;
1056  yearbeg = EPOCH_YEAR;
1057 
1058  do
1059  {
1060  int32 yearsecs
1061  = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
1062 
1063  yearbeg--;
1064  if (increment_overflow_time(&janfirst, -yearsecs))
1065  {
1066  janoffset = -yearsecs;
1067  break;
1068  }
1069  } while (EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1070 
1071  yearlim = yearbeg + YEARSPERREPEAT + 1;
1072  for (year = yearbeg; year < yearlim; year++)
1073  {
1074  int32
1075  starttime = transtime(year, &start, stdoffset),
1076  endtime = transtime(year, &end, dstoffset);
1077  int32
1078  yearsecs = (year_lengths[isleap(year)]
1079  * SECSPERDAY);
1080  bool reversed = endtime < starttime;
1081 
1082  if (reversed)
1083  {
1084  int32 swap = starttime;
1085 
1086  starttime = endtime;
1087  endtime = swap;
1088  }
1089  if (reversed
1090  || (starttime < endtime
1091  && (endtime - starttime
1092  < (yearsecs
1093  + (stdoffset - dstoffset)))))
1094  {
1095  if (TZ_MAX_TIMES - 2 < timecnt)
1096  break;
1097  sp->ats[timecnt] = janfirst;
1099  (&sp->ats[timecnt],
1100  janoffset + starttime))
1101  sp->types[timecnt++] = !reversed;
1102  sp->ats[timecnt] = janfirst;
1104  (&sp->ats[timecnt],
1105  janoffset + endtime))
1106  {
1107  sp->types[timecnt++] = reversed;
1108  yearlim = year + YEARSPERREPEAT + 1;
1109  }
1110  }
1112  (&janfirst, janoffset + yearsecs))
1113  break;
1114  janoffset = 0;
1115  }
1116  sp->timecnt = timecnt;
1117  if (!timecnt)
1118  {
1119  sp->ttis[0] = sp->ttis[1];
1120  sp->typecnt = 1; /* Perpetual DST. */
1121  }
1122  else if (YEARSPERREPEAT < year - yearbeg)
1123  sp->goback = sp->goahead = true;
1124  }
1125  else
1126  {
1127  int32 theirstdoffset;
1128  int32 theirdstoffset;
1129  int32 theiroffset;
1130  bool isdst;
1131  int i;
1132  int j;
1133 
1134  if (*name != '\0')
1135  return false;
1136 
1137  /*
1138  * Initial values of theirstdoffset and theirdstoffset.
1139  */
1140  theirstdoffset = 0;
1141  for (i = 0; i < sp->timecnt; ++i)
1142  {
1143  j = sp->types[i];
1144  if (!sp->ttis[j].tt_isdst)
1145  {
1146  theirstdoffset =
1147  -sp->ttis[j].tt_utoff;
1148  break;
1149  }
1150  }
1151  theirdstoffset = 0;
1152  for (i = 0; i < sp->timecnt; ++i)
1153  {
1154  j = sp->types[i];
1155  if (sp->ttis[j].tt_isdst)
1156  {
1157  theirdstoffset =
1158  -sp->ttis[j].tt_utoff;
1159  break;
1160  }
1161  }
1162 
1163  /*
1164  * Initially we're assumed to be in standard time.
1165  */
1166  isdst = false;
1167  theiroffset = theirstdoffset;
1168 
1169  /*
1170  * Now juggle transition times and types tracking offsets as you
1171  * do.
1172  */
1173  for (i = 0; i < sp->timecnt; ++i)
1174  {
1175  j = sp->types[i];
1176  sp->types[i] = sp->ttis[j].tt_isdst;
1177  if (sp->ttis[j].tt_ttisut)
1178  {
1179  /* No adjustment to transition time */
1180  }
1181  else
1182  {
1183  /*
1184  * If daylight saving time is in effect, and the
1185  * transition time was not specified as standard time, add
1186  * the daylight saving time offset to the transition time;
1187  * otherwise, add the standard time offset to the
1188  * transition time.
1189  */
1190  /*
1191  * Transitions from DST to DDST will effectively disappear
1192  * since POSIX provides for only one DST offset.
1193  */
1194  if (isdst && !sp->ttis[j].tt_ttisstd)
1195  {
1196  sp->ats[i] += dstoffset -
1197  theirdstoffset;
1198  }
1199  else
1200  {
1201  sp->ats[i] += stdoffset -
1202  theirstdoffset;
1203  }
1204  }
1205  theiroffset = -sp->ttis[j].tt_utoff;
1206  if (sp->ttis[j].tt_isdst)
1207  theirdstoffset = theiroffset;
1208  else
1209  theirstdoffset = theiroffset;
1210  }
1211 
1212  /*
1213  * Finally, fill in ttis.
1214  */
1215  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1216  init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1217  sp->typecnt = 2;
1218  sp->defaulttype = 0;
1219  }
1220  }
1221  else
1222  {
1223  dstlen = 0;
1224  sp->typecnt = 1; /* only standard time */
1225  sp->timecnt = 0;
1226  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1227  sp->defaulttype = 0;
1228  }
1229  sp->charcnt = charcnt;
1230  cp = sp->chars;
1231  memcpy(cp, stdname, stdlen);
1232  cp += stdlen;
1233  *cp++ = '\0';
1234  if (dstlen != 0)
1235  {
1236  memcpy(cp, dstname, dstlen);
1237  *(cp + dstlen) = '\0';
1238  }
1239  return true;
1240 }
#define swap(a, b)
Definition: qsort.c:94
int64 pg_time_t
Definition: pgtime.h:23
int charcnt
Definition: pgtz.h:46
bool goback
Definition: pgtz.h:47
#define SECSPERDAY
Definition: private.h:108
#define isleap(y)
Definition: datetime.h:271
int leapcnt
Definition: pgtz.h:43
static const char * getqzname(const char *strp, const int delim)
Definition: localtime.c:661
#define SECSPERHOUR
Definition: private.h:107
#define TZ_MAX_TIMES
Definition: tzfile.h:100
int32 tt_utoff
Definition: pgtz.h:28
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
#define TZDEFRULESTRING
Definition: localtime.c:61
Definition: localtime.c:72
signed int int32
Definition: c.h:355
bool tt_ttisut
Definition: pgtz.h:32
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, 4),(2 *(TZ_STRLEN_MAX+1)))]
Definition: pgtz.h:53
bool tt_isdst
Definition: pgtz.h:29
static const char * getoffset(const char *strp, int32 *const offsetp)
Definition: localtime.c:749
static const char * getrule(const char *strp, struct rule *const rulep)
Definition: localtime.c:776
#define EPOCH_YEAR
Definition: private.h:134
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
static void init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
Definition: localtime.c:106
static ptrdiff_t timecnt
Definition: zic.c:194
int timecnt
Definition: pgtz.h:44
static int charcnt
Definition: zic.c:175
bool tt_ttisstd
Definition: pgtz.h:31
const char * name
Definition: encode.c:561
#define YEARSPERREPEAT
Definition: private.h:99
static bool increment_overflow_time(pg_time_t *, int32)
Definition: localtime.c:1555
static const int year_lengths[2]
Definition: localtime.c:629
static int32 transtime(const int year, const struct rule *const rulep, const int32 offset)
Definition: localtime.c:837
int i
bool goahead
Definition: pgtz.h:48
int typecnt
Definition: pgtz.h:45
int defaulttype
Definition: pgtz.h:61
static const char * getzname(const char *strp)
Definition: localtime.c:640