Deleted Added
full compact
localtime.c (177824) localtime.c (192625)
1/*
2** This file is in the public domain, so clarified as of
1/*
2** This file is in the public domain, so clarified as of
3** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
3** 1996-06-05 by Arthur David Olson.
4*/
5
6#include <sys/cdefs.h>
7#ifndef lint
8#ifndef NOID
4*/
5
6#include <sys/cdefs.h>
7#ifndef lint
8#ifndef NOID
9static char elsieid[] __unused = "@(#)localtime.c 7.78";
9static char elsieid[] __unused = "@(#)localtime.c 8.9";
10#endif /* !defined NOID */
11#endif /* !defined lint */
10#endif /* !defined NOID */
11#endif /* !defined lint */
12__FBSDID("$FreeBSD: head/lib/libc/stdtime/localtime.c 177824 2008-04-01 06:56:11Z davidxu $");
12__FBSDID("$FreeBSD: head/lib/libc/stdtime/localtime.c 192625 2009-05-23 06:31:50Z edwin $");
13
14/*
13
14/*
15** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu).
16** POSIX-style TZ environment variable handling from Guy Harris
17** (guy@auspex.com).
15** Leap second handling from Bradley White.
16** POSIX-style TZ environment variable handling from Guy Harris.
18*/
19
20/*LINTLIBRARY*/
21
22#include "namespace.h"
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <pthread.h>
27#include "private.h"
28#include "un-namespace.h"
29
30#include "tzfile.h"
17*/
18
19/*LINTLIBRARY*/
20
21#include "namespace.h"
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <fcntl.h>
25#include <pthread.h>
26#include "private.h"
27#include "un-namespace.h"
28
29#include "tzfile.h"
30#include "float.h" /* for FLT_MAX and DBL_MAX */
31
31
32#ifndef TZ_ABBR_MAX_LEN
33#define TZ_ABBR_MAX_LEN 16
34#endif /* !defined TZ_ABBR_MAX_LEN */
35
36#ifndef TZ_ABBR_CHAR_SET
37#define TZ_ABBR_CHAR_SET \
38 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
39#endif /* !defined TZ_ABBR_CHAR_SET */
40
41#ifndef TZ_ABBR_ERR_CHAR
42#define TZ_ABBR_ERR_CHAR '_'
43#endif /* !defined TZ_ABBR_ERR_CHAR */
44
32#include "libc_private.h"
33
34#define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x)
35#define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x)
36
37#define _RWLOCK_RDLOCK(x) \
38 do { \
39 if (__isthreaded) _pthread_rwlock_rdlock(x); \

--- 29 unchanged lines hidden (view full) ---

69** or implicitly).
70** 3. They might reference tzname[1] after setting to a time zone
71** in which Daylight Saving Time is never observed.
72** 4. They might reference tzname[0] after setting to a time zone
73** in which Standard Time is never observed.
74** 5. They might reference tm.TM_ZONE after calling offtime.
75** What's best to do in the above cases is open to debate;
76** for now, we just set things up so that in any of the five cases
45#include "libc_private.h"
46
47#define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x)
48#define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x)
49
50#define _RWLOCK_RDLOCK(x) \
51 do { \
52 if (__isthreaded) _pthread_rwlock_rdlock(x); \

--- 29 unchanged lines hidden (view full) ---

82** or implicitly).
83** 3. They might reference tzname[1] after setting to a time zone
84** in which Daylight Saving Time is never observed.
85** 4. They might reference tzname[0] after setting to a time zone
86** in which Standard Time is never observed.
87** 5. They might reference tm.TM_ZONE after calling offtime.
88** What's best to do in the above cases is open to debate;
89** for now, we just set things up so that in any of the five cases
77** WILDABBR is used. Another possibility: initialize tzname[0] to the
90** WILDABBR is used. Another possibility: initialize tzname[0] to the
78** string "tzname[0] used before set", and similarly for the other cases.
91** string "tzname[0] used before set", and similarly for the other cases.
79** And another: initialize tzname[0] to "ERA", with an explanation in the
92** And another: initialize tzname[0] to "ERA", with an explanation in the
80** manual page of what this "time zone abbreviation" means (doing this so
81** that tzname[0] has the "normal" length of three characters).
82*/
83#define WILDABBR " "
84#endif /* !defined WILDABBR */
85
93** manual page of what this "time zone abbreviation" means (doing this so
94** that tzname[0] has the "normal" length of three characters).
95*/
96#define WILDABBR " "
97#endif /* !defined WILDABBR */
98
86static char wildabbr[] = "WILDABBR";
99static char wildabbr[] = WILDABBR;
87
88/*
89 * In June 2004 it was decided UTC was a more appropriate default time
90 * zone than GMT.
91 */
92
93static const char gmt[] = "UTC";
94

--- 30 unchanged lines hidden (view full) ---

125#define MY_TZNAME_MAX 255
126#endif /* !defined TZNAME_MAX */
127
128struct state {
129 int leapcnt;
130 int timecnt;
131 int typecnt;
132 int charcnt;
100
101/*
102 * In June 2004 it was decided UTC was a more appropriate default time
103 * zone than GMT.
104 */
105
106static const char gmt[] = "UTC";
107

--- 30 unchanged lines hidden (view full) ---

138#define MY_TZNAME_MAX 255
139#endif /* !defined TZNAME_MAX */
140
141struct state {
142 int leapcnt;
143 int timecnt;
144 int typecnt;
145 int charcnt;
146 int goback;
147 int goahead;
133 time_t ats[TZ_MAX_TIMES];
134 unsigned char types[TZ_MAX_TIMES];
135 struct ttinfo ttis[TZ_MAX_TYPES];
136 char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
137 (2 * (MY_TZNAME_MAX + 1)))];
138 struct lsinfo lsis[TZ_MAX_LEAPS];
139};
140

--- 9 unchanged lines hidden (view full) ---

150#define DAY_OF_YEAR 1 /* n - day of year */
151#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
152
153/*
154** Prototypes for static functions.
155*/
156
157static long detzcode(const char * codep);
148 time_t ats[TZ_MAX_TIMES];
149 unsigned char types[TZ_MAX_TIMES];
150 struct ttinfo ttis[TZ_MAX_TYPES];
151 char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
152 (2 * (MY_TZNAME_MAX + 1)))];
153 struct lsinfo lsis[TZ_MAX_LEAPS];
154};
155

--- 9 unchanged lines hidden (view full) ---

165#define DAY_OF_YEAR 1 /* n - day of year */
166#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
167
168/*
169** Prototypes for static functions.
170*/
171
172static long detzcode(const char * codep);
173static time_t detzcode64(const char * codep);
174static int differ_by_repeat(time_t t1, time_t t0);
158static const char * getzname(const char * strp);
175static const char * getzname(const char * strp);
176static const char * getqzname(const char * strp, const int delim);
159static const char * getnum(const char * strp, int * nump, int min,
160 int max);
161static const char * getsecs(const char * strp, long * secsp);
162static const char * getoffset(const char * strp, long * offsetp);
163static const char * getrule(const char * strp, struct rule * rulep);
164static void gmtload(struct state * sp);
177static const char * getnum(const char * strp, int * nump, int min,
178 int max);
179static const char * getsecs(const char * strp, long * secsp);
180static const char * getoffset(const char * strp, long * offsetp);
181static const char * getrule(const char * strp, struct rule * rulep);
182static void gmtload(struct state * sp);
165static void gmtsub(const time_t * timep, long offset,
183static struct tm * gmtsub(const time_t * timep, long offset,
166 struct tm * tmp);
184 struct tm * tmp);
167static void localsub(const time_t * timep, long offset,
185static struct tm * localsub(const time_t * timep, long offset,
168 struct tm * tmp);
169static int increment_overflow(int * number, int delta);
186 struct tm * tmp);
187static int increment_overflow(int * number, int delta);
188static int leaps_thru_end_of(int y);
189static int long_increment_overflow(long * number, int delta);
190static int long_normalize_overflow(long * tensptr,
191 int * unitsptr, int base);
170static int normalize_overflow(int * tensptr, int * unitsptr,
171 int base);
172static void settzname(void);
173static time_t time1(struct tm * tmp,
192static int normalize_overflow(int * tensptr, int * unitsptr,
193 int base);
194static void settzname(void);
195static time_t time1(struct tm * tmp,
174 void(*funcp) (const time_t *,
196 struct tm * (*funcp)(const time_t *,
175 long, struct tm *),
176 long offset);
177static time_t time2(struct tm *tmp,
197 long, struct tm *),
198 long offset);
199static time_t time2(struct tm *tmp,
178 void(*funcp) (const time_t *,
200 struct tm * (*funcp)(const time_t *,
179 long, struct tm*),
180 long offset, int * okayp);
181static time_t time2sub(struct tm *tmp,
201 long, struct tm*),
202 long offset, int * okayp);
203static time_t time2sub(struct tm *tmp,
182 void(*funcp) (const time_t *,
204 struct tm * (*funcp)(const time_t *,
183 long, struct tm*),
184 long offset, int * okayp, int do_norm_secs);
205 long, struct tm*),
206 long offset, int * okayp, int do_norm_secs);
185static void timesub(const time_t * timep, long offset,
207static struct tm * timesub(const time_t * timep, long offset,
186 const struct state * sp, struct tm * tmp);
187static int tmcomp(const struct tm * atmp,
188 const struct tm * btmp);
189static time_t transtime(time_t janfirst, int year,
190 const struct rule * rulep, long offset);
208 const struct state * sp, struct tm * tmp);
209static int tmcomp(const struct tm * atmp,
210 const struct tm * btmp);
211static time_t transtime(time_t janfirst, int year,
212 const struct rule * rulep, long offset);
191static int tzload(const char * name, struct state * sp);
213static int typesequiv(const struct state * sp, int a, int b);
214static int tzload(const char * name, struct state * sp,
215 int doextend);
192static int tzparse(const char * name, struct state * sp,
193 int lastditch);
194
195#ifdef ALL_STATE
196static struct state * lclptr;
197static struct state * gmtptr;
198#endif /* defined ALL_STATE */
199

--- 19 unchanged lines hidden (view full) ---

219 wildabbr
220};
221
222/*
223** Section 4.12.3 of X3.159-1989 requires that
224** Except for the strftime function, these functions [asctime,
225** ctime, gmtime, localtime] return values in one of two static
226** objects: a broken-down time structure and an array of char.
216static int tzparse(const char * name, struct state * sp,
217 int lastditch);
218
219#ifdef ALL_STATE
220static struct state * lclptr;
221static struct state * gmtptr;
222#endif /* defined ALL_STATE */
223

