#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "private.h"
#include "tzfile.h"
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/localtime.h"
#include "asterisk/strings.h"
Go to the source code of this file.
Data Structures | |
struct | lsinfo |
leap second information More... | |
struct | rule |
struct | state |
struct | ttinfo |
Defines | |
#define | BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) |
#define | DAY_OF_YEAR 1 |
#define | JULIAN_DAY 0 |
#define | LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) |
#define | MONTH_NTH_DAY_OF_WEEK 2 |
#define | MY_TZNAME_MAX 255 |
#define | OPEN_MODE O_RDONLY |
#define | TZ_STRLEN_MAX 255 |
#define | WILDABBR " " |
#define | WRONG (-1) |
Functions | |
char * | ast_ctime (time_t *const timep) const |
char * | ast_ctime_r (time_t *const timep, char *buf) const |
struct tm * | ast_localtime (time_t *const timep, struct tm *p_tm, const char *const zone) const |
time_t | ast_mktime (struct tm *const tmp, const char *const zone) |
AST_MUTEX_DEFINE_STATIC (gmt_mutex) | |
AST_MUTEX_DEFINE_STATIC (tzsetwall_mutex) | |
AST_MUTEX_DEFINE_STATIC (tzset_mutex) | |
AST_MUTEX_DEFINE_STATIC (lcl_mutex) | |
static long | detzcode (const char *const codep) |
static const char * | getnum (register const char *strp, int *const nump, const int min, const int max) |
Given a pointer into a time zone string, extract a number from that string. | |
static const char * | getoffset (register const char *strp, long *const offsetp) |
Given a pointer into a time zone string, extract an offset, in [+-]hh[:mm[:ss]] form, from the string. | |
static const char * | getrule (const char *strp, register struct rule *const rulep) |
Given a pointer into a time zone string, extract a rule in the form date[/time]. See POSIX section 8 for the format of "date" and "time". | |
static const char * | getsecs (register const char *strp, long *const secsp) |
Given a pointer into a time zone string, extract a number of seconds, in hh[:mm[:ss]] form, from the string. | |
static void | gmtload (struct state *const sp) |
static void | gmtsub (time_t *const timep, const long offset, struct tm *const tmp, const char *const zone) const |
static int | increment_overflow (int *number, int delta) |
static void | localsub (time_t *const timep, const long offset, struct tm *const tmp, const char *const zone) const |
static int | normalize_overflow (int *const tensptr, int *const unitsptr, const int base) |
static int ast_tzset_basic | P ((const char *name)) |
static int ast_tzsetwall_basic | P ((void)) |
static int tzparse | P ((const char *name, struct state *sp, int lastditch)) |
static int tzload | P ((const char *name, struct state *sp)) |
static time_t transtime | P ((time_t janfirst, int year, const struct rule *rulep, long offset)) |
static int tmcomp | P ((const struct tm *atmp, const struct tm *btmp)) |
static void timesub | P ((const time_t *timep, long offset, const struct state *sp, struct tm *tmp)) |
static time_t time2 | P ((struct tm *tmp, void(*funcp) P((const time_t *, long, struct tm *, const char *)), long offset, int *okayp, const char *zone)) |
static time_t time1 | P ((struct tm *tmp, void(*funcp) P((const time_t *, long, struct tm *, const char *)), long offset, const char *zone)) |
static int normalize_overflow | P ((int *tensptr, int *unitsptr, int base)) |
static int increment_overflow | P ((int *number, int delta)) |
static void gmtsub | P ((const time_t *timep, long offset, struct tm *tmp, const char *zone)) |
static void gmtload | P ((struct state *sp)) |
static const char *getrule | P ((const char *strp, struct rule *rulep)) |
static const char *getoffset | P ((const char *strp, long *offsetp)) |
static const char *getsecs | P ((const char *strp, long *secsp)) |
static const char *getnum | P ((const char *strp, int *nump, int min, int max)) |
static long detzcode | P ((const char *codep)) |
static time_t | time1 (struct tm *const tmp, funcp, const long offset, const char *const zone) |
static time_t | time2 (struct tm *const tmp, funcp, const long offset, int *const okayp, const char *const zone) |
static void | timesub (time_t *const timep, const long offset, const struct state *const sp, struct tm *const tmp) const |
static int | tmcomp (const struct tm *const atmp, const struct tm *const btmp) |
static time_t | transtime (time_t janfirst, const int year, const struct rule *const rulep, const long offset) const |
Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the year, a rule, and the offset from GMT at the time that rule takes effect, calculate the Epoch-relative time that rule takes effect. | |
static int | tzload (register const char *name, register struct state *const sp) |
static int | tzparse (char *name, struct state *const sp, const int lastditch) const |
Variables | |
static const char | elsieid [] = "@(#)localtime.c 7.57" |
static char | gmt [] = "GMT" |
FreeBSD defines 'zone' in 'struct tm' as non-const, so don't declare this string as const. | |
static int | gmt_is_set |
static struct state * | gmtptr = NULL |
static struct state * | last_lclptr = NULL |
static struct state * | lclptr = NULL |
static const int | mon_lengths [2][MONSPERYEAR] |
static char | wildabbr [] = "WILDABBR" |
static const int | year_lengths [2] |
Definition in file localtime.c.
#define BIGGEST | ( | a, | |||
b | ) | (((a) > (b)) ? (a) : (b)) |
Definition at line 136 of file localtime.c.
#define DAY_OF_YEAR 1 |
n - day of year
Definition at line 169 of file localtime.c.
Referenced by getrule(), and transtime().
#define JULIAN_DAY 0 |
Jn - Julian day
Definition at line 168 of file localtime.c.
Referenced by getrule(), and transtime().
#define LEAPS_THRU_END_OF | ( | y | ) | ((y) / 4 - (y) / 100 + (y) / 400) |
Referenced by timesub().
#define MONTH_NTH_DAY_OF_WEEK 2 |
Mm.n.d - month, week, day of week
Definition at line 170 of file localtime.c.
Referenced by getrule(), and transtime().
#define MY_TZNAME_MAX 255 |
Definition at line 142 of file localtime.c.
#define OPEN_MODE O_RDONLY |
#define TZ_STRLEN_MAX 255 |
Definition at line 43 of file localtime.c.
#define WILDABBR " " |
Definition at line 111 of file localtime.c.
#define WRONG (-1) |
char* ast_ctime | ( | time_t * const | timep | ) | const |
Definition at line 1202 of file localtime.c.
01204 { 01205 /* 01206 ** Section 4.12.3.2 of X3.159-1989 requires that 01207 ** The ctime funciton converts the calendar time pointed to by timer 01208 ** to local time in the form of a string. It is equivalent to 01209 ** asctime(localtime(timer)) 01210 */ 01211 return asctime(localtime(timep)); 01212 }
char* ast_ctime_r | ( | time_t * const | timep, | |
char * | buf | |||
) | const |
Definition at line 1215 of file localtime.c.
References localtime_r.
01218 { 01219 struct tm tm; 01220 return asctime_r(localtime_r(timep, &tm), buf); 01221 }
struct tm* ast_localtime | ( | time_t * const | timep, | |
struct tm * | p_tm, | |||
const char * const | zone | |||
) | const [read] |
Definition at line 1051 of file localtime.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_tzset(), and localsub().
01055 { 01056 #ifdef _THREAD_SAFE 01057 ast_mutex_lock(&lcl_mutex); 01058 #endif 01059 ast_tzset(ast_strlen_zero(zone) ? "/etc/localtime" : zone); 01060 localsub(timep, 0L, p_tm, zone); 01061 #ifdef _THREAD_SAFE 01062 ast_mutex_unlock(&lcl_mutex); 01063 #endif 01064 return(p_tm); 01065 }
time_t ast_mktime | ( | struct tm * const | tmp, | |
const char * const | zone | |||
) |
Definition at line 1491 of file localtime.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_tzset(), localsub(), and time1().
01494 { 01495 time_t mktime_return_value; 01496 #ifdef _THREAD_SAFE 01497 ast_mutex_lock(&lcl_mutex); 01498 #endif 01499 ast_tzset(!ast_strlen_zero(zone) ? zone : "/etc/localtime"); 01500 mktime_return_value = time1(tmp, localsub, 0L, !ast_strlen_zero(zone) ? zone : "/etc/localtime"); 01501 #ifdef _THREAD_SAFE 01502 ast_mutex_unlock(&lcl_mutex); 01503 #endif 01504 return(mktime_return_value); 01505 }
AST_MUTEX_DEFINE_STATIC | ( | gmt_mutex | ) |
AST_MUTEX_DEFINE_STATIC | ( | tzsetwall_mutex | ) |
AST_MUTEX_DEFINE_STATIC | ( | tzset_mutex | ) |
AST_MUTEX_DEFINE_STATIC | ( | lcl_mutex | ) |
static long detzcode | ( | const char *const | codep | ) | [static] |
Definition at line 232 of file localtime.c.
Referenced by tzload().
00233 { 00234 register long result; 00235 register int i; 00236 00237 result = (codep[0] & 0x80) ? ~0L : 0L; 00238 for (i = 0; i < 4; ++i) 00239 result = (result << 8) | (codep[i] & 0xff); 00240 return result; 00241 }
static const char* getnum | ( | register const char * | strp, | |
int *const | nump, | |||
const int | min, | |||
const int | max | |||
) | [static] |
Given a pointer into a time zone string, extract a number from that string.
Definition at line 412 of file localtime.c.
References is_digit.
Referenced by getrule(), and getsecs().
00413 { 00414 register char c; 00415 register int num; 00416 00417 if (strp == NULL || !is_digit(c = *strp)) 00418 return NULL; 00419 num = 0; 00420 do { 00421 num = num * 10 + (c - '0'); 00422 if (num > max) 00423 return NULL; /* illegal value */ 00424 c = *++strp; 00425 } while (is_digit(c)); 00426 if (num < min) 00427 return NULL; /* illegal value */ 00428 *nump = num; 00429 return strp; 00430 }
static const char* getoffset | ( | register const char * | strp, | |
long *const | offsetp | |||
) | [static] |
Given a pointer into a time zone string, extract an offset, in [+-]hh[:mm[:ss]] form, from the string.
Definition at line 479 of file localtime.c.
References getsecs().
Referenced by tzparse().
00480 { 00481 register int neg = 0; 00482 00483 if (*strp == '-') { 00484 neg = 1; 00485 ++strp; 00486 } else if (*strp == '+') 00487 ++strp; 00488 strp = getsecs(strp, offsetp); 00489 if (strp == NULL) 00490 return NULL; /* illegal time */ 00491 if (neg) 00492 *offsetp = -*offsetp; 00493 return strp; 00494 }
static const char* getrule | ( | const char * | strp, | |
register struct rule *const | rulep | |||
) | [static] |
Given a pointer into a time zone string, extract a rule in the form date[/time]. See POSIX section 8 for the format of "date" and "time".
Definition at line 503 of file localtime.c.
References DAY_OF_YEAR, DAYSPERLYEAR, DAYSPERNYEAR, DAYSPERWEEK, getnum(), getsecs(), is_digit, JULIAN_DAY, MONSPERYEAR, MONTH_NTH_DAY_OF_WEEK, and SECSPERHOUR.
Referenced by tzparse().
00504 { 00505 if (*strp == 'J') { 00506 /* 00507 ** Julian day. 00508 */ 00509 rulep->r_type = JULIAN_DAY; 00510 ++strp; 00511 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 00512 } else if (*strp == 'M') { 00513 /* 00514 ** Month, week, day. 00515 */ 00516 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 00517 ++strp; 00518 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 00519 if (strp == NULL) 00520 return NULL; 00521 if (*strp++ != '.') 00522 return NULL; 00523 strp = getnum(strp, &rulep->r_week, 1, 5); 00524 if (strp == NULL) 00525 return NULL; 00526 if (*strp++ != '.') 00527 return NULL; 00528 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 00529 } else if (is_digit(*strp)) { 00530 /* 00531 ** Day of year. 00532 */ 00533 rulep->r_type = DAY_OF_YEAR; 00534 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 00535 } else return NULL; /* invalid format */ 00536 if (strp == NULL) 00537 return NULL; 00538 if (*strp == '/') { 00539 /* 00540 ** Time specified. 00541 */ 00542 ++strp; 00543 strp = getsecs(strp, &rulep->r_time); 00544 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 00545 return strp; 00546 }
static const char* getsecs | ( | register const char * | strp, | |
long *const | secsp | |||
) | [static] |
Given a pointer into a time zone string, extract a number of seconds, in hh[:mm[:ss]] form, from the string.
Definition at line 440 of file localtime.c.
References DAYSPERWEEK, getnum(), HOURSPERDAY, MINSPERHOUR, SECSPERHOUR, and SECSPERMIN.
Referenced by getoffset(), and getrule().
00441 { 00442 int num; 00443 00444 /* 00445 ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like 00446 ** "M10.4.6/26", which does not conform to Posix, 00447 ** but which specifies the equivalent of 00448 ** ``02:00 on the first Sunday on or after 23 Oct''. 00449 */ 00450 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 00451 if (strp == NULL) 00452 return NULL; 00453 *secsp = num * (long) SECSPERHOUR; 00454 if (*strp == ':') { 00455 ++strp; 00456 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 00457 if (strp == NULL) 00458 return NULL; 00459 *secsp += num * SECSPERMIN; 00460 if (*strp == ':') { 00461 ++strp; 00462 /* `SECSPERMIN' allows for leap seconds. */ 00463 strp = getnum(strp, &num, 0, SECSPERMIN); 00464 if (strp == NULL) 00465 return NULL; 00466 *secsp += num; 00467 } 00468 } 00469 return strp; 00470 }
static void gmtload | ( | struct state * const | sp | ) | [static] |
static void gmtsub | ( | time_t * const | timep, | |
const long | offset, | |||
struct tm * const | tmp, | |||
const char * const | zone | |||
) | const [static] |
Definition at line 1072 of file localtime.c.
References ast_mutex_lock(), ast_mutex_unlock(), state::chars, gmtload(), malloc, timesub(), and TRUE.
Referenced by localsub().
01077 { 01078 #ifdef _THREAD_SAFE 01079 ast_mutex_lock(&gmt_mutex); 01080 #endif 01081 if (!gmt_is_set) { 01082 gmt_is_set = TRUE; 01083 gmtptr = (struct state *) malloc(sizeof *gmtptr); 01084 if (gmtptr != NULL) 01085 gmtload(gmtptr); 01086 } 01087 ast_mutex_unlock(&gmt_mutex); 01088 timesub(timep, offset, gmtptr, tmp); 01089 #ifdef TM_ZONE 01090 /* 01091 ** Could get fancy here and deliver something such as 01092 ** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero, 01093 ** but this is no time for a treasure hunt. 01094 */ 01095 if (offset != 0) 01096 tmp->TM_ZONE = wildabbr; 01097 else { 01098 if (gmtptr == NULL) 01099 tmp->TM_ZONE = gmt; 01100 else tmp->TM_ZONE = gmtptr->chars; 01101 } 01102 #endif /* defined TM_ZONE */ 01103 }
static int increment_overflow | ( | int * | number, | |
int | delta | |||
) | [static] |
Definition at line 1242 of file localtime.c.
Referenced by normalize_overflow(), and time2().
01245 { 01246 int number0; 01247 01248 number0 = *number; 01249 *number += delta; 01250 return (*number < number0) != (delta < 0); 01251 }
static void localsub | ( | time_t * const | timep, | |
const long | offset, | |||
struct tm * const | tmp, | |||
const char * const | zone | |||
) | const [static] |
Definition at line 984 of file localtime.c.
References ast_tzsetwall(), state::chars, gmtsub(), state::name, state::next, t, state::timecnt, timesub(), ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, state::typecnt, and state::types.
Referenced by ast_localtime(), ast_mktime(), time1(), and time2().
00989 { 00990 register struct state * sp; 00991 register const struct ttinfo * ttisp; 00992 register int i; 00993 const time_t t = *timep; 00994 00995 sp = lclptr; 00996 /* Find the right zone record */ 00997 if (zone == NULL) 00998 sp = NULL; 00999 else 01000 while (sp != NULL) { 01001 if (!strcmp(sp->name,zone)) 01002 break; 01003 sp = sp->next; 01004 } 01005 01006 if (sp == NULL) { 01007 ast_tzsetwall(); 01008 sp = lclptr; 01009 /* Find the default zone record */ 01010 while (sp != NULL) { 01011 if (sp->name[0] == '\0') 01012 break; 01013 sp = sp->next; 01014 } 01015 } 01016 01017 /* Last ditch effort, use GMT */ 01018 if (sp == NULL) { 01019 gmtsub(timep, offset, tmp, zone); 01020 return; 01021 } 01022 if (sp->timecnt == 0 || t < sp->ats[0]) { 01023 i = 0; 01024 while (sp->ttis[i].tt_isdst) 01025 if (++i >= sp->typecnt) { 01026 i = 0; 01027 break; 01028 } 01029 } else { 01030 for (i = 1; i < sp->timecnt; ++i) 01031 if (t < sp->ats[i]) 01032 break; 01033 i = sp->types[i - 1]; 01034 } 01035 ttisp = &sp->ttis[i]; 01036 /* 01037 ** To get (wrong) behavior that's compatible with System V Release 2.0 01038 ** you'd replace the statement below with 01039 ** t += ttisp->tt_gmtoff; 01040 ** timesub(&t, 0L, sp, tmp); 01041 */ 01042 timesub(&t, ttisp->tt_gmtoff, sp, tmp); 01043 tmp->tm_isdst = ttisp->tt_isdst; 01044 tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; 01045 #ifdef TM_ZONE 01046 tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; 01047 #endif /* defined TM_ZONE */ 01048 }
static int normalize_overflow | ( | int * const | tensptr, | |
int * const | unitsptr, | |||
const int | base | |||
) | [static] |
Definition at line 1254 of file localtime.c.
References increment_overflow().
Referenced by time2().
01258 { 01259 register int tensdelta; 01260 01261 tensdelta = (*unitsptr >= 0) ? 01262 (*unitsptr / base) : 01263 (-1 - (-1 - *unitsptr) / base); 01264 *unitsptr -= tensdelta * base; 01265 return increment_overflow(tensptr, tensdelta); 01266 }
void ast_tzset P | ( | (const char *name) | ) | [static] |
Definition at line 906 of file localtime.c.
References ast_tzsetwall(), state::chars, FALSE, gmtload(), state::leapcnt, malloc, state::name, state::next, state::timecnt, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, state::ttis, tzload(), and tzparse().
00911 { 00912 struct state *cur_state = lclptr; 00913 00914 /* Not set at all */ 00915 if (name == NULL) { 00916 return ast_tzsetwall(); 00917 } 00918 00919 /* Find the appropriate structure, if already parsed */ 00920 while (cur_state != NULL) { 00921 if (!strcmp(cur_state->name,name)) 00922 break; 00923 cur_state = cur_state->next; 00924 } 00925 if (cur_state != NULL) 00926 return 0; 00927 00928 cur_state = malloc(sizeof(struct state)); 00929 if (cur_state == NULL) { 00930 return -1; 00931 } 00932 memset(cur_state,0,sizeof(*cur_state)); 00933 00934 /* Name is set, but set to the empty string == no adjustments */ 00935 if (name[0] == '\0') { 00936 /* 00937 ** User wants it fast rather than right. 00938 */ 00939 cur_state->leapcnt = 0; /* so, we're off a little */ 00940 cur_state->timecnt = 0; 00941 cur_state->ttis[0].tt_gmtoff = 0; 00942 cur_state->ttis[0].tt_abbrind = 0; 00943 (void) strncpy(cur_state->chars, gmt, sizeof(cur_state->chars) - 1); 00944 } else if (tzload(name, cur_state) != 0) { 00945 if (name[0] == ':') { 00946 (void) gmtload(cur_state); 00947 } else if (tzparse(name, cur_state, FALSE) != 0) { 00948 /* If not found, load localtime */ 00949 if (tzload("/etc/localtime", cur_state) != 0) 00950 /* Last ditch, get GMT */ 00951 (void) gmtload(cur_state); 00952 } 00953 } 00954 strncpy(cur_state->name, name, sizeof(cur_state->name) - 1); 00955 if (last_lclptr) 00956 last_lclptr->next = cur_state; 00957 else 00958 lclptr = cur_state; 00959 last_lclptr = cur_state; 00960 return 0; 00961 }
int ast_tzsetwall P | ( | (void) | ) | [static] |
Definition at line 854 of file localtime.c.
References gmtload(), malloc, state::name, state::next, and tzload().
00859 { 00860 struct state *cur_state = lclptr; 00861 00862 /* Find the appropriate structure, if already parsed */ 00863 while (cur_state != NULL) { 00864 if (cur_state->name[0] == '\0') 00865 break; 00866 cur_state = cur_state->next; 00867 } 00868 if (cur_state != NULL) 00869 return 0; 00870 cur_state = malloc(sizeof(struct state)); 00871 if (cur_state == NULL) { 00872 return -1; 00873 } 00874 memset(cur_state,0,sizeof(struct state)); 00875 if (tzload((char *) NULL, cur_state) != 0) 00876 #ifdef DEBUG 00877 { 00878 fprintf(stderr, "ast_tzsetwall: calling gmtload()\n"); 00879 #endif 00880 gmtload(cur_state); 00881 #ifdef DEBUG 00882 } 00883 #endif 00884 00885 if (last_lclptr) 00886 last_lclptr->next = cur_state; 00887 else 00888 lclptr = cur_state; 00889 last_lclptr = cur_state; 00890 return 0; 00891 }
static time_t transtime P | ( | (time_t janfirst, int year, const struct rule *rulep, long offset) | ) | [static] |
static int tmcomp P | ( | (const struct tm *atmp, const struct tm *btmp) | ) | [static] |
static void timesub P | ( | (const time_t *timep, long offset, const struct state *sp, struct tm *tmp) | ) | [static] |
static time_t time2 P | ( | (struct tm *tmp, void(*funcp) P((const time_t *, long, struct tm *, const char *)), long offset, int *okayp, const char *zone) | ) | [static] |
static time_t time1 P | ( | (struct tm *tmp, void(*funcp) P((const time_t *, long, struct tm *, const char *)), long offset, const char *zone) | ) | [static] |
static int normalize_overflow P | ( | (int *tensptr, int *unitsptr, int base) | ) | [static] |
static int increment_overflow P | ( | (int *number, int delta) | ) | [static] |
static void localsub P | ( | (const time_t *timep, long offset, struct tm *tmp, const char *zone) | ) | [static] |
static void gmtload P | ( | (struct state *sp) | ) | [static] |
static const char* getrule P | ( | (const char *strp, struct rule *rulep) | ) | [static] |
static const char* getoffset P | ( | (const char *strp, long *offsetp) | ) | [static] |
static const char* getsecs P | ( | (const char *strp, long *secsp) | ) | [static] |
static const char* getnum P | ( | (const char *strp, int *nump, int min, int max) | ) | [static] |
static long detzcode P | ( | (const char *codep) | ) | [static] |
static time_t time1 | ( | struct tm * const | tmp, | |
funcp | , | |||
const long | offset, | |||
const char * const | zone | |||
) | [static] |
Definition at line 1430 of file localtime.c.
References localsub(), t, time2(), ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, state::typecnt, and WRONG.
Referenced by ast_mktime().
01435 { 01436 register time_t t; 01437 register const struct state * sp; 01438 register int samei, otheri; 01439 int okay; 01440 01441 if (tmp->tm_isdst > 1) 01442 tmp->tm_isdst = 1; 01443 t = time2(tmp, funcp, offset, &okay, zone); 01444 #ifdef PCTS 01445 /* 01446 ** PCTS code courtesy Grant Sullivan (grant@osf.org). 01447 */ 01448 if (okay) 01449 return t; 01450 if (tmp->tm_isdst < 0) 01451 tmp->tm_isdst = 0; /* reset to std and try again */ 01452 #endif /* defined PCTS */ 01453 #ifndef PCTS 01454 if (okay || tmp->tm_isdst < 0) 01455 return t; 01456 #endif /* !defined PCTS */ 01457 /* 01458 ** We're supposed to assume that somebody took a time of one type 01459 ** and did some math on it that yielded a "struct tm" that's bad. 01460 ** We try to divine the type they started from and adjust to the 01461 ** type they need. 01462 */ 01463 /* 01464 ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. 01465 */ 01466 sp = (const struct state *) (((void *) funcp == (void *) localsub) ? 01467 lclptr : gmtptr); 01468 if (sp == NULL) 01469 return WRONG; 01470 for (samei = sp->typecnt - 1; samei >= 0; --samei) { 01471 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 01472 continue; 01473 for (otheri = sp->typecnt - 1; otheri >= 0; --otheri) { 01474 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) 01475 continue; 01476 tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - 01477 sp->ttis[samei].tt_gmtoff; 01478 tmp->tm_isdst = !tmp->tm_isdst; 01479 t = time2(tmp, funcp, offset, &okay, zone); 01480 if (okay) 01481 return t; 01482 tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - 01483 sp->ttis[samei].tt_gmtoff; 01484 tmp->tm_isdst = !tmp->tm_isdst; 01485 } 01486 } 01487 return WRONG; 01488 }
static time_t time2 | ( | struct tm * const | tmp, | |
funcp | , | |||
const long | offset, | |||
int * const | okayp, | |||
const char * const | zone | |||
) | [static] |
Definition at line 1285 of file localtime.c.
References DAYSPERLYEAR, EPOCH_YEAR, FALSE, HOURSPERDAY, increment_overflow(), isleap, localsub(), MINSPERHOUR, MONSPERYEAR, normalize_overflow(), SECSPERMIN, t, TM_YEAR_BASE, tmcomp(), TRUE, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, TYPE_BIT, TYPE_SIGNED, state::typecnt, and WRONG.
Referenced by time1().
01291 { 01292 register const struct state * sp; 01293 register int dir; 01294 register int bits; 01295 register int i, j ; 01296 register int saved_seconds; 01297 time_t newt; 01298 time_t t; 01299 struct tm yourtm, mytm; 01300 01301 *okayp = FALSE; 01302 yourtm = *tmp; 01303 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) 01304 return WRONG; 01305 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) 01306 return WRONG; 01307 if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR)) 01308 return WRONG; 01309 /* 01310 ** Turn yourtm.tm_year into an actual year number for now. 01311 ** It is converted back to an offset from TM_YEAR_BASE later. 01312 */ 01313 if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE)) 01314 return WRONG; 01315 while (yourtm.tm_mday <= 0) { 01316 if (increment_overflow(&yourtm.tm_year, -1)) 01317 return WRONG; 01318 i = yourtm.tm_year + (1 < yourtm.tm_mon); 01319 yourtm.tm_mday += year_lengths[isleap(i)]; 01320 } 01321 while (yourtm.tm_mday > DAYSPERLYEAR) { 01322 i = yourtm.tm_year + (1 < yourtm.tm_mon); 01323 yourtm.tm_mday -= year_lengths[isleap(i)]; 01324 if (increment_overflow(&yourtm.tm_year, 1)) 01325 return WRONG; 01326 } 01327 for ( ; ; ) { 01328 i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon]; 01329 if (yourtm.tm_mday <= i) 01330 break; 01331 yourtm.tm_mday -= i; 01332 if (++yourtm.tm_mon >= MONSPERYEAR) { 01333 yourtm.tm_mon = 0; 01334 if (increment_overflow(&yourtm.tm_year, 1)) 01335 return WRONG; 01336 } 01337 } 01338 if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE)) 01339 return WRONG; 01340 if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { 01341 /* 01342 ** We can't set tm_sec to 0, because that might push the 01343 ** time below the minimum representable time. 01344 ** Set tm_sec to 59 instead. 01345 ** This assumes that the minimum representable time is 01346 ** not in the same minute that a leap second was deleted from, 01347 ** which is a safer assumption than using 58 would be. 01348 */ 01349 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) 01350 return WRONG; 01351 saved_seconds = yourtm.tm_sec; 01352 yourtm.tm_sec = SECSPERMIN - 1; 01353 } else { 01354 saved_seconds = yourtm.tm_sec; 01355 yourtm.tm_sec = 0; 01356 } 01357 /* 01358 ** Divide the search space in half 01359 ** (this works whether time_t is signed or unsigned). 01360 */ 01361 bits = TYPE_BIT(time_t) - 1; 01362 /* 01363 ** If time_t is signed, then 0 is just above the median, 01364 ** assuming two's complement arithmetic. 01365 ** If time_t is unsigned, then (1 << bits) is just above the median. 01366 */ 01367 t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); 01368 for ( ; ; ) { 01369 (*funcp)(&t, offset, &mytm, zone); 01370 dir = tmcomp(&mytm, &yourtm); 01371 if (dir != 0) { 01372 if (bits-- < 0) 01373 return WRONG; 01374 if (bits < 0) 01375 --t; /* may be needed if new t is minimal */ 01376 else if (dir > 0) 01377 t -= ((time_t) 1) << bits; 01378 else t += ((time_t) 1) << bits; 01379 continue; 01380 } 01381 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 01382 break; 01383 /* 01384 ** Right time, wrong type. 01385 ** Hunt for right time, right type. 01386 ** It's okay to guess wrong since the guess 01387 ** gets checked. 01388 */ 01389 /* 01390 ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. 01391 */ 01392 sp = (const struct state *) 01393 (((void *) funcp == (void *) localsub) ? 01394 lclptr : gmtptr); 01395 if (sp == NULL) 01396 return WRONG; 01397 for (i = sp->typecnt - 1; i >= 0; --i) { 01398 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 01399 continue; 01400 for (j = sp->typecnt - 1; j >= 0; --j) { 01401 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 01402 continue; 01403 newt = t + sp->ttis[j].tt_gmtoff - 01404 sp->ttis[i].tt_gmtoff; 01405 (*funcp)(&newt, offset, &mytm, zone); 01406 if (tmcomp(&mytm, &yourtm) != 0) 01407 continue; 01408 if (mytm.tm_isdst != yourtm.tm_isdst) 01409 continue; 01410 /* 01411 ** We have a match. 01412 */ 01413 t = newt; 01414 goto label; 01415 } 01416 } 01417 return WRONG; 01418 } 01419 label: 01420 newt = t + saved_seconds; 01421 if ((newt < t) != (saved_seconds < 0)) 01422 return WRONG; 01423 t = newt; 01424 (*funcp)(&t, offset, tmp, zone); 01425 *okayp = TRUE; 01426 return t; 01427 }
static void timesub | ( | time_t * const | timep, | |
const long | offset, | |||
const struct state * const | sp, | |||
struct tm * const | tmp | |||
) | const [static] |
Definition at line 1106 of file localtime.c.
References days, DAYSPERNYEAR, DAYSPERWEEK, EPOCH_WDAY, EPOCH_YEAR, isleap, LEAPS_THRU_END_OF, lsinfo::ls_corr, lsinfo::ls_trans, SECSPERDAY, SECSPERHOUR, SECSPERMIN, and TM_YEAR_BASE.
Referenced by gmtsub(), and localsub().
01111 { 01112 register const struct lsinfo * lp; 01113 register long days; 01114 register long rem; 01115 register int y; 01116 register int yleap; 01117 register const int * ip; 01118 register long corr; 01119 register int hit; 01120 register int i; 01121 01122 corr = 0; 01123 hit = 0; 01124 i = (sp == NULL) ? 0 : sp->leapcnt; 01125 while (--i >= 0) { 01126 lp = &sp->lsis[i]; 01127 if (*timep >= lp->ls_trans) { 01128 if (*timep == lp->ls_trans) { 01129 hit = ((i == 0 && lp->ls_corr > 0) || 01130 lp->ls_corr > sp->lsis[i - 1].ls_corr); 01131 if (hit) 01132 while (i > 0 && 01133 sp->lsis[i].ls_trans == 01134 sp->lsis[i - 1].ls_trans + 1 && 01135 sp->lsis[i].ls_corr == 01136 sp->lsis[i - 1].ls_corr + 1) { 01137 ++hit; 01138 --i; 01139 } 01140 } 01141 corr = lp->ls_corr; 01142 break; 01143 } 01144 } 01145 days = *timep / SECSPERDAY; 01146 rem = *timep % SECSPERDAY; 01147 #ifdef mc68k 01148 if (*timep == 0x80000000) { 01149 /* 01150 ** A 3B1 muffs the division on the most negative number. 01151 */ 01152 days = -24855; 01153 rem = -11648; 01154 } 01155 #endif /* defined mc68k */ 01156 rem += (offset - corr); 01157 while (rem < 0) { 01158 rem += SECSPERDAY; 01159 --days; 01160 } 01161 while (rem >= SECSPERDAY) { 01162 rem -= SECSPERDAY; 01163 ++days; 01164 } 01165 tmp->tm_hour = (int) (rem / SECSPERHOUR); 01166 rem = rem % SECSPERHOUR; 01167 tmp->tm_min = (int) (rem / SECSPERMIN); 01168 /* 01169 ** A positive leap second requires a special 01170 ** representation. This uses "... ??:59:60" et seq. 01171 */ 01172 tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; 01173 tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); 01174 if (tmp->tm_wday < 0) 01175 tmp->tm_wday += DAYSPERWEEK; 01176 y = EPOCH_YEAR; 01177 #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) 01178 while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { 01179 register int newy; 01180 01181 newy = y + days / DAYSPERNYEAR; 01182 if (days < 0) 01183 --newy; 01184 days -= (newy - y) * DAYSPERNYEAR + 01185 LEAPS_THRU_END_OF(newy - 1) - 01186 LEAPS_THRU_END_OF(y - 1); 01187 y = newy; 01188 } 01189 tmp->tm_year = y - TM_YEAR_BASE; 01190 tmp->tm_yday = (int) days; 01191 ip = mon_lengths[yleap]; 01192 for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) 01193 days = days - (long) ip[tmp->tm_mon]; 01194 tmp->tm_mday = (int) (days + 1); 01195 tmp->tm_isdst = 0; 01196 #ifdef TM_GMTOFF 01197 tmp->TM_GMTOFF = offset; 01198 #endif /* defined TM_GMTOFF */ 01199 }
static int tmcomp | ( | const struct tm * const | atmp, | |
const struct tm * const | btmp | |||
) | [static] |
Definition at line 1269 of file localtime.c.
Referenced by time2().
01272 { 01273 register int result; 01274 01275 if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && 01276 (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 01277 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 01278 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 01279 (result = (atmp->tm_min - btmp->tm_min)) == 0) 01280 result = atmp->tm_sec - btmp->tm_sec; 01281 return result; 01282 }
static time_t transtime | ( | time_t | janfirst, | |
const int | year, | |||
const struct rule * const | rulep, | |||
const long | offset | |||
) | const [static] |
Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the year, a rule, and the offset from GMT at the time that rule takes effect, calculate the Epoch-relative time that rule takes effect.
Definition at line 554 of file localtime.c.
References DAY_OF_YEAR, DAYSPERWEEK, isleap, JULIAN_DAY, m1, MONTH_NTH_DAY_OF_WEEK, and SECSPERDAY.
Referenced by tzparse().
00559 { 00560 register int leapyear; 00561 register time_t value = 0; 00562 register int i; 00563 int d, m1, yy0, yy1, yy2, dow; 00564 00565 leapyear = isleap(year); 00566 switch (rulep->r_type) { 00567 00568 case JULIAN_DAY: 00569 /* 00570 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 00571 ** years. 00572 ** In non-leap years, or if the day number is 59 or less, just 00573 ** add SECSPERDAY times the day number-1 to the time of 00574 ** January 1, midnight, to get the day. 00575 */ 00576 value = janfirst + (rulep->r_day - 1) * SECSPERDAY; 00577 if (leapyear && rulep->r_day >= 60) 00578 value += SECSPERDAY; 00579 break; 00580 00581 case DAY_OF_YEAR: 00582 /* 00583 ** n - day of year. 00584 ** Just add SECSPERDAY times the day number to the time of 00585 ** January 1, midnight, to get the day. 00586 */ 00587 value = janfirst + rulep->r_day * SECSPERDAY; 00588 break; 00589 00590 case MONTH_NTH_DAY_OF_WEEK: 00591 /* 00592 ** Mm.n.d - nth "dth day" of month m. 00593 */ 00594 value = janfirst; 00595 for (i = 0; i < rulep->r_mon - 1; ++i) 00596 value += mon_lengths[leapyear][i] * SECSPERDAY; 00597 00598 /* 00599 ** Use Zeller's Congruence to get day-of-week of first day of 00600 ** month. 00601 */ 00602 m1 = (rulep->r_mon + 9) % 12 + 1; 00603 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; 00604 yy1 = yy0 / 100; 00605 yy2 = yy0 % 100; 00606 dow = ((26 * m1 - 2) / 10 + 00607 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; 00608 if (dow < 0) 00609 dow += DAYSPERWEEK; 00610 00611 /* 00612 ** "dow" is the day-of-week of the first day of the month. Get 00613 ** the day-of-month (zero-origin) of the first "dow" day of the 00614 ** month. 00615 */ 00616 d = rulep->r_day - dow; 00617 if (d < 0) 00618 d += DAYSPERWEEK; 00619 for (i = 1; i < rulep->r_week; ++i) { 00620 if (d + DAYSPERWEEK >= 00621 mon_lengths[leapyear][rulep->r_mon - 1]) 00622 break; 00623 d += DAYSPERWEEK; 00624 } 00625 00626 /* 00627 ** "d" is the day-of-month (zero-origin) of the day we want. 00628 */ 00629 value += d * SECSPERDAY; 00630 break; 00631 } 00632 00633 /* 00634 ** "value" is the Epoch-relative time of 00:00:00 GMT on the day in 00635 ** question. To get the Epoch-relative time of the specified local 00636 ** time on that day, add the transition time and the current offset 00637 ** from GMT. 00638 */ 00639 return value + rulep->r_time + offset; 00640 }
static int tzload | ( | register const char * | name, | |
register struct state *const | sp | |||
) | [static] |
Definition at line 243 of file localtime.c.
References detzcode(), FALSE, FILENAME_MAX, lsinfo::ls_corr, lsinfo::ls_trans, OPEN_MODE, TRUE, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, ttinfo::tt_ttisstd, TZ_MAX_CHARS, TZ_MAX_LEAPS, TZ_MAX_TIMES, TZ_MAX_TYPES, TZDEFAULT, TZDIR, tzhead::tzh_magic, and tzhead::tzh_reserved.
Referenced by gmtload(), P(), and tzparse().
00244 { 00245 register const char * p; 00246 register int i; 00247 register int fid; 00248 00249 #ifdef DEBUG 00250 fprintf(stderr,"tzload called with name=%s, sp=%d\n", name, sp); 00251 #endif 00252 if (name == NULL && (name = TZDEFAULT) == NULL) 00253 return -1; 00254 { 00255 register int doaccess; 00256 struct stat stab; 00257 /* 00258 ** Section 4.9.1 of the C standard says that 00259 ** "FILENAME_MAX expands to an integral constant expression 00260 ** that is the size needed for an array of char large enough 00261 ** to hold the longest file name string that the implementation 00262 ** guarantees can be opened." 00263 */ 00264 char fullname[FILENAME_MAX + 1] = ""; 00265 00266 if (name[0] == ':') 00267 ++name; 00268 doaccess = name[0] == '/'; 00269 if (!doaccess) { 00270 if ((p = TZDIR) == NULL) 00271 return -1; 00272 if ((strlen(p) + 1 + strlen(name) + 1) >= sizeof fullname) 00273 return -1; 00274 (void) strncpy(fullname, p, sizeof(fullname) - 1); 00275 (void) strncat(fullname, "/", sizeof(fullname) - strlen(fullname) - 1); 00276 (void) strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1); 00277 /* 00278 ** Set doaccess if '.' (as in "../") shows up in name. 00279 */ 00280 if (strchr(name, '.') != NULL) 00281 doaccess = TRUE; 00282 name = fullname; 00283 } 00284 if (doaccess && access(name, R_OK) != 0) 00285 return -1; 00286 if ((fid = open(name, OPEN_MODE)) == -1) 00287 return -1; 00288 if ((fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) { 00289 close(fid); 00290 return -1; 00291 } 00292 } 00293 { 00294 struct tzhead * tzhp; 00295 char buf[sizeof *sp + sizeof *tzhp]; 00296 int ttisstdcnt; 00297 int ttisgmtcnt; 00298 00299 i = read(fid, buf, sizeof buf); 00300 if (close(fid) != 0) 00301 return -1; 00302 p = buf; 00303 p += (sizeof tzhp->tzh_magic) + (sizeof tzhp->tzh_reserved); 00304 ttisstdcnt = (int) detzcode(p); 00305 p += 4; 00306 ttisgmtcnt = (int) detzcode(p); 00307 p += 4; 00308 sp->leapcnt = (int) detzcode(p); 00309 p += 4; 00310 sp->timecnt = (int) detzcode(p); 00311 p += 4; 00312 sp->typecnt = (int) detzcode(p); 00313 p += 4; 00314 sp->charcnt = (int) detzcode(p); 00315 p += 4; 00316 if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || 00317 sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || 00318 sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || 00319 sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || 00320 (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || 00321 (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) 00322 return -1; 00323 if (i - (p - buf) < sp->timecnt * 4 + /* ats */ 00324 sp->timecnt + /* types */ 00325 sp->typecnt * (4 + 2) + /* ttinfos */ 00326 sp->charcnt + /* chars */ 00327 sp->leapcnt * (4 + 4) + /* lsinfos */ 00328 ttisstdcnt + /* ttisstds */ 00329 ttisgmtcnt) /* ttisgmts */ 00330 return -1; 00331 for (i = 0; i < sp->timecnt; ++i) { 00332 sp->ats[i] = detzcode(p); 00333 p += 4; 00334 } 00335 for (i = 0; i < sp->timecnt; ++i) { 00336 sp->types[i] = (unsigned char) *p++; 00337 if (sp->types[i] >= sp->typecnt) 00338 return -1; 00339 } 00340 for (i = 0; i < sp->typecnt; ++i) { 00341 register struct ttinfo * ttisp; 00342 00343 ttisp = &sp->ttis[i]; 00344 ttisp->tt_gmtoff = detzcode(p); 00345 p += 4; 00346 ttisp->tt_isdst = (unsigned char) *p++; 00347 if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) 00348 return -1; 00349 ttisp->tt_abbrind = (unsigned char) *p++; 00350 if (ttisp->tt_abbrind < 0 || 00351 ttisp->tt_abbrind > sp->charcnt) 00352 return -1; 00353 } 00354 for (i = 0; i < sp->charcnt; ++i) 00355 sp->chars[i] = *p++; 00356 sp->chars[i] = '\0'; /* ensure '\0' at end */ 00357 for (i = 0; i < sp->leapcnt; ++i) { 00358 register struct lsinfo * lsisp; 00359 00360 lsisp = &sp->lsis[i]; 00361 lsisp->ls_trans = detzcode(p); 00362 p += 4; 00363 lsisp->ls_corr = detzcode(p); 00364 p += 4; 00365 } 00366 for (i = 0; i < sp->typecnt; ++i) { 00367 register struct ttinfo * ttisp; 00368 00369 ttisp = &sp->ttis[i]; 00370 if (ttisstdcnt == 0) 00371 ttisp->tt_ttisstd = FALSE; 00372 else { 00373 ttisp->tt_ttisstd = *p++; 00374 if (ttisp->tt_ttisstd != TRUE && 00375 ttisp->tt_ttisstd != FALSE) 00376 return -1; 00377 } 00378 } 00379 for (i = 0; i < sp->typecnt; ++i) { 00380 register struct ttinfo * ttisp; 00381 00382 ttisp = &sp->ttis[i]; 00383 if (ttisgmtcnt == 0) 00384 ttisp->tt_ttisgmt = FALSE; 00385 else { 00386 ttisp->tt_ttisgmt = *p++; 00387 if (ttisp->tt_ttisgmt != TRUE && 00388 ttisp->tt_ttisgmt != FALSE) 00389 return -1; 00390 } 00391 } 00392 } 00393 return 0; 00394 }
static int tzparse | ( | char * | name, | |
struct state * const | sp, | |||
const int | lastditch | |||
) | const [static] |
Definition at line 648 of file localtime.c.
References EPOCH_YEAR, FALSE, getoffset(), getrule(), isleap, SECSPERDAY, SECSPERHOUR, starttime, transtime(), TRUE, TZ_MAX_TIMES, TZDEFRULES, and tzload().
Referenced by gmtload(), and P().
00652 { 00653 const char * stdname; 00654 const char * dstname = NULL; 00655 size_t stdlen = 0; 00656 size_t dstlen = 0; 00657 long stdoffset = 0L; 00658 long dstoffset = 0L; 00659 register time_t * atp; 00660 register unsigned char * typep; 00661 register char * cp; 00662 register int load_result; 00663 00664 stdname = name; 00665 #ifdef DEBUG 00666 fprintf(stderr, "tzparse(): loading default rules\n"); 00667 #endif 00668 load_result = tzload(TZDEFRULES, sp); 00669 if (load_result != 0) 00670 sp->leapcnt = 0; /* so, we're off a little */ 00671 if (*name != '\0') { 00672 if (*name != '\0' && *name != ',' && *name != ';') { 00673 name = getoffset(name, &dstoffset); 00674 if (name == NULL) 00675 return -1; 00676 } else dstoffset = stdoffset - SECSPERHOUR; 00677 if (*name == ',' || *name == ';') { 00678 struct rule start; 00679 struct rule end; 00680 register int year; 00681 register time_t janfirst; 00682 time_t starttime; 00683 time_t endtime; 00684 00685 ++name; 00686 if ((name = getrule(name, &start)) == NULL) 00687 return -1; 00688 if (*name++ != ',') 00689 return -1; 00690 if ((name = getrule(name, &end)) == NULL) 00691 return -1; 00692 if (*name != '\0') 00693 return -1; 00694 sp->typecnt = 2; /* standard time and DST */ 00695 /* 00696 ** Two transitions per year, from EPOCH_YEAR to 2037. 00697 */ 00698 sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1); 00699 if (sp->timecnt > TZ_MAX_TIMES) 00700 return -1; 00701 sp->ttis[0].tt_gmtoff = -dstoffset; 00702 sp->ttis[0].tt_isdst = 1; 00703 sp->ttis[0].tt_abbrind = stdlen + 1; 00704 sp->ttis[1].tt_gmtoff = -stdoffset; 00705 sp->ttis[1].tt_isdst = 0; 00706 sp->ttis[1].tt_abbrind = 0; 00707 atp = sp->ats; 00708 typep = sp->types; 00709 janfirst = 0; 00710 for (year = EPOCH_YEAR; year <= 2037; ++year) { 00711 starttime = transtime(janfirst, year, &start, 00712 stdoffset); 00713 endtime = transtime(janfirst, year, &end, 00714 dstoffset); 00715 if (starttime > endtime) { 00716 *atp++ = endtime; 00717 *typep++ = 1; /* DST ends */ 00718 *atp++ = starttime; 00719 *typep++ = 0; /* DST begins */ 00720 } else { 00721 *atp++ = starttime; 00722 *typep++ = 0; /* DST begins */ 00723 *atp++ = endtime; 00724 *typep++ = 1; /* DST ends */ 00725 } 00726 janfirst += year_lengths[isleap(year)] * 00727 SECSPERDAY; 00728 } 00729 } else { 00730 register long theirstdoffset; 00731 register long theirdstoffset; 00732 register long theiroffset; 00733 register int isdst; 00734 register int i; 00735 register int j; 00736 00737 if (*name != '\0') 00738 return -1; 00739 if (load_result != 0) 00740 return -1; 00741 /* 00742 ** Initial values of theirstdoffset and theirdstoffset. 00743 */ 00744 theirstdoffset = 0; 00745 for (i = 0; i < sp->timecnt; ++i) { 00746 j = sp->types[i]; 00747 if (!sp->ttis[j].tt_isdst) { 00748 theirstdoffset = 00749 -sp->ttis[j].tt_gmtoff; 00750 break; 00751 } 00752 } 00753 theirdstoffset = 0; 00754 for (i = 0; i < sp->timecnt; ++i) { 00755 j = sp->types[i]; 00756 if (sp->ttis[j].tt_isdst) { 00757 theirdstoffset = 00758 -sp->ttis[j].tt_gmtoff; 00759 break; 00760 } 00761 } 00762 /* 00763 ** Initially we're assumed to be in standard time. 00764 */ 00765 isdst = FALSE; 00766 theiroffset = theirstdoffset; 00767 /* 00768 ** Now juggle transition times and types 00769 ** tracking offsets as you do. 00770 */ 00771 for (i = 0; i < sp->timecnt; ++i) { 00772 j = sp->types[i]; 00773 sp->types[i] = sp->ttis[j].tt_isdst; 00774 if (sp->ttis[j].tt_ttisgmt) { 00775 /* No adjustment to transition time */ 00776 } else { 00777 /* 00778 ** If summer time is in effect, and the 00779 ** transition time was not specified as 00780 ** standard time, add the summer time 00781 ** offset to the transition time; 00782 ** otherwise, add the standard time 00783 ** offset to the transition time. 00784 */ 00785 /* 00786 ** Transitions from DST to DDST 00787 ** will effectively disappear since 00788 ** POSIX provides for only one DST 00789 ** offset. 00790 */ 00791 if (isdst && !sp->ttis[j].tt_ttisstd) { 00792 sp->ats[i] += dstoffset - 00793 theirdstoffset; 00794 } else { 00795 sp->ats[i] += stdoffset - 00796 theirstdoffset; 00797 } 00798 } 00799 theiroffset = -sp->ttis[j].tt_gmtoff; 00800 if (sp->ttis[j].tt_isdst) 00801 theirdstoffset = theiroffset; 00802 else theirstdoffset = theiroffset; 00803 } 00804 /* 00805 ** Finally, fill in ttis. 00806 ** ttisstd and ttisgmt need not be handled. 00807 */ 00808 sp->ttis[0].tt_gmtoff = -stdoffset; 00809 sp->ttis[0].tt_isdst = FALSE; 00810 sp->ttis[0].tt_abbrind = 0; 00811 sp->ttis[1].tt_gmtoff = -dstoffset; 00812 sp->ttis[1].tt_isdst = TRUE; 00813 sp->ttis[1].tt_abbrind = stdlen + 1; 00814 } 00815 } else { 00816 dstlen = 0; 00817 sp->typecnt = 1; /* only standard time */ 00818 sp->timecnt = 0; 00819 sp->ttis[0].tt_gmtoff = -stdoffset; 00820 sp->ttis[0].tt_isdst = 0; 00821 sp->ttis[0].tt_abbrind = 0; 00822 } 00823 sp->charcnt = stdlen + 1; 00824 if (dstlen != 0) 00825 sp->charcnt += dstlen + 1; 00826 if (sp->charcnt > sizeof sp->chars) 00827 return -1; 00828 cp = sp->chars; 00829 (void) strncpy(cp, stdname, stdlen); 00830 cp += stdlen; 00831 *cp++ = '\0'; 00832 if (dstlen != 0) { 00833 (void) strncpy(cp, dstname, dstlen); 00834 *(cp + dstlen) = '\0'; 00835 } 00836 return 0; 00837 }
const char elsieid[] = "@(#)localtime.c 7.57" [static] |
Definition at line 68 of file localtime.c.
char gmt[] = "GMT" [static] |
FreeBSD defines 'zone' in 'struct tm' as non-const, so don't declare this string as const.
time type information
Definition at line 119 of file localtime.c.
int gmt_is_set [static] |
Definition at line 216 of file localtime.c.
Definition at line 210 of file localtime.c.
struct state* last_lclptr = NULL [static] |
Definition at line 209 of file localtime.c.
Definition at line 208 of file localtime.c.
const int mon_lengths[2][MONSPERYEAR] [static] |
Initial value:
{ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }
Definition at line 396 of file localtime.c.
char wildabbr[] = "WILDABBR" [static] |
Definition at line 114 of file localtime.c.
const int year_lengths[2] [static] |