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,
  b 
)    (((a) > (b)) ? (a) : (b))

Definition at line 24 of file pgtz.h.

◆ SMALLEST

#define SMALLEST (   a,
  b 
)    (((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.

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 }
#define PG_BINARY
Definition: c.h:1273
static const char * pg_TZDIR(void)
Definition: findtimezone.c:37
#define MAXPGPATH
#define TZ_STRLEN_MAX
Definition: pgtime.h:54
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
const char * name

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

Referenced by tzloadbody().

◆ tzload()

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

Definition at line 586 of file localtime.c.

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

References err(), free, malloc, name, and tzloadbody().

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

◆ tzparse()

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

Definition at line 936 of file localtime.c.

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

References state::ats, state::charcnt, charcnt, state::chars, state::defaulttype, EPOCH_YEAR, getoffset(), getqzname(), getrule(), getzname(), state::goahead, state::goback, i, if(), increment_overflow_time(), init_ttinfo(), isleap, j, state::leapcnt, name, SECSPERDAY, SECSPERHOUR, start, 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().