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:1261
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 587 of file localtime.c.

588{
589 union local_storage *lsp = malloc(sizeof *lsp);
590
591 if (!lsp)
592 return errno;
593 else
594 {
595 int err = tzloadbody(name, canonname, sp, doextend, lsp);
596
597 free(lsp);
598 return err;
599 }
600}
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 937 of file localtime.c.

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

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().