--- 19 unchanged lines hidden (view full) ---

243 wildabbr
244};
245
246/*
247** Section 4.12.3 of X3.159-1989 requires that
248** Except for the strftime function, these functions [asctime,
249** ctime, gmtime, localtime] return values in one of two static
250** objects: a broken-down time structure and an array of char.
227** Thanks to Paul Eggert (eggert@twinsun.com) for noting this.
251** Thanks to Paul Eggert for noting this.
228*/
229
230static struct tm tm;
231
232#ifdef USG_COMPAT
233time_t timezone = 0;
234int daylight = 0;
235#endif /* defined USG_COMPAT */

--- 4 unchanged lines hidden (view full) ---

240
241static long
242detzcode(codep)
243const char * const codep;
244{
245 long result;
246 int i;
247
252*/
253
254static struct tm tm;
255
256#ifdef USG_COMPAT
257time_t timezone = 0;
258int daylight = 0;
259#endif /* defined USG_COMPAT */

--- 4 unchanged lines hidden (view full) ---

264
265static long
266detzcode(codep)
267const char * const codep;
268{
269 long result;
270 int i;
271
248 result = (codep[0] & 0x80) ? ~0L : 0L;
272 result = (codep[0] & 0x80) ? ~0L : 0;
249 for (i = 0; i < 4; ++i)
250 result = (result << 8) | (codep[i] & 0xff);
251 return result;
252}
253
273 for (i = 0; i < 4; ++i)
274 result = (result << 8) | (codep[i] & 0xff);
275 return result;
276}
277
278static time_t
279detzcode64(codep)
280const char * const codep;
281{
282 register time_t result;
283 register int i;
284
285 result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0;
286 for (i = 0; i < 8; ++i)
287 result = result * 256 + (codep[i] & 0xff);
288 return result;
289}
290
254static void
255settzname(void)
256{
257 struct state * sp = lclptr;
258 int i;
259
260 tzname[0] = wildabbr;
261 tzname[1] = wildabbr;

--- 32 unchanged lines hidden (view full) ---

294 for (i = 0; i < sp->timecnt; ++i) {
295 const struct ttinfo * const ttisp =
296 &sp->ttis[
297 sp->types[i]];
298
299 tzname[ttisp->tt_isdst] =
300 &sp->chars[ttisp->tt_abbrind];
301 }
291static void
292settzname(void)
293{
294 struct state * sp = lclptr;
295 int i;
296
297 tzname[0] = wildabbr;
298 tzname[1] = wildabbr;

--- 32 unchanged lines hidden (view full) ---

331 for (i = 0; i < sp->timecnt; ++i) {
332 const struct ttinfo * const ttisp =
333 &sp->ttis[
334 sp->types[i]];
335
336 tzname[ttisp->tt_isdst] =
337 &sp->chars[ttisp->tt_abbrind];
338 }
339 /*
340 ** Finally, scrub the abbreviations.
341 ** First, replace bogus characters.
342 */
343 for (i = 0; i < sp->charcnt; ++i)
344 if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
345 sp->chars[i] = TZ_ABBR_ERR_CHAR;
346 /*
347 ** Second, truncate long abbreviations.
348 */
349 for (i = 0; i < sp->typecnt; ++i) {
350 register const struct ttinfo * const ttisp = &sp->ttis[i];
351 register char * cp = &sp->chars[ttisp->tt_abbrind];
352
353 if (strlen(cp) > TZ_ABBR_MAX_LEN &&
354 strcmp(cp, GRANDPARENTED) != 0)
355 *(cp + TZ_ABBR_MAX_LEN) = '\0';
356 }
302}
303
304static int
357}
358
359static int
305tzload(name, sp)
360differ_by_repeat(t1, t0)
361const time_t t1;
362const time_t t0;
363{
364 int_fast64_t _t0 = t0;
365 int_fast64_t _t1 = t1;
366
367 if (TYPE_INTEGRAL(time_t) &&
368 TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
369 return 0;
370 //turn ((int_fast64_t)(t1 - t0) == SECSPERREPEAT);
371 return _t1 - _t0 == SECSPERREPEAT;
372}
373
374static int
375tzload(name, sp, doextend)
306const char * name;
307struct state * const sp;
376const char * name;
377struct state * const sp;
378register const int doextend;
308{
309 const char * p;
310 int i;
311 int fid;
379{
380 const char * p;
381 int i;
382 int fid;
383 int stored;
384 int nread;
385 union {
386 struct tzhead tzhead;
387 char buf[2 * sizeof(struct tzhead) +
388 2 * sizeof *sp +
389 4 * TZ_MAX_TIMES];
390 } u;
312
313 /* XXX The following is from OpenBSD, and I'm not sure it is correct */
314 if (name != NULL && issetugid() != 0)
315 if ((name[0] == ':' && name[1] == '/') ||
316 name[0] == '/' || strchr(name, '.'))
317 name = NULL;
318 if (name == NULL && (name = TZDEFAULT) == NULL)
319 return -1;

--- 31 unchanged lines hidden (view full) ---

351 return -1;
352 if ((fid = _open(name, OPEN_MODE)) == -1)
353 return -1;
354 if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) {
355 _close(fid);
356 return -1;
357 }
358 }
391
392 /* XXX The following is from OpenBSD, and I'm not sure it is correct */
393 if (name != NULL && issetugid() != 0)
394 if ((name[0] == ':' && name[1] == '/') ||
395 name[0] == '/' || strchr(name, '.'))
396 name = NULL;
397 if (name == NULL && (name = TZDEFAULT) == NULL)
398 return -1;

--- 31 unchanged lines hidden (view full) ---

430 return -1;
431 if ((fid = _open(name, OPEN_MODE)) == -1)
432 return -1;
433 if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) {
434 _close(fid);
435 return -1;
436 }
437 }
359 {
360 struct tzhead * tzhp;
361 union {
362 struct tzhead tzhead;
363 char buf[sizeof *sp + sizeof *tzhp];
364 } u;
438 nread = _read(fid, u.buf, sizeof u.buf);
439 if (_close(fid) < 0 || nread <= 0)
440 return -1;
441 for (stored = 4; stored <= 8; stored *= 2) {
365 int ttisstdcnt;
366 int ttisgmtcnt;
367
442 int ttisstdcnt;
443 int ttisgmtcnt;
444
368 i = _read(fid, u.buf, sizeof u.buf);
369 if (_close(fid) != 0)
370 return -1;
371 ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
372 ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
373 sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
374 sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
375 sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
376 sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
377 p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
378 if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
379 sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
380 sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
381 sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
382 (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
383 (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
384 return -1;
445 ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
446 ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
447 sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
448 sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
449 sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
450 sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
451 p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
452 if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
453 sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
454 sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
455 sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
456 (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
457 (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
458 return -1;
385 if (i - (p - u.buf) < sp->timecnt * 4 + /* ats */
459 if (nread - (p - u.buf) <
460 sp->timecnt * stored + /* ats */
386 sp->timecnt + /* types */
461 sp->timecnt + /* types */
387 sp->typecnt * (4 + 2) + /* ttinfos */
462 sp->typecnt * 6 + /* ttinfos */
388 sp->charcnt + /* chars */
463 sp->charcnt + /* chars */
389 sp->leapcnt * (4 + 4) + /* lsinfos */
464 sp->leapcnt * (stored + 4) + /* lsinfos */
390 ttisstdcnt + /* ttisstds */
391 ttisgmtcnt) /* ttisgmts */
392 return -1;
393 for (i = 0; i < sp->timecnt; ++i) {
465 ttisstdcnt + /* ttisstds */
466 ttisgmtcnt) /* ttisgmts */
467 return -1;
468 for (i = 0; i < sp->timecnt; ++i) {
394 sp->ats[i] = detzcode(p);
395 p += 4;
469 sp->ats[i] = (stored == 4) ?
470 detzcode(p) : detzcode64(p);
471 p += stored;
396 }
397 for (i = 0; i < sp->timecnt; ++i) {
398 sp->types[i] = (unsigned char) *p++;
399 if (sp->types[i] >= sp->typecnt)
400 return -1;
401 }
402 for (i = 0; i < sp->typecnt; ++i) {
403 struct ttinfo * ttisp;

--- 11 unchanged lines hidden (view full) ---

415 }
416 for (i = 0; i < sp->charcnt; ++i)
417 sp->chars[i] = *p++;
418 sp->chars[i] = '\0'; /* ensure '\0' at end */
419 for (i = 0; i < sp->leapcnt; ++i) {
420 struct lsinfo * lsisp;
421
422 lsisp = &sp->lsis[i];
472 }
473 for (i = 0; i < sp->timecnt; ++i) {
474 sp->types[i] = (unsigned char) *p++;
475 if (sp->types[i] >= sp->typecnt)
476 return -1;
477 }
478 for (i = 0; i < sp->typecnt; ++i) {
479 struct ttinfo * ttisp;

--- 11 unchanged lines hidden (view full) ---

491 }
492 for (i = 0; i < sp->charcnt; ++i)
493 sp->chars[i] = *p++;
494 sp->chars[i] = '\0'; /* ensure '\0' at end */
495 for (i = 0; i < sp->leapcnt; ++i) {
496 struct lsinfo * lsisp;
497
498 lsisp = &sp->lsis[i];
423 lsisp->ls_trans = detzcode(p);
424 p += 4;
499 lsisp->ls_trans = (stored == 4) ?
500 detzcode(p) : detzcode64(p);
501 p += stored;
425 lsisp->ls_corr = detzcode(p);
426 p += 4;
427 }
428 for (i = 0; i < sp->typecnt; ++i) {
429 struct ttinfo * ttisp;
430
431 ttisp = &sp->ttis[i];
432 if (ttisstdcnt == 0)

--- 13 unchanged lines hidden (view full) ---

446 ttisp->tt_ttisgmt = FALSE;
447 else {
448 ttisp->tt_ttisgmt = *p++;
449 if (ttisp->tt_ttisgmt != TRUE &&
450 ttisp->tt_ttisgmt != FALSE)
451 return -1;
452 }
453 }
502 lsisp->ls_corr = detzcode(p);
503 p += 4;
504 }
505 for (i = 0; i < sp->typecnt; ++i) {
506 struct ttinfo * ttisp;
507
508 ttisp = &sp->ttis[i];
509 if (ttisstdcnt == 0)

--- 13 unchanged lines hidden (view full) ---

523 ttisp->tt_ttisgmt = FALSE;
524 else {
525 ttisp->tt_ttisgmt = *p++;
526 if (ttisp->tt_ttisgmt != TRUE &&
527 ttisp->tt_ttisgmt != FALSE)
528 return -1;
529 }
530 }
531 /*
532 ** Out-of-sort ats should mean we're running on a
533 ** signed time_t system but using a data file with
534 ** unsigned values (or vice versa).
535 */
536 for (i = 0; i < sp->timecnt - 2; ++i)
537 if (sp->ats[i] > sp->ats[i + 1]) {
538 ++i;
539 if (TYPE_SIGNED(time_t)) {
540 /*
541 ** Ignore the end (easy).
542 */
543 sp->timecnt = i;
544 } else {
545 /*
546 ** Ignore the beginning (harder).
547 */
548 register int j;
549
550 for (j = 0; j + i < sp->timecnt; ++j) {
551 sp->ats[j] = sp->ats[j + i];
552 sp->types[j] = sp->types[j + i];
553 }
554 sp->timecnt = j;
555 }
556 break;
557 }
558 /*
559 ** If this is an old file, we're done.
560 */
561 if (u.tzhead.tzh_version[0] == '\0')
562 break;
563 nread -= p - u.buf;
564 for (i = 0; i < nread; ++i)
565 u.buf[i] = p[i];
566 /*
567 ** If this is a narrow integer time_t system, we're done.
568 */
569 if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
570 break;
454 }
571 }
572 if (doextend && nread > 2 &&
573 u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
574 sp->typecnt + 2 <= TZ_MAX_TYPES) {
575 struct state ts;
576 register int result;
577
578 u.buf[nread - 1] = '\0';
579 result = tzparse(&u.buf[1], &ts, FALSE);
580 if (result == 0 && ts.typecnt == 2 &&
581 sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
582 for (i = 0; i < 2; ++i)
583 ts.ttis[i].tt_abbrind +=
584 sp->charcnt;
585 for (i = 0; i < ts.charcnt; ++i)
586 sp->chars[sp->charcnt++] =
587 ts.chars[i];
588 i = 0;
589 while (i < ts.timecnt &&
590 ts.ats[i] <=
591 sp->ats[sp->timecnt - 1])
592 ++i;
593 while (i < ts.timecnt &&
594 sp->timecnt < TZ_MAX_TIMES) {
595 sp->ats[sp->timecnt] =
596 ts.ats[i];
597 sp->types[sp->timecnt] =
598 sp->typecnt +
599 ts.types[i];
600 ++sp->timecnt;
601 ++i;
602 }
603 sp->ttis[sp->typecnt++] = ts.ttis[0];
604 sp->ttis[sp->typecnt++] = ts.ttis[1];
605 }
606 }
607 sp->goback = sp->goahead = FALSE;
608 if (sp->timecnt > 1) {
609 for (i = 1; i < sp->timecnt; ++i)
610 if (typesequiv(sp, sp->types[i], sp->types[0]) &&
611 differ_by_repeat(sp->ats[i], sp->ats[0])) {
612 sp->goback = TRUE;
613 break;
614 }
615 for (i = sp->timecnt - 2; i >= 0; --i)
616 if (typesequiv(sp, sp->types[sp->timecnt - 1],
617 sp->types[i]) &&
618 differ_by_repeat(sp->ats[sp->timecnt - 1],
619 sp->ats[i])) {
620 sp->goahead = TRUE;
621 break;
622 }
623 }
455 return 0;
456}
457
624 return 0;
625}
626
627static int
628typesequiv(sp, a, b)
629const struct state * const sp;
630const int a;
631const int b;
632{
633 register int result;
634
635 if (sp == NULL ||
636 a < 0 || a >= sp->typecnt ||
637 b < 0 || b >= sp->typecnt)
638 result = FALSE;
639 else {
640 register const struct ttinfo * ap = &sp->ttis[a];
641 register const struct ttinfo * bp = &sp->ttis[b];
642 result = ap->tt_gmtoff == bp->tt_gmtoff &&
643 ap->tt_isdst == bp->tt_isdst &&
644 ap->tt_ttisstd == bp->tt_ttisstd &&
645 ap->tt_ttisgmt == bp->tt_ttisgmt &&
646 strcmp(&sp->chars[ap->tt_abbrind],
647 &sp->chars[bp->tt_abbrind]) == 0;
648 }
649 return result;
650}
651
458static const int mon_lengths[2][MONSPERYEAR] = {
459 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
460 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
461};
462
463static const int year_lengths[2] = {
464 DAYSPERNYEAR, DAYSPERLYEAR
465};
466
467/*
468** Given a pointer into a time zone string, scan until a character that is not
652static const int mon_lengths[2][MONSPERYEAR] = {
653 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
654 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
655};
656
657static const int year_lengths[2] = {
658 DAYSPERNYEAR, DAYSPERLYEAR
659};
660
661/*
662** Given a pointer into a time zone string, scan until a character that is not
469** a valid character in a zone name is found. Return a pointer to that
663** a valid character in a zone name is found. Return a pointer to that
470** character.
471*/
472
473static const char *
474getzname(strp)
475const char * strp;
476{
477 char c;
478
479 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
480 c != '+')
481 ++strp;
482 return strp;
483}
484
485/*
664** character.
665*/
666
667static const char *
668getzname(strp)
669const char * strp;
670{
671 char c;
672
673 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
674 c != '+')
675 ++strp;
676 return strp;
677}
678
679/*
680** Given a pointer into an extended time zone string, scan until the ending
681** delimiter of the zone name is located. Return a pointer to the delimiter.
682**
683** As with getzname above, the legal character set is actually quite
684** restricted, with other characters producing undefined results.
685** We don't do any checking here; checking is done later in common-case code.
686*/
687
688static const char *
689getqzname(register const char *strp, const int delim)
690{
691 register int c;
692
693 while ((c = *strp) != '\0' && c != delim)
694 ++strp;
695 return strp;
696}
697
698/*
486** Given a pointer into a time zone string, extract a number from that string.
487** Check that the number is within a specified range; if it is not, return
488** NULL.
489** Otherwise, return a pointer to the first character not part of the number.
490*/
491
492static const char *
493getnum(strp, nump, min, max)

--- 48 unchanged lines hidden (view full) ---

542 if (*strp == ':') {
543 ++strp;
544 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
545 if (strp == NULL)
546 return NULL;
547 *secsp += num * SECSPERMIN;
548 if (*strp == ':') {
549 ++strp;
699** Given a pointer into a time zone string, extract a number from that string.
700** Check that the number is within a specified range; if it is not, return
701** NULL.
702** Otherwise, return a pointer to the first character not part of the number.
703*/
704
705static const char *
706getnum(strp, nump, min, max)

--- 48 unchanged lines hidden (view full) ---

755 if (*strp == ':') {
756 ++strp;
757 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
758 if (strp == NULL)
759 return NULL;
760 *secsp += num * SECSPERMIN;
761 if (*strp == ':') {
762 ++strp;
550 /* `SECSPERMIN' allows for leap seconds. */
763 /* `SECSPERMIN' allows for leap seconds. */
551 strp = getnum(strp, &num, 0, SECSPERMIN);
552 if (strp == NULL)
553 return NULL;
554 *secsp += num;
555 }
556 }
557 return strp;
558}

--- 22 unchanged lines hidden (view full) ---

581 return NULL; /* illegal time */
582 if (neg)
583 *offsetp = -*offsetp;
584 return strp;
585}
586
587/*
588** Given a pointer into a time zone string, extract a rule in the form
764 strp = getnum(strp, &num, 0, SECSPERMIN);
765 if (strp == NULL)
766 return NULL;
767 *secsp += num;
768 }
769 }
770 return strp;
771}

--- 22 unchanged lines hidden (view full) ---

794 return NULL; /* illegal time */
795 if (neg)
796 *offsetp = -*offsetp;
797 return strp;
798}
799
800/*
801** Given a pointer into a time zone string, extract a rule in the form
589** date[/time]. See POSIX section 8 for the format of "date" and "time".
802** date[/time]. See POSIX section 8 for the format of "date" and "time".
590** If a valid rule is not found, return NULL.
591** Otherwise, return a pointer to the first character not part of the rule.
592*/
593
594static const char *
595getrule(strp, rulep)
596const char * strp;
597struct rule * const rulep;

--- 102 unchanged lines hidden (view full) ---

700 yy1 = yy0 / 100;
701 yy2 = yy0 % 100;
702 dow = ((26 * m1 - 2) / 10 +
703 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
704 if (dow < 0)
705 dow += DAYSPERWEEK;
706
707 /*
803** If a valid rule is not found, return NULL.
804** Otherwise, return a pointer to the first character not part of the rule.
805*/
806
807static const char *
808getrule(strp, rulep)
809const char * strp;
810struct rule * const rulep;

--- 102 unchanged lines hidden (view full) ---

913 yy1 = yy0 / 100;
914 yy2 = yy0 % 100;
915 dow = ((26 * m1 - 2) / 10 +
916 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
917 if (dow < 0)
918 dow += DAYSPERWEEK;
919
920 /*
708 ** "dow" is the day-of-week of the first day of the month. Get
921 ** "dow" is the day-of-week of the first day of the month. Get
709 ** the day-of-month (zero-origin) of the first "dow" day of the
710 ** month.
711 */
712 d = rulep->r_day - dow;
713 if (d < 0)
714 d += DAYSPERWEEK;
715 for (i = 1; i < rulep->r_week; ++i) {
716 if (d + DAYSPERWEEK >=

--- 6 unchanged lines hidden (view full) ---

723 ** "d" is the day-of-month (zero-origin) of the day we want.
724 */
725 value += d * SECSPERDAY;
726 break;
727 }
728
729 /*
730 ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
922 ** the day-of-month (zero-origin) of the first "dow" day of the
923 ** month.
924 */
925 d = rulep->r_day - dow;
926 if (d < 0)
927 d += DAYSPERWEEK;
928 for (i = 1; i < rulep->r_week; ++i) {
929 if (d + DAYSPERWEEK >=

--- 6 unchanged lines hidden (view full) ---

936 ** "d" is the day-of-month (zero-origin) of the day we want.
937 */
938 value += d * SECSPERDAY;
939 break;
940 }
941
942 /*
943 ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
731 ** question. To get the Epoch-relative time of the specified local
944 ** question. To get the Epoch-relative time of the specified local
732 ** time on that day, add the transition time and the current offset
733 ** from UTC.
734 */
735 return value + rulep->r_time + offset;
736}
737
738/*
739** Given a POSIX section 8-style TZ string, fill in the rule tables as

--- 21 unchanged lines hidden (view full) ---

761 stdname = name;
762 if (lastditch) {
763 stdlen = strlen(name); /* length of standard zone name */
764 name += stdlen;
765 if (stdlen >= sizeof sp->chars)
766 stdlen = (sizeof sp->chars) - 1;
767 stdoffset = 0;
768 } else {
945 ** time on that day, add the transition time and the current offset
946 ** from UTC.
947 */
948 return value + rulep->r_time + offset;
949}
950
951/*
952** Given a POSIX section 8-style TZ string, fill in the rule tables as

--- 21 unchanged lines hidden (view full) ---

974 stdname = name;
975 if (lastditch) {
976 stdlen = strlen(name); /* length of standard zone name */
977 name += stdlen;
978 if (stdlen >= sizeof sp->chars)
979 stdlen = (sizeof sp->chars) - 1;
980 stdoffset = 0;
981 } else {
769 name = getzname(name);
770 stdlen = name - stdname;
771 if (stdlen < 3)
772 return -1;
982 if (*name == '<') {
983 name++;
984 stdname = name;
985 name = getqzname(name, '>');
986 if (*name != '>')
987 return (-1);
988 stdlen = name - stdname;
989 name++;
990 } else {
991 name = getzname(name);
992 stdlen = name - stdname;
993 }
773 if (*name == '\0')
774 return -1; /* was "stdoffset = 0;" */
775 else {
776 name = getoffset(name, &stdoffset);
777 if (name == NULL)
778 return -1;
779 }
780 }
994 if (*name == '\0')
995 return -1; /* was "stdoffset = 0;" */
996 else {
997 name = getoffset(name, &stdoffset);
998 if (name == NULL)
999 return -1;
1000 }
1001 }
781 load_result = tzload(TZDEFRULES, sp);
1002 load_result = tzload(TZDEFRULES, sp, FALSE);
782 if (load_result != 0)
783 sp->leapcnt = 0; /* so, we're off a little */
784 if (*name != '\0') {
1003 if (load_result != 0)
1004 sp->leapcnt = 0; /* so, we're off a little */
1005 if (*name != '\0') {
785 dstname = name;
786 name = getzname(name);
787 dstlen = name - dstname; /* length of DST zone name */
788 if (dstlen < 3)
789 return -1;
1006 if (*name == '<') {
1007 dstname = ++name;
1008 name = getqzname(name, '>');
1009 if (*name != '>')
1010 return -1;
1011 dstlen = name - dstname;
1012 name++;
1013 } else {
1014 dstname = name;
1015 name = getzname(name);
1016 dstlen = name - dstname; /* length of DST zone name */
1017 }
790 if (*name != '\0' && *name != ',' && *name != ';') {
791 name = getoffset(name, &dstoffset);
792 if (name == NULL)
793 return -1;
794 } else dstoffset = stdoffset - SECSPERHOUR;
795 if (*name == '\0' && load_result != 0)
796 name = TZDEFRULESTRING;
797 if (*name == ',' || *name == ';') {

--- 10 unchanged lines hidden (view full) ---

808 if (*name++ != ',')
809 return -1;
810 if ((name = getrule(name, &end)) == NULL)
811 return -1;
812 if (*name != '\0')
813 return -1;
814 sp->typecnt = 2; /* standard time and DST */
815 /*
1018 if (*name != '\0' && *name != ',' && *name != ';') {
1019 name = getoffset(name, &dstoffset);
1020 if (name == NULL)
1021 return -1;
1022 } else dstoffset = stdoffset - SECSPERHOUR;
1023 if (*name == '\0' && load_result != 0)
1024 name = TZDEFRULESTRING;
1025 if (*name == ',' || *name == ';') {

--- 10 unchanged lines hidden (view full) ---

1036 if (*name++ != ',')
1037 return -1;
1038 if ((name = getrule(name, &end)) == NULL)
1039 return -1;
1040 if (*name != '\0')
1041 return -1;
1042 sp->typecnt = 2; /* standard time and DST */
1043 /*
816 ** Two transitions per year, from EPOCH_YEAR to 2037.
1044 ** Two transitions per year, from EPOCH_YEAR forward.
817 */
1045 */
818 sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
819 if (sp->timecnt > TZ_MAX_TIMES)
820 return -1;
821 sp->ttis[0].tt_gmtoff = -dstoffset;
822 sp->ttis[0].tt_isdst = 1;
823 sp->ttis[0].tt_abbrind = stdlen + 1;
824 sp->ttis[1].tt_gmtoff = -stdoffset;
825 sp->ttis[1].tt_isdst = 0;
826 sp->ttis[1].tt_abbrind = 0;
827 atp = sp->ats;
828 typep = sp->types;
829 janfirst = 0;
1046 sp->ttis[0].tt_gmtoff = -dstoffset;
1047 sp->ttis[0].tt_isdst = 1;
1048 sp->ttis[0].tt_abbrind = stdlen + 1;
1049 sp->ttis[1].tt_gmtoff = -stdoffset;
1050 sp->ttis[1].tt_isdst = 0;
1051 sp->ttis[1].tt_abbrind = 0;
1052 atp = sp->ats;
1053 typep = sp->types;
1054 janfirst = 0;
830 for (year = EPOCH_YEAR; year <= 2037; ++year) {
1055 sp->timecnt = 0;
1056 for (year = EPOCH_YEAR;
1057 sp->timecnt + 2 <= TZ_MAX_TIMES;
1058 ++year) {
1059 time_t newfirst;
1060
831 starttime = transtime(janfirst, year, &start,
832 stdoffset);
833 endtime = transtime(janfirst, year, &end,
834 dstoffset);
835 if (starttime > endtime) {
836 *atp++ = endtime;
837 *typep++ = 1; /* DST ends */
838 *atp++ = starttime;
839 *typep++ = 0; /* DST begins */
840 } else {
841 *atp++ = starttime;
842 *typep++ = 0; /* DST begins */
843 *atp++ = endtime;
844 *typep++ = 1; /* DST ends */
845 }
1061 starttime = transtime(janfirst, year, &start,
1062 stdoffset);
1063 endtime = transtime(janfirst, year, &end,
1064 dstoffset);
1065 if (starttime > endtime) {
1066 *atp++ = endtime;
1067 *typep++ = 1; /* DST ends */
1068 *atp++ = starttime;
1069 *typep++ = 0; /* DST begins */
1070 } else {
1071 *atp++ = starttime;
1072 *typep++ = 0; /* DST begins */
1073 *atp++ = endtime;
1074 *typep++ = 1; /* DST ends */
1075 }
846 janfirst += year_lengths[isleap(year)] *
1076 sp->timecnt += 2;
1077 newfirst = janfirst;
1078 newfirst += year_lengths[isleap(year)] *
847 SECSPERDAY;
1079 SECSPERDAY;
1080 if (newfirst <= janfirst)
1081 break;
1082 janfirst = newfirst;
848 }
849 } else {
850 long theirstdoffset;
851 long theirdstoffset;
852 long theiroffset;
853 int isdst;
854 int i;
855 int j;

--- 98 unchanged lines hidden (view full) ---

954 }
955 return 0;
956}
957
958static void
959gmtload(sp)
960struct state * const sp;
961{
1083 }
1084 } else {
1085 long theirstdoffset;
1086 long theirdstoffset;
1087 long theiroffset;
1088 int isdst;
1089 int i;
1090 int j;

--- 98 unchanged lines hidden (view full) ---

1189 }
1190 return 0;
1191}
1192
1193static void
1194gmtload(sp)
1195struct state * const sp;
1196{
962 if (tzload(gmt, sp) != 0)
1197 if (tzload(gmt, sp, TRUE) != 0)
963 (void) tzparse(gmt, sp, TRUE);
964}
965
966static void
967tzsetwall_basic(int rdlocked)
968{
969 if (!rdlocked)
970 _RWLOCK_RDLOCK(&lcl_rwlock);

--- 14 unchanged lines hidden (view full) ---

985 settzname(); /* all we can do */
986 _RWLOCK_UNLOCK(&lcl_rwlock);
987 if (rdlocked)
988 _RWLOCK_RDLOCK(&lcl_rwlock);
989 return;
990 }
991 }
992#endif /* defined ALL_STATE */
1198 (void) tzparse(gmt, sp, TRUE);
1199}
1200
1201static void
1202tzsetwall_basic(int rdlocked)
1203{
1204 if (!rdlocked)
1205 _RWLOCK_RDLOCK(&lcl_rwlock);

--- 14 unchanged lines hidden (view full) ---

1220 settzname(); /* all we can do */
1221 _RWLOCK_UNLOCK(&lcl_rwlock);
1222 if (rdlocked)
1223 _RWLOCK_RDLOCK(&lcl_rwlock);
1224 return;
1225 }
1226 }
1227#endif /* defined ALL_STATE */
993 if (tzload((char *) NULL, lclptr) != 0)
1228 if (tzload((char *) NULL, lclptr, TRUE) != 0)
994 gmtload(lclptr);
995 settzname();
996 _RWLOCK_UNLOCK(&lcl_rwlock);
997
998 if (rdlocked)
999 _RWLOCK_RDLOCK(&lcl_rwlock);
1000}
1001

--- 46 unchanged lines hidden (view full) ---

1048 */
1049 lclptr->leapcnt = 0; /* so, we're off a little */
1050 lclptr->timecnt = 0;
1051 lclptr->typecnt = 0;
1052 lclptr->ttis[0].tt_isdst = 0;
1053 lclptr->ttis[0].tt_gmtoff = 0;
1054 lclptr->ttis[0].tt_abbrind = 0;
1055 (void) strcpy(lclptr->chars, gmt);
1229 gmtload(lclptr);
1230 settzname();
1231 _RWLOCK_UNLOCK(&lcl_rwlock);
1232
1233 if (rdlocked)
1234 _RWLOCK_RDLOCK(&lcl_rwlock);
1235}
1236

--- 46 unchanged lines hidden (view full) ---

1283 */
1284 lclptr->leapcnt = 0; /* so, we're off a little */
1285 lclptr->timecnt = 0;
1286 lclptr->typecnt = 0;
1287 lclptr->ttis[0].tt_isdst = 0;
1288 lclptr->ttis[0].tt_gmtoff = 0;
1289 lclptr->ttis[0].tt_abbrind = 0;
1290 (void) strcpy(lclptr->chars, gmt);
1056 } else if (tzload(name, lclptr) != 0)
1291 } else if (tzload(name, lclptr, TRUE) != 0)
1057 if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
1058 (void) gmtload(lclptr);
1059 settzname();
1060 _RWLOCK_UNLOCK(&lcl_rwlock);
1061
1062 if (rdlocked)
1063 _RWLOCK_RDLOCK(&lcl_rwlock);
1064}
1065
1066void
1067tzset(void)
1068{
1069 tzset_basic(0);
1070}
1071
1072/*
1073** The easy way to behave "as if no library function calls" localtime
1074** is to not call it--so we drop its guts into "localsub", which can be
1292 if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
1293 (void) gmtload(lclptr);
1294 settzname();
1295 _RWLOCK_UNLOCK(&lcl_rwlock);
1296
1297 if (rdlocked)
1298 _RWLOCK_RDLOCK(&lcl_rwlock);
1299}
1300
1301void
1302tzset(void)
1303{
1304 tzset_basic(0);
1305}
1306
1307/*
1308** The easy way to behave "as if no library function calls" localtime
1309** is to not call it--so we drop its guts into "localsub", which can be
1075** freely called. (And no, the PANS doesn't require the above behavior--
1310** freely called. (And no, the PANS doesn't require the above behavior--
1076** but it *is* desirable.)
1077**
1078** The unused offset argument is for the benefit of mktime variants.
1079*/
1080
1081/*ARGSUSED*/
1311** but it *is* desirable.)
1312**
1313** The unused offset argument is for the benefit of mktime variants.
1314*/
1315
1316/*ARGSUSED*/
1082static void
1317static struct tm *
1083localsub(timep, offset, tmp)
1084const time_t * const timep;
1085const long offset;
1086struct tm * const tmp;
1087{
1088 struct state * sp;
1089 const struct ttinfo * ttisp;
1090 int i;
1318localsub(timep, offset, tmp)
1319const time_t * const timep;
1320const long offset;
1321struct tm * const tmp;
1322{
1323 struct state * sp;
1324 const struct ttinfo * ttisp;
1325 int i;
1091 const time_t t = *timep;
1326 struct tm * result;
1327 const time_t t = *timep;
1092
1093 sp = lclptr;
1094#ifdef ALL_STATE
1328
1329 sp = lclptr;
1330#ifdef ALL_STATE
1095 if (sp == NULL) {
1096 gmtsub(timep, offset, tmp);
1097 return;
1098 }
1331 if (sp == NULL)
1332 return gmtsub(timep, offset, tmp);
1099#endif /* defined ALL_STATE */
1333#endif /* defined ALL_STATE */
1334 if ((sp->goback && t < sp->ats[0]) ||
1335 (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1336 time_t newt = t;
1337 register time_t seconds;
1338 register time_t tcycles;
1339 register int_fast64_t icycles;
1340
1341 if (t < sp->ats[0])
1342 seconds = sp->ats[0] - t;
1343 else seconds = t - sp->ats[sp->timecnt - 1];
1344 --seconds;
1345 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1346 ++tcycles;
1347 icycles = tcycles;
1348 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1349 return NULL;
1350 seconds = icycles;
1351 seconds *= YEARSPERREPEAT;
1352 seconds *= AVGSECSPERYEAR;
1353 if (t < sp->ats[0])
1354 newt += seconds;
1355 else newt -= seconds;
1356 if (newt < sp->ats[0] ||
1357 newt > sp->ats[sp->timecnt - 1])
1358 return NULL; /* "cannot happen" */
1359 result = localsub(&newt, offset, tmp);
1360 if (result == tmp) {
1361 register time_t newy;
1362
1363 newy = tmp->tm_year;
1364 if (t < sp->ats[0])
1365 newy -= icycles * YEARSPERREPEAT;
1366 else newy += icycles * YEARSPERREPEAT;
1367 tmp->tm_year = newy;
1368 if (tmp->tm_year != newy)
1369 return NULL;
1370 }
1371 return result;
1372 }
1100 if (sp->timecnt == 0 || t < sp->ats[0]) {
1101 i = 0;
1102 while (sp->ttis[i].tt_isdst)
1103 if (++i >= sp->typecnt) {
1104 i = 0;
1105 break;
1106 }
1107 } else {
1373 if (sp->timecnt == 0 || t < sp->ats[0]) {
1374 i = 0;
1375 while (sp->ttis[i].tt_isdst)
1376 if (++i >= sp->typecnt) {
1377 i = 0;
1378 break;
1379 }
1380 } else {
1108 for (i = 1; i < sp->timecnt; ++i)
1109 if (t < sp->ats[i])
1110 break;
1111 i = sp->types[i - 1];
1381 register int lo = 1;
1382 register int hi = sp->timecnt;
1383
1384 while (lo < hi) {
1385 register int mid = (lo + hi) >> 1;
1386
1387 if (t < sp->ats[mid])
1388 hi = mid;
1389 else lo = mid + 1;
1390 }
1391 i = (int) sp->types[lo - 1];
1112 }
1113 ttisp = &sp->ttis[i];
1114 /*
1115 ** To get (wrong) behavior that's compatible with System V Release 2.0
1116 ** you'd replace the statement below with
1117 ** t += ttisp->tt_gmtoff;
1118 ** timesub(&t, 0L, sp, tmp);
1119 */
1392 }
1393 ttisp = &sp->ttis[i];
1394 /*
1395 ** To get (wrong) behavior that's compatible with System V Release 2.0
1396 ** you'd replace the statement below with
1397 ** t += ttisp->tt_gmtoff;
1398 ** timesub(&t, 0L, sp, tmp);
1399 */
1120 timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1400 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1121 tmp->tm_isdst = ttisp->tt_isdst;
1122 tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
1123#ifdef TM_ZONE
1124 tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
1125#endif /* defined TM_ZONE */
1401 tmp->tm_isdst = ttisp->tt_isdst;
1402 tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
1403#ifdef TM_ZONE
1404 tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
1405#endif /* defined TM_ZONE */
1406 return result;
1126}
1127
1128struct tm *
1129localtime(timep)
1130const time_t * const timep;
1131{
1132 static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
1133 static pthread_key_t localtime_key = -1;

--- 29 unchanged lines hidden (view full) ---

1163 }
1164}
1165
1166/*
1167** Re-entrant version of localtime.
1168*/
1169
1170struct tm *
1407}
1408
1409struct tm *
1410localtime(timep)
1411const time_t * const timep;
1412{
1413 static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
1414 static pthread_key_t localtime_key = -1;

--- 29 unchanged lines hidden (view full) ---

1444 }
1445}
1446
1447/*
1448** Re-entrant version of localtime.
1449*/
1450
1451struct tm *
1171localtime_r(timep, tm)
1452localtime_r(timep, tmp)
1172const time_t * const timep;
1453const time_t * const timep;
1173struct tm * tm;
1454struct tm * tmp;
1174{
1175 _RWLOCK_RDLOCK(&lcl_rwlock);
1176 tzset_basic(1);
1455{
1456 _RWLOCK_RDLOCK(&lcl_rwlock);
1457 tzset_basic(1);
1177 localsub(timep, 0L, tm);
1458 localsub(timep, 0L, tmp);
1178 _RWLOCK_UNLOCK(&lcl_rwlock);
1459 _RWLOCK_UNLOCK(&lcl_rwlock);
1179 return tm;
1460 return tmp;
1180}
1181
1182/*
1183** gmtsub is to gmtime as localsub is to localtime.
1184*/
1185
1461}
1462
1463/*
1464** gmtsub is to gmtime as localsub is to localtime.
1465*/
1466
1186static void
1467static struct tm *
1187gmtsub(timep, offset, tmp)
1188const time_t * const timep;
1189const long offset;
1190struct tm * const tmp;
1191{
1468gmtsub(timep, offset, tmp)
1469const time_t * const timep;
1470const long offset;
1471struct tm * const tmp;
1472{
1473 register struct tm * result;
1474
1192 if (!gmt_is_set) {
1193 _MUTEX_LOCK(&gmt_mutex);
1194 if (!gmt_is_set) {
1195#ifdef ALL_STATE
1196 gmtptr = (struct state *) malloc(sizeof *gmtptr);
1197 if (gmtptr != NULL)
1198#endif /* defined ALL_STATE */
1199 gmtload(gmtptr);
1200 gmt_is_set = TRUE;
1201 }
1202 _MUTEX_UNLOCK(&gmt_mutex);
1203 }
1475 if (!gmt_is_set) {
1476 _MUTEX_LOCK(&gmt_mutex);
1477 if (!gmt_is_set) {
1478#ifdef ALL_STATE
1479 gmtptr = (struct state *) malloc(sizeof *gmtptr);
1480 if (gmtptr != NULL)
1481#endif /* defined ALL_STATE */
1482 gmtload(gmtptr);
1483 gmt_is_set = TRUE;
1484 }
1485 _MUTEX_UNLOCK(&gmt_mutex);
1486 }
1204 timesub(timep, offset, gmtptr, tmp);
1487 result = timesub(timep, offset, gmtptr, tmp);
1205#ifdef TM_ZONE
1206 /*
1207 ** Could get fancy here and deliver something such as
1208 ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
1209 ** but this is no time for a treasure hunt.
1210 */
1211 if (offset != 0)
1212 tmp->TM_ZONE = wildabbr;
1213 else {
1214#ifdef ALL_STATE
1215 if (gmtptr == NULL)
1216 tmp->TM_ZONE = gmt;
1217 else tmp->TM_ZONE = gmtptr->chars;
1218#endif /* defined ALL_STATE */
1219#ifndef ALL_STATE
1220 tmp->TM_ZONE = gmtptr->chars;
1221#endif /* State Farm */
1222 }
1223#endif /* defined TM_ZONE */
1488#ifdef TM_ZONE
1489 /*
1490 ** Could get fancy here and deliver something such as
1491 ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
1492 ** but this is no time for a treasure hunt.
1493 */
1494 if (offset != 0)
1495 tmp->TM_ZONE = wildabbr;
1496 else {
1497#ifdef ALL_STATE
1498 if (gmtptr == NULL)
1499 tmp->TM_ZONE = gmt;
1500 else tmp->TM_ZONE = gmtptr->chars;
1501#endif /* defined ALL_STATE */
1502#ifndef ALL_STATE
1503 tmp->TM_ZONE = gmtptr->chars;
1504#endif /* State Farm */
1505 }
1506#endif /* defined TM_ZONE */
1507 return result;
1224}
1225
1226struct tm *
1227gmtime(timep)
1228const time_t * const timep;
1229{
1230 static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
1231 static pthread_key_t gmtime_key = -1;

--- 30 unchanged lines hidden (view full) ---

1262 }
1263}
1264
1265/*
1266* Re-entrant version of gmtime.
1267*/
1268
1269struct tm *
1508}
1509
1510struct tm *
1511gmtime(timep)
1512const time_t * const timep;
1513{
1514 static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
1515 static pthread_key_t gmtime_key = -1;

--- 30 unchanged lines hidden (view full) ---

1546 }
1547}
1548
1549/*
1550* Re-entrant version of gmtime.
1551*/
1552
1553struct tm *
1270gmtime_r(timep, tm)
1554gmtime_r(timep, tmp)
1271const time_t * const timep;
1555const time_t * const timep;
1272struct tm * tm;
1556struct tm * tmp;
1273{
1557{
1274 gmtsub(timep, 0L, tm);
1275 return tm;
1558 return gmtsub(timep, 0L, tmp);
1276}
1277
1278#ifdef STD_INSPIRED
1279
1280struct tm *
1281offtime(timep, offset)
1282const time_t * const timep;
1283const long offset;
1284{
1559}
1560
1561#ifdef STD_INSPIRED
1562
1563struct tm *
1564offtime(timep, offset)
1565const time_t * const timep;
1566const long offset;
1567{
1285 gmtsub(timep, offset, &tm);
1286 return &tm;
1568 return gmtsub(timep, offset, &tm);
1287}
1288
1289#endif /* defined STD_INSPIRED */
1290
1569}
1570
1571#endif /* defined STD_INSPIRED */
1572
1291static void
1573/*
1574** Return the number of leap years through the end of the given year
1575** where, to make the math easy, the answer for year zero is defined as zero.
1576*/
1577
1578static int
1579leaps_thru_end_of(y)
1580register const int y;
1581{
1582 return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1583 -(leaps_thru_end_of(-(y + 1)) + 1);
1584}
1585
1586static struct tm *
1292timesub(timep, offset, sp, tmp)
1293const time_t * const timep;
1294const long offset;
1295const struct state * const sp;
1296struct tm * const tmp;
1297{
1298 const struct lsinfo * lp;
1587timesub(timep, offset, sp, tmp)
1588const time_t * const timep;
1589const long offset;
1590const struct state * const sp;
1591struct tm * const tmp;
1592{
1593 const struct lsinfo * lp;
1299 long days;
1594 time_t tdays;
1595 int idays; /* unsigned would be so 2003 */
1300 long rem;
1596 long rem;
1301 long y;
1302 int yleap;
1597 int y;
1303 const int * ip;
1304 long corr;
1305 int hit;
1306 int i;
1307
1308 corr = 0;
1309 hit = 0;
1310#ifdef ALL_STATE

--- 17 unchanged lines hidden (view full) ---

1328 ++hit;
1329 --i;
1330 }
1331 }
1332 corr = lp->ls_corr;
1333 break;
1334 }
1335 }
1598 const int * ip;
1599 long corr;
1600 int hit;
1601 int i;
1602
1603 corr = 0;
1604 hit = 0;
1605#ifdef ALL_STATE

--- 17 unchanged lines hidden (view full) ---

1623 ++hit;
1624 --i;
1625 }
1626 }
1627 corr = lp->ls_corr;
1628 break;
1629 }
1630 }
1336 days = *timep / SECSPERDAY;
1337 rem = *timep % SECSPERDAY;
1338#ifdef mc68k
1339 if (*timep == 0x80000000) {
1340 /*
1341 ** A 3B1 muffs the division on the most negative number.
1342 */
1343 days = -24855;
1344 rem = -11648;
1631 y = EPOCH_YEAR;
1632 tdays = *timep / SECSPERDAY;
1633 rem = *timep - tdays * SECSPERDAY;
1634 while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1635 int newy;
1636 register time_t tdelta;
1637 register int idelta;
1638 register int leapdays;
1639
1640 tdelta = tdays / DAYSPERLYEAR;
1641 idelta = tdelta;
1642 if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
1643 return NULL;
1644 if (idelta == 0)
1645 idelta = (tdays < 0) ? -1 : 1;
1646 newy = y;
1647 if (increment_overflow(&newy, idelta))
1648 return NULL;
1649 leapdays = leaps_thru_end_of(newy - 1) -
1650 leaps_thru_end_of(y - 1);
1651 tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1652 tdays -= leapdays;
1653 y = newy;
1345 }
1654 }
1346#endif /* defined mc68k */
1347 rem += (offset - corr);
1655 {
1656 register long seconds;
1657
1658 seconds = tdays * SECSPERDAY + 0.5;
1659 tdays = seconds / SECSPERDAY;
1660 rem += seconds - tdays * SECSPERDAY;
1661 }
1662 /*
1663 ** Given the range, we can now fearlessly cast...
1664 */
1665 idays = tdays;
1666 rem += offset - corr;
1348 while (rem < 0) {
1349 rem += SECSPERDAY;
1667 while (rem < 0) {
1668 rem += SECSPERDAY;
1350 --days;
1669 --idays;
1351 }
1352 while (rem >= SECSPERDAY) {
1353 rem -= SECSPERDAY;
1670 }
1671 while (rem >= SECSPERDAY) {
1672 rem -= SECSPERDAY;
1354 ++days;
1673 ++idays;
1355 }
1674 }
1675 while (idays < 0) {
1676 if (increment_overflow(&y, -1))
1677 return NULL;
1678 idays += year_lengths[isleap(y)];
1679 }
1680 while (idays >= year_lengths[isleap(y)]) {
1681 idays -= year_lengths[isleap(y)];
1682 if (increment_overflow(&y, 1))
1683 return NULL;
1684 }
1685 tmp->tm_year = y;
1686 if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1687 return NULL;
1688 tmp->tm_yday = idays;
1689 /*
1690 ** The "extra" mods below avoid overflow problems.
1691 */
1692 tmp->tm_wday = EPOCH_WDAY +
1693 ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1694 (DAYSPERNYEAR % DAYSPERWEEK) +
1695 leaps_thru_end_of(y - 1) -
1696 leaps_thru_end_of(EPOCH_YEAR - 1) +
1697 idays;
1698 tmp->tm_wday %= DAYSPERWEEK;
1699 if (tmp->tm_wday < 0)
1700 tmp->tm_wday += DAYSPERWEEK;
1356 tmp->tm_hour = (int) (rem / SECSPERHOUR);
1701 tmp->tm_hour = (int) (rem / SECSPERHOUR);
1357 rem = rem % SECSPERHOUR;
1702 rem %= SECSPERHOUR;
1358 tmp->tm_min = (int) (rem / SECSPERMIN);
1359 /*
1360 ** A positive leap second requires a special
1703 tmp->tm_min = (int) (rem / SECSPERMIN);
1704 /*
1705 ** A positive leap second requires a special
1361 ** representation. This uses "... ??:59:60" et seq.
1706 ** representation. This uses "... ??:59:60" et seq.
1362 */
1363 tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1707 */
1708 tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1364 tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
1365 if (tmp->tm_wday < 0)
1366 tmp->tm_wday += DAYSPERWEEK;
1367 y = EPOCH_YEAR;
1368#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
1369 while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
1370 long newy;
1371
1372 newy = y + days / DAYSPERNYEAR;
1373 if (days < 0)
1374 --newy;
1375 days -= (newy - y) * DAYSPERNYEAR +
1376 LEAPS_THRU_END_OF(newy - 1) -
1377 LEAPS_THRU_END_OF(y - 1);
1378 y = newy;
1379 }
1380 tmp->tm_year = y - TM_YEAR_BASE;
1381 tmp->tm_yday = (int) days;
1382 ip = mon_lengths[yleap];
1383 for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
1384 days = days - (long) ip[tmp->tm_mon];
1385 tmp->tm_mday = (int) (days + 1);
1709 ip = mon_lengths[isleap(y)];
1710 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1711 idays -= ip[tmp->tm_mon];
1712 tmp->tm_mday = (int) (idays + 1);
1386 tmp->tm_isdst = 0;
1387#ifdef TM_GMTOFF
1388 tmp->TM_GMTOFF = offset;
1389#endif /* defined TM_GMTOFF */
1713 tmp->tm_isdst = 0;
1714#ifdef TM_GMTOFF
1715 tmp->TM_GMTOFF = offset;
1716#endif /* defined TM_GMTOFF */
1717 return tmp;
1390}
1391
1392char *
1393ctime(timep)
1394const time_t * const timep;
1395{
1396/*
1397** Section 4.12.3.2 of X3.159-1989 requires that
1398** The ctime function converts the calendar time pointed to by timer
1718}
1719
1720char *
1721ctime(timep)
1722const time_t * const timep;
1723{
1724/*
1725** Section 4.12.3.2 of X3.159-1989 requires that
1726** The ctime function converts the calendar time pointed to by timer
1399** to local time in the form of a string. It is equivalent to
1727** to local time in the form of a string. It is equivalent to
1400** asctime(localtime(timer))
1401*/
1402 return asctime(localtime(timep));
1403}
1404
1405char *
1406ctime_r(timep, buf)
1407const time_t * const timep;
1408char * buf;
1409{
1728** asctime(localtime(timer))
1729*/
1730 return asctime(localtime(timep));
1731}
1732
1733char *
1734ctime_r(timep, buf)
1735const time_t * const timep;
1736char * buf;
1737{
1410 struct tm tm;
1738 struct tm mytm;
1411
1739
1412 return asctime_r(localtime_r(timep, &tm), buf);
1740 return asctime_r(localtime_r(timep, &mytm), buf);
1413}
1414
1415/*
1416** Adapted from code provided by Robert Elz, who writes:
1417** The "best" way to do mktime I think is based on an idea of Bob
1418** Kridle's (so its said...) from a long time ago.
1741}
1742
1743/*
1744** Adapted from code provided by Robert Elz, who writes:
1745** The "best" way to do mktime I think is based on an idea of Bob
1746** Kridle's (so its said...) from a long time ago.
1419** [kridle@xinet.com as of 1996-01-16.]
1420** It does a binary search of the time_t space. Since time_t's are
1747** It does a binary search of the time_t space. Since time_t's are
1421** just 32 bits, its a max of 32 iterations (even at 64 bits it
1422** would still be very reasonable).
1423*/
1424
1425#ifndef WRONG
1426#define WRONG (-1)
1427#endif /* !defined WRONG */
1428
1429/*
1748** just 32 bits, its a max of 32 iterations (even at 64 bits it
1749** would still be very reasonable).
1750*/
1751
1752#ifndef WRONG
1753#define WRONG (-1)
1754#endif /* !defined WRONG */
1755
1756/*
1430** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).
1757** Simplified normalize logic courtesy Paul Eggert.
1431*/
1432
1433static int
1434increment_overflow(number, delta)
1435int * number;
1436int delta;
1437{
1438 int number0;
1439
1440 number0 = *number;
1441 *number += delta;
1442 return (*number < number0) != (delta < 0);
1443}
1444
1445static int
1758*/
1759
1760static int
1761increment_overflow(number, delta)
1762int * number;
1763int delta;
1764{
1765 int number0;
1766
1767 number0 = *number;
1768 *number += delta;
1769 return (*number < number0) != (delta < 0);
1770}
1771
1772static int
1773long_increment_overflow(number, delta)
1774long * number;
1775int delta;
1776{
1777 long number0;
1778
1779 number0 = *number;
1780 *number += delta;
1781 return (*number < number0) != (delta < 0);
1782}
1783
1784static int
1446normalize_overflow(tensptr, unitsptr, base)
1447int * const tensptr;
1448int * const unitsptr;
1449const int base;
1450{
1451 int tensdelta;
1452
1453 tensdelta = (*unitsptr >= 0) ?
1454 (*unitsptr / base) :
1455 (-1 - (-1 - *unitsptr) / base);
1456 *unitsptr -= tensdelta * base;
1457 return increment_overflow(tensptr, tensdelta);
1458}
1459
1460static int
1785normalize_overflow(tensptr, unitsptr, base)
1786int * const tensptr;
1787int * const unitsptr;
1788const int base;
1789{
1790 int tensdelta;
1791
1792 tensdelta = (*unitsptr >= 0) ?
1793 (*unitsptr / base) :
1794 (-1 - (-1 - *unitsptr) / base);
1795 *unitsptr -= tensdelta * base;
1796 return increment_overflow(tensptr, tensdelta);
1797}
1798
1799static int
1800long_normalize_overflow(tensptr, unitsptr, base)
1801long * const tensptr;
1802int * const unitsptr;
1803const int base;
1804{
1805 register int tensdelta;
1806
1807 tensdelta = (*unitsptr >= 0) ?
1808 (*unitsptr / base) :
1809 (-1 - (-1 - *unitsptr) / base);
1810 *unitsptr -= tensdelta * base;
1811 return long_increment_overflow(tensptr, tensdelta);
1812}
1813
1814static int
1461tmcomp(atmp, btmp)
1462const struct tm * const atmp;
1463const struct tm * const btmp;
1464{
1465 int result;
1466
1467 if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
1468 (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1469 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1470 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1471 (result = (atmp->tm_min - btmp->tm_min)) == 0)
1472 result = atmp->tm_sec - btmp->tm_sec;
1473 return result;
1474}
1475
1476static time_t
1477time2sub(tmp, funcp, offset, okayp, do_norm_secs)
1478struct tm * const tmp;
1815tmcomp(atmp, btmp)
1816const struct tm * const atmp;
1817const struct tm * const btmp;
1818{
1819 int result;
1820
1821 if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
1822 (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1823 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1824 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1825 (result = (atmp->tm_min - btmp->tm_min)) == 0)
1826 result = atmp->tm_sec - btmp->tm_sec;
1827 return result;
1828}
1829
1830static time_t
1831time2sub(tmp, funcp, offset, okayp, do_norm_secs)
1832struct tm * const tmp;
1479void (* const funcp)(const time_t*, long, struct tm*);
1833struct tm * (* const funcp)(const time_t*, long, struct tm*);
1480const long offset;
1481int * const okayp;
1482const int do_norm_secs;
1483{
1484 const struct state * sp;
1485 int dir;
1834const long offset;
1835int * const okayp;
1836const int do_norm_secs;
1837{
1838 const struct state * sp;
1839 int dir;
1486 int bits;
1487 int i, j ;
1840 int i, j;
1488 int saved_seconds;
1841 int saved_seconds;
1489 time_t newt;
1490 time_t t;
1491 struct tm yourtm, mytm;
1842 long li;
1843 time_t lo;
1844 time_t hi;
1845 long y;
1846 time_t newt;
1847 time_t t;
1848 struct tm yourtm, mytm;
1492
1493 *okayp = FALSE;
1494 yourtm = *tmp;
1495 if (do_norm_secs) {
1496 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1497 SECSPERMIN))
1498 return WRONG;
1499 }
1500 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1501 return WRONG;
1502 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1503 return WRONG;
1849
1850 *okayp = FALSE;
1851 yourtm = *tmp;
1852 if (do_norm_secs) {
1853 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1854 SECSPERMIN))
1855 return WRONG;
1856 }
1857 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1858 return WRONG;
1859 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1860 return WRONG;
1504 if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR))
1861 y = yourtm.tm_year;
1862 if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
1505 return WRONG;
1506 /*
1863 return WRONG;
1864 /*
1507 ** Turn yourtm.tm_year into an actual year number for now.
1865 ** Turn y into an actual year number for now.
1508 ** It is converted back to an offset from TM_YEAR_BASE later.
1509 */
1866 ** It is converted back to an offset from TM_YEAR_BASE later.
1867 */
1510 if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE))
1868 if (long_increment_overflow(&y, TM_YEAR_BASE))
1511 return WRONG;
1512 while (yourtm.tm_mday <= 0) {
1869 return WRONG;
1870 while (yourtm.tm_mday <= 0) {
1513 if (increment_overflow(&yourtm.tm_year, -1))
1871 if (long_increment_overflow(&y, -1))
1514 return WRONG;
1872 return WRONG;
1515 i = yourtm.tm_year + (1 < yourtm.tm_mon);
1516 yourtm.tm_mday += year_lengths[isleap(i)];
1873 li = y + (1 < yourtm.tm_mon);
1874 yourtm.tm_mday += year_lengths[isleap(li)];
1517 }
1518 while (yourtm.tm_mday > DAYSPERLYEAR) {
1875 }
1876 while (yourtm.tm_mday > DAYSPERLYEAR) {
1519 i = yourtm.tm_year + (1 < yourtm.tm_mon);
1520 yourtm.tm_mday -= year_lengths[isleap(i)];
1521 if (increment_overflow(&yourtm.tm_year, 1))
1877 li = y + (1 < yourtm.tm_mon);
1878 yourtm.tm_mday -= year_lengths[isleap(li)];
1879 if (long_increment_overflow(&y, 1))
1522 return WRONG;
1523 }
1524 for ( ; ; ) {
1880 return WRONG;
1881 }
1882 for ( ; ; ) {
1525 i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon];
1883 i = mon_lengths[isleap(y)][yourtm.tm_mon];
1526 if (yourtm.tm_mday <= i)
1527 break;
1528 yourtm.tm_mday -= i;
1529 if (++yourtm.tm_mon >= MONSPERYEAR) {
1530 yourtm.tm_mon = 0;
1884 if (yourtm.tm_mday <= i)
1885 break;
1886 yourtm.tm_mday -= i;
1887 if (++yourtm.tm_mon >= MONSPERYEAR) {
1888 yourtm.tm_mon = 0;
1531 if (increment_overflow(&yourtm.tm_year, 1))
1889 if (long_increment_overflow(&y, 1))
1532 return WRONG;
1533 }
1534 }
1890 return WRONG;
1891 }
1892 }
1535 if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))
1893 if (long_increment_overflow(&y, -TM_YEAR_BASE))
1536 return WRONG;
1894 return WRONG;
1895 yourtm.tm_year = y;
1896 if (yourtm.tm_year != y)
1897 return WRONG;
1537 /* Don't go below 1900 for POLA */
1538 if (yourtm.tm_year < 0)
1539 return WRONG;
1540 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1541 saved_seconds = 0;
1898 /* Don't go below 1900 for POLA */
1899 if (yourtm.tm_year < 0)
1900 return WRONG;
1901 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1902 saved_seconds = 0;
1542 else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
1903 else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1543 /*
1544 ** We can't set tm_sec to 0, because that might push the
1545 ** time below the minimum representable time.
1546 ** Set tm_sec to 59 instead.
1547 ** This assumes that the minimum representable time is
1548 ** not in the same minute that a leap second was deleted from,
1549 ** which is a safer assumption than using 58 would be.
1550 */
1551 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1552 return WRONG;
1553 saved_seconds = yourtm.tm_sec;
1554 yourtm.tm_sec = SECSPERMIN - 1;
1555 } else {
1556 saved_seconds = yourtm.tm_sec;
1557 yourtm.tm_sec = 0;
1558 }
1559 /*
1904 /*
1905 ** We can't set tm_sec to 0, because that might push the
1906 ** time below the minimum representable time.
1907 ** Set tm_sec to 59 instead.
1908 ** This assumes that the minimum representable time is
1909 ** not in the same minute that a leap second was deleted from,
1910 ** which is a safer assumption than using 58 would be.
1911 */
1912 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1913 return WRONG;
1914 saved_seconds = yourtm.tm_sec;
1915 yourtm.tm_sec = SECSPERMIN - 1;
1916 } else {
1917 saved_seconds = yourtm.tm_sec;
1918 yourtm.tm_sec = 0;
1919 }
1920 /*
1560 ** Divide the search space in half
1561 ** (this works whether time_t is signed or unsigned).
1921 ** Do a binary search (this works whatever time_t's type is).
1562 */
1922 */
1563 bits = TYPE_BIT(time_t) - 1;
1564 /*
1565 ** If we have more than this, we will overflow tm_year for tmcomp().
1566 ** We should really return an error if we cannot represent it.
1567 */
1568 if (bits > 48)
1569 bits = 48;
1570 /*
1571 ** If time_t is signed, then 0 is just above the median,
1572 ** assuming two's complement arithmetic.
1573 ** If time_t is unsigned, then (1 << bits) is just above the median.
1574 */
1575 t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits);
1923 if (!TYPE_SIGNED(time_t)) {
1924 lo = 0;
1925 hi = lo - 1;
1926 } else if (!TYPE_INTEGRAL(time_t)) {
1927 if (sizeof(time_t) > sizeof(float))
1928 hi = (time_t) DBL_MAX;
1929 else hi = (time_t) FLT_MAX;
1930 lo = -hi;
1931 } else {
1932 lo = 1;
1933 for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
1934 lo *= 2;
1935 hi = -(lo + 1);
1936 }
1576 for ( ; ; ) {
1937 for ( ; ; ) {
1577 (*funcp)(&t, offset, &mytm);
1578 dir = tmcomp(&mytm, &yourtm);
1938 t = lo / 2 + hi / 2;
1939 if (t < lo)
1940 t = lo;
1941 else if (t > hi)
1942 t = hi;
1943 if ((*funcp)(&t, offset, &mytm) == NULL) {
1944 /*
1945 ** Assume that t is too extreme to be represented in
1946 ** a struct tm; arrange things so that it is less
1947 ** extreme on the next pass.
1948 */
1949 dir = (t > 0) ? 1 : -1;
1950 } else dir = tmcomp(&mytm, &yourtm);
1579 if (dir != 0) {
1951 if (dir != 0) {
1580 if (bits-- < 0)
1952 if (t == lo) {
1953 ++t;
1954 if (t <= lo)
1955 return WRONG;
1956 ++lo;
1957 } else if (t == hi) {
1958 --t;
1959 if (t >= hi)
1960 return WRONG;
1961 --hi;
1962 }
1963 if (lo > hi)
1581 return WRONG;
1964 return WRONG;
1582 if (bits < 0)
1583 --t; /* may be needed if new t is minimal */
1584 else if (dir > 0)
1585 t -= ((time_t) 1) << bits;
1586 else t += ((time_t) 1) << bits;
1965 if (dir > 0)
1966 hi = t;
1967 else lo = t;
1587 continue;
1588 }
1589 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
1590 break;
1591 /*
1592 ** Right time, wrong type.
1593 ** Hunt for right time, right type.
1594 ** It's okay to guess wrong since the guess
1595 ** gets checked.
1596 */
1968 continue;
1969 }
1970 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
1971 break;
1972 /*
1973 ** Right time, wrong type.
1974 ** Hunt for right time, right type.
1975 ** It's okay to guess wrong since the guess
1976 ** gets checked.
1977 */
1597 sp = (funcp == localsub) ? lclptr : gmtptr;
1978 sp = (const struct state *)
1979 ((funcp == localsub) ? lclptr : gmtptr);
1598#ifdef ALL_STATE
1599 if (sp == NULL)
1600 return WRONG;
1601#endif /* defined ALL_STATE */
1602 for (i = sp->typecnt - 1; i >= 0; --i) {
1603 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
1604 continue;
1605 for (j = sp->typecnt - 1; j >= 0; --j) {
1606 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
1607 continue;
1608 newt = t + sp->ttis[j].tt_gmtoff -
1609 sp->ttis[i].tt_gmtoff;
1980#ifdef ALL_STATE
1981 if (sp == NULL)
1982 return WRONG;
1983#endif /* defined ALL_STATE */
1984 for (i = sp->typecnt - 1; i >= 0; --i) {
1985 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
1986 continue;
1987 for (j = sp->typecnt - 1; j >= 0; --j) {
1988 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
1989 continue;
1990 newt = t + sp->ttis[j].tt_gmtoff -
1991 sp->ttis[i].tt_gmtoff;
1610 (*funcp)(&newt, offset, &mytm);
1992 if ((*funcp)(&newt, offset, &mytm) == NULL)
1993 continue;
1611 if (tmcomp(&mytm, &yourtm) != 0)
1612 continue;
1613 if (mytm.tm_isdst != yourtm.tm_isdst)
1614 continue;
1615 /*
1616 ** We have a match.
1617 */
1618 t = newt;
1619 goto label;
1620 }
1621 }
1622 return WRONG;
1623 }
1624label:
1625 newt = t + saved_seconds;
1626 if ((newt < t) != (saved_seconds < 0))
1627 return WRONG;
1628 t = newt;
1994 if (tmcomp(&mytm, &yourtm) != 0)
1995 continue;
1996 if (mytm.tm_isdst != yourtm.tm_isdst)
1997 continue;
1998 /*
1999 ** We have a match.
2000 */
2001 t = newt;
2002 goto label;
2003 }
2004 }
2005 return WRONG;
2006 }
2007label:
2008 newt = t + saved_seconds;
2009 if ((newt < t) != (saved_seconds < 0))
2010 return WRONG;
2011 t = newt;
1629 (*funcp)(&t, offset, tmp);
1630 *okayp = TRUE;
2012 if ((*funcp)(&t, offset, tmp))
2013 *okayp = TRUE;
1631 return t;
1632}
1633
1634static time_t
1635time2(tmp, funcp, offset, okayp)
1636struct tm * const tmp;
2014 return t;
2015}
2016
2017static time_t
2018time2(tmp, funcp, offset, okayp)
2019struct tm * const tmp;
1637void (* const funcp)(const time_t*, long, struct tm*);
2020struct tm * (* const funcp)(const time_t*, long, struct tm*);
1638const long offset;
1639int * const okayp;
1640{
1641 time_t t;
1642
1643 /*
1644 ** First try without normalization of seconds
1645 ** (in case tm_sec contains a value associated with a leap second).
1646 ** If that fails, try with normalization of seconds.
1647 */
1648 t = time2sub(tmp, funcp, offset, okayp, FALSE);
1649 return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
1650}
1651
1652static time_t
1653time1(tmp, funcp, offset)
1654struct tm * const tmp;
2021const long offset;
2022int * const okayp;
2023{
2024 time_t t;
2025
2026 /*
2027 ** First try without normalization of seconds
2028 ** (in case tm_sec contains a value associated with a leap second).
2029 ** If that fails, try with normalization of seconds.
2030 */
2031 t = time2sub(tmp, funcp, offset, okayp, FALSE);
2032 return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
2033}
2034
2035static time_t
2036time1(tmp, funcp, offset)
2037struct tm * const tmp;
1655void (* const funcp)(const time_t *, long, struct tm *);
2038struct tm * (* const funcp)(const time_t *, long, struct tm *);
1656const long offset;
1657{
1658 time_t t;
1659 const struct state * sp;
1660 int samei, otheri;
1661 int sameind, otherind;
1662 int i;
1663 int nseen;
1664 int seen[TZ_MAX_TYPES];
1665 int types[TZ_MAX_TYPES];
1666 int okay;
1667
1668 if (tmp->tm_isdst > 1)
1669 tmp->tm_isdst = 1;
1670 t = time2(tmp, funcp, offset, &okay);
1671#ifdef PCTS
1672 /*
2039const long offset;
2040{
2041 time_t t;
2042 const struct state * sp;
2043 int samei, otheri;
2044 int sameind, otherind;
2045 int i;
2046 int nseen;
2047 int seen[TZ_MAX_TYPES];
2048 int types[TZ_MAX_TYPES];
2049 int okay;
2050
2051 if (tmp->tm_isdst > 1)
2052 tmp->tm_isdst = 1;
2053 t = time2(tmp, funcp, offset, &okay);
2054#ifdef PCTS
2055 /*
1673 ** PCTS code courtesy Grant Sullivan (grant@osf.org).
2056 ** PCTS code courtesy Grant Sullivan.
1674 */
1675 if (okay)
1676 return t;
1677 if (tmp->tm_isdst < 0)
1678 tmp->tm_isdst = 0; /* reset to std and try again */
1679#endif /* defined PCTS */
1680#ifndef PCTS
1681 if (okay || tmp->tm_isdst < 0)
1682 return t;
1683#endif /* !defined PCTS */
1684 /*
1685 ** We're supposed to assume that somebody took a time of one type
1686 ** and did some math on it that yielded a "struct tm" that's bad.
1687 ** We try to divine the type they started from and adjust to the
1688 ** type they need.
1689 */
2057 */
2058 if (okay)
2059 return t;
2060 if (tmp->tm_isdst < 0)
2061 tmp->tm_isdst = 0; /* reset to std and try again */
2062#endif /* defined PCTS */
2063#ifndef PCTS
2064 if (okay || tmp->tm_isdst < 0)
2065 return t;
2066#endif /* !defined PCTS */
2067 /*
2068 ** We're supposed to assume that somebody took a time of one type
2069 ** and did some math on it that yielded a "struct tm" that's bad.
2070 ** We try to divine the type they started from and adjust to the
2071 ** type they need.
2072 */
1690 sp = (funcp == localsub) ? lclptr : gmtptr;
2073 sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr);
1691#ifdef ALL_STATE
1692 if (sp == NULL)
1693 return WRONG;
1694#endif /* defined ALL_STATE */
1695 for (i = 0; i < sp->typecnt; ++i)
1696 seen[i] = FALSE;
1697 nseen = 0;
1698 for (i = sp->timecnt - 1; i >= 0; --i)

--- 129 unchanged lines hidden (view full) ---

1828time_t t;
1829{
1830 time_t x;
1831 time_t y;
1832
1833 tzset();
1834 /*
1835 ** For a positive leap second hit, the result
2074#ifdef ALL_STATE
2075 if (sp == NULL)
2076 return WRONG;
2077#endif /* defined ALL_STATE */
2078 for (i = 0; i < sp->typecnt; ++i)
2079 seen[i] = FALSE;
2080 nseen = 0;
2081 for (i = sp->timecnt - 1; i >= 0; --i)

--- 129 unchanged lines hidden (view full) ---

2211time_t t;
2212{
2213 time_t x;
2214 time_t y;
2215
2216 tzset();
2217 /*
2218 ** For a positive leap second hit, the result
1836 ** is not unique. For a negative leap second
2219 ** is not unique. For a negative leap second
1837 ** hit, the corresponding time doesn't exist,
1838 ** so we return an adjacent second.
1839 */
1840 x = t + leapcorr(&t);
1841 y = x - leapcorr(&x);
1842 if (y < t) {
1843 do {
1844 x++;

--- 16 unchanged lines hidden ---
2220 ** hit, the corresponding time doesn't exist,
2221 ** so we return an adjacent second.
2222 */
2223 x = t + leapcorr(&t);
2224 y = x - leapcorr(&x);
2225 if (y < t) {
2226 do {
2227 x++;

--- 16 unchanged lines hidden ---