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:1230
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}
int32_t int32
Definition: c.h:484
return str start
#define isleap(y)
Definition: datetime.h:271
int j
Definition: isn.c:73
int i
Definition: isn.c:72
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
static const char * getqzname(const char *strp, const int delim)
Definition: localtime.c:663
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 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 * getzname(const char *strp)
Definition: localtime.c:642
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 * getrule(const char *strp, struct rule *const rulep)
Definition: localtime.c:778
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().