w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

localtime.c
Go to the documentation of this file.
1 /*
2 ** This file is in the public domain, so clarified as of
3 ** 1996-06-05 by Arthur David Olson.
4 */
5 
6 /*
7 ** Leap second handling from Bradley White.
8 ** POSIX-style TZ environment variable handling from Guy Harris.
9 */
10 
11 /*LINTLIBRARY*/
12 
13 #include "private.h"
14 #include "tzfile.h"
15 #include "fcntl.h"
16 
17 #ifndef TZ_ABBR_MAX_LEN
18 #define TZ_ABBR_MAX_LEN 16
19 #endif /* !defined TZ_ABBR_MAX_LEN */
20 
21 #ifndef TZ_ABBR_CHAR_SET
22 #define TZ_ABBR_CHAR_SET \
23  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
24 #endif /* !defined TZ_ABBR_CHAR_SET */
25 
26 #ifndef TZ_ABBR_ERR_CHAR
27 #define TZ_ABBR_ERR_CHAR '_'
28 #endif /* !defined TZ_ABBR_ERR_CHAR */
29 
30 /*
31 ** SunOS 4.1.1 headers lack O_BINARY.
32 */
33 
34 #ifdef O_BINARY
35 #define OPEN_MODE (O_RDONLY | O_BINARY)
36 #endif /* defined O_BINARY */
37 #ifndef O_BINARY
38 #define OPEN_MODE O_RDONLY
39 #endif /* !defined O_BINARY */
40 
41 #ifndef WILDABBR
42 /*
43 ** Someone might make incorrect use of a time zone abbreviation:
44 ** 1. They might reference tzname[0] before calling tzset (explicitly
45 ** or implicitly).
46 ** 2. They might reference tzname[1] before calling tzset (explicitly
47 ** or implicitly).
48 ** 3. They might reference tzname[1] after setting to a time zone
49 ** in which Daylight Saving Time is never observed.
50 ** 4. They might reference tzname[0] after setting to a time zone
51 ** in which Standard Time is never observed.
52 ** 5. They might reference tm.TM_ZONE after calling offtime.
53 ** What's best to do in the above cases is open to debate;
54 ** for now, we just set things up so that in any of the five cases
55 ** WILDABBR is used. Another possibility: initialize tzname[0] to the
56 ** string "tzname[0] used before set", and similarly for the other cases.
57 ** And another: initialize tzname[0] to "ERA", with an explanation in the
58 ** manual page of what this "time zone abbreviation" means (doing this so
59 ** that tzname[0] has the "normal" length of three characters).
60 */
61 #define WILDABBR " "
62 #endif /* !defined WILDABBR */
63 
64 static const char wildabbr[] = WILDABBR;
65 
66 static const char gmt[] = "GMT";
67 
68 /*
69 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
70 ** We default to US rules as of 1999-08-17.
71 ** POSIX 1003.1 section 8.1.1 says that the default DST rules are
72 ** implementation dependent; for historical reasons, US rules are a
73 ** common default.
74 */
75 #ifndef TZDEFRULESTRING
76 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
77 #endif /* !defined TZDEFDST */
78 
79 struct ttinfo { /* time type information */
80  int_fast32_t tt_gmtoff; /* UT offset in seconds */
81  int tt_isdst; /* used to set tm_isdst */
82  int tt_abbrind; /* abbreviation list index */
83  int tt_ttisstd; /* TRUE if transition is std time */
84  int tt_ttisgmt; /* TRUE if transition is UT */
85 };
86 
87 struct lsinfo { /* leap second information */
88  time_t ls_trans; /* transition time */
89  int_fast64_t ls_corr; /* correction to apply */
90 };
91 
92 #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
93 
94 #ifdef TZNAME_MAX
95 #define MY_TZNAME_MAX TZNAME_MAX
96 #endif /* defined TZNAME_MAX */
97 #ifndef TZNAME_MAX
98 #define MY_TZNAME_MAX 255
99 #endif /* !defined TZNAME_MAX */
100 
101 struct state {
102  int leapcnt;
103  int timecnt;
104  int typecnt;
105  int charcnt;
106  int goback;
107  int goahead;
109  unsigned char types[TZ_MAX_TIMES];
110  struct ttinfo ttis[TZ_MAX_TYPES];
111  char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
112  (2 * (MY_TZNAME_MAX + 1)))];
113  struct lsinfo lsis[TZ_MAX_LEAPS];
114  int defaulttype; /* for early times or if no transitions */
115 };
116 
117 struct rule {
118  int r_type; /* type of rule--see below */
119  int r_day; /* day number of rule */
120  int r_week; /* week number of rule */
121  int r_mon; /* month number of rule */
122  int_fast32_t r_time; /* transition time of rule */
123 };
124 
125 #define JULIAN_DAY 0 /* Jn - Julian day */
126 #define DAY_OF_YEAR 1 /* n - day of year */
127 #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
128 
129 /*
130 ** Prototypes for static functions.
131 */
132 
133 static int_fast32_t detzcode(const char * codep);
134 static int_fast64_t detzcode64(const char * codep);
135 static int differ_by_repeat(time_t t1, time_t t0);
136 static const char * getzname(const char * strp) ATTRIBUTE_PURE;
137 static const char * getqzname(const char * strp, const int delim)
139 static const char * getnum(const char * strp, int * nump, int min,
140  int max);
141 static const char * getsecs(const char * strp, int_fast32_t * secsp);
142 static const char * getoffset(const char * strp, int_fast32_t * offsetp);
143 static const char * getrule(const char * strp, struct rule * rulep);
144 static void gmtload(struct state * sp);
145 static struct tm * gmtsub(const time_t * timep, int_fast32_t offset,
146  struct tm * tmp);
147 static struct tm * localsub(const time_t * timep, int_fast32_t offset,
148  struct tm * tmp);
149 static int increment_overflow(int * number, int delta);
151 static int increment_overflow32(int_fast32_t * number, int delta);
153 static int normalize_overflow32(int_fast32_t * tensptr,
154  int * unitsptr, int base);
155 static int normalize_overflow(int * tensptr, int * unitsptr,
156  int base);
157 static void settzname(void);
158 static time_t time1(struct tm * tmp,
159  struct tm * (*funcp)(const time_t *,
160  int_fast32_t, struct tm *),
162 static time_t time2(struct tm *tmp,
163  struct tm * (*funcp)(const time_t *,
164  int_fast32_t, struct tm*),
165  int_fast32_t offset, int * okayp);
166 static time_t time2sub(struct tm *tmp,
167  struct tm * (*funcp)(const time_t *,
168  int_fast32_t, struct tm*),
169  int_fast32_t offset, int * okayp, int do_norm_secs);
170 static struct tm * timesub(const time_t * timep, int_fast32_t offset,
171  const struct state * sp, struct tm * tmp);
172 static int tmcomp(const struct tm * atmp,
173  const struct tm * btmp);
174 static int_fast32_t transtime(int year, const struct rule * rulep,
177 static int typesequiv(const struct state * sp, int a, int b);
178 static int tzload(const char * name, struct state * sp,
179  int doextend);
180 static int tzparse(const char * name, struct state * sp,
181  int lastditch);
182 
183 #ifdef ALL_STATE
184 static struct state * lclptr;
185 static struct state * gmtptr;
186 #endif /* defined ALL_STATE */
187 
188 #ifndef ALL_STATE
189 static struct state lclmem;
190 static struct state gmtmem;
191 #define lclptr (&lclmem)
192 #define gmtptr (&gmtmem)
193 #endif /* State Farm */
194 
195 #ifndef TZ_STRLEN_MAX
196 #define TZ_STRLEN_MAX 255
197 #endif /* !defined TZ_STRLEN_MAX */
198 
199 static char lcl_TZname[TZ_STRLEN_MAX + 1];
200 static int lcl_is_set;
201 static int gmt_is_set;
202 
203 char * tzname[2] = {
204  (char *) wildabbr,
205  (char *) wildabbr
206 };
207 
208 /*
209 ** Section 4.12.3 of X3.159-1989 requires that
210 ** Except for the strftime function, these functions [asctime,
211 ** ctime, gmtime, localtime] return values in one of two static
212 ** objects: a broken-down time structure and an array of char.
213 ** Thanks to Paul Eggert for noting this.
214 */
215 
216 static struct tm tm;
217 
218 #ifdef USG_COMPAT
219 long timezone = 0;
220 int daylight = 0;
221 #endif /* defined USG_COMPAT */
222 
223 #ifdef ALTZONE
224 long altzone = 0;
225 #endif /* defined ALTZONE */
226 
227 static int_fast32_t
228 detzcode(const char *const codep)
229 {
230  register int_fast32_t result;
231  register int i;
232 
233  result = (codep[0] & 0x80) ? -1 : 0;
234  for (i = 0; i < 4; ++i)
235  result = (result << 8) | (codep[i] & 0xff);
236  return result;
237 }
238 
239 static int_fast64_t
240 detzcode64(const char *const codep)
241 {
242  register int_fast64_t result;
243  register int i;
244 
245  result = (codep[0] & 0x80) ? -1 : 0;
246  for (i = 0; i < 8; ++i)
247  result = (result << 8) | (codep[i] & 0xff);
248  return result;
249 }
250 
251 static void
253 {
254  register struct state * const sp = lclptr;
255  register int i;
256 
257  tzname[0] = tzname[1] = (char *) wildabbr;
258 #ifdef USG_COMPAT
259  daylight = 0;
260  timezone = 0;
261 #endif /* defined USG_COMPAT */
262 #ifdef ALTZONE
263  altzone = 0;
264 #endif /* defined ALTZONE */
265  if (sp == NULL) {
266  tzname[0] = tzname[1] = (char *) gmt;
267  return;
268  }
269  /*
270  ** And to get the latest zone names into tzname. . .
271  */
272  for (i = 0; i < sp->typecnt; ++i) {
273  register const struct ttinfo * const ttisp = &sp->ttis[i];
274 
275  tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];
276  }
277  for (i = 0; i < sp->timecnt; ++i) {
278  register const struct ttinfo * const ttisp =
279  &sp->ttis[
280  sp->types[i]];
281 
282  tzname[ttisp->tt_isdst] =
283  &sp->chars[ttisp->tt_abbrind];
284 #ifdef USG_COMPAT
285  if (ttisp->tt_isdst)
286  daylight = 1;
287  if (!ttisp->tt_isdst)
288  timezone = -(ttisp->tt_gmtoff);
289 #endif /* defined USG_COMPAT */
290 #ifdef ALTZONE
291  if (ttisp->tt_isdst)
292  altzone = -(ttisp->tt_gmtoff);
293 #endif /* defined ALTZONE */
294  }
295  /*
296  ** Finally, scrub the abbreviations.
297  ** First, replace bogus characters.
298  */
299  for (i = 0; i < sp->charcnt; ++i)
300  if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
301  sp->chars[i] = TZ_ABBR_ERR_CHAR;
302  /*
303  ** Second, truncate long abbreviations.
304  */
305  for (i = 0; i < sp->typecnt; ++i) {
306  register const struct ttinfo * const ttisp = &sp->ttis[i];
307  register char * cp = &sp->chars[ttisp->tt_abbrind];
308 
309  if (strlen(cp) > TZ_ABBR_MAX_LEN &&
310  strcmp(cp, GRANDPARENTED) != 0)
311  *(cp + TZ_ABBR_MAX_LEN) = '\0';
312  }
313 }
314 
315 static int
317 {
319  return 0;
320  return t1 - t0 == SECSPERREPEAT;
321 }
322 
323 static int
324 tzload(register const char *name, register struct state *const sp,
325  register const int doextend)
326 {
327  register const char * p;
328  register int i;
329  register int fid;
330  register int stored;
331  register int nread;
332  typedef union {
333  struct tzhead tzhead;
334  char buf[2 * sizeof(struct tzhead) +
335  2 * sizeof *sp +
336  4 * TZ_MAX_TIMES];
337  } u_t;
338 #ifdef ALL_STATE
339  register u_t * const up = malloc(sizeof *up);
340 #else /* !defined ALL_STATE */
341  u_t u;
342  register u_t * const up = &u;
343 #endif /* !defined ALL_STATE */
344 
345  sp->goback = sp->goahead = FALSE;
346 
347  if (up == NULL)
348  return -1;
349 
350  if (name == NULL && (name = TZDEFAULT) == NULL)
351  goto oops;
352  {
353  register int doaccess;
354  /*
355  ** Section 4.9.1 of the C standard says that
356  ** "FILENAME_MAX expands to an integral constant expression
357  ** that is the size needed for an array of char large enough
358  ** to hold the longest file name string that the implementation
359  ** guarantees can be opened."
360  */
361  char fullname[FILENAME_MAX + 1];
362 
363  if (name[0] == ':')
364  ++name;
365  doaccess = name[0] == '/';
366  if (!doaccess) {
367  if ((p = TZDIR) == NULL)
368  goto oops;
369  if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
370  goto oops;
371  (void) strcpy(fullname, p);
372  (void) strcat(fullname, "/");
373  (void) strcat(fullname, name);
374  /*
375  ** Set doaccess if '.' (as in "../") shows up in name.
376  */
377  if (strchr(name, '.') != NULL)
378  doaccess = TRUE;
379  name = fullname;
380  }
381  if (doaccess && access(name, R_OK) != 0)
382  goto oops;
383  if ((fid = open(name, OPEN_MODE)) == -1)
384  goto oops;
385  }
386  nread = read(fid, up->buf, sizeof up->buf);
387  if (close(fid) < 0 || nread <= 0)
388  goto oops;
389  for (stored = 4; stored <= 8; stored *= 2) {
390  int ttisstdcnt;
391  int ttisgmtcnt;
392  int timecnt;
393 
394  ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt);
395  ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt);
396  sp->leapcnt = (int) detzcode(up->tzhead.tzh_leapcnt);
397  sp->timecnt = (int) detzcode(up->tzhead.tzh_timecnt);
398  sp->typecnt = (int) detzcode(up->tzhead.tzh_typecnt);
399  sp->charcnt = (int) detzcode(up->tzhead.tzh_charcnt);
400  p = up->tzhead.tzh_charcnt + sizeof up->tzhead.tzh_charcnt;
401  if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
402  sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
403  sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
404  sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
405  (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
406  (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
407  goto oops;
408  if (nread - (p - up->buf) <
409  sp->timecnt * stored + /* ats */
410  sp->timecnt + /* types */
411  sp->typecnt * 6 + /* ttinfos */
412  sp->charcnt + /* chars */
413  sp->leapcnt * (stored + 4) + /* lsinfos */
414  ttisstdcnt + /* ttisstds */
415  ttisgmtcnt) /* ttisgmts */
416  goto oops;
417  timecnt = 0;
418  for (i = 0; i < sp->timecnt; ++i) {
419  int_fast64_t at
420  = stored == 4 ? detzcode(p) : detzcode64(p);
421  sp->types[i] = ((TYPE_SIGNED(time_t)
422  ? time_t_min <= at
423  : 0 <= at)
424  && at <= time_t_max);
425  if (sp->types[i]) {
426  if (i && !timecnt && at != time_t_min) {
427  /*
428  ** Keep the earlier record, but tweak
429  ** it so that it starts with the
430  ** minimum time_t value.
431  */
432  sp->types[i - 1] = 1;
433  sp->ats[timecnt++] = time_t_min;
434  }
435  sp->ats[timecnt++] = at;
436  }
437  p += stored;
438  }
439  timecnt = 0;
440  for (i = 0; i < sp->timecnt; ++i) {
441  unsigned char typ = *p++;
442  if (sp->typecnt <= typ)
443  goto oops;
444  if (sp->types[i])
445  sp->types[timecnt++] = typ;
446  }
447  sp->timecnt = timecnt;
448  for (i = 0; i < sp->typecnt; ++i) {
449  register struct ttinfo * ttisp;
450 
451  ttisp = &sp->ttis[i];
452  ttisp->tt_gmtoff = detzcode(p);
453  p += 4;
454  ttisp->tt_isdst = (unsigned char) *p++;
455  if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
456  goto oops;
457  ttisp->tt_abbrind = (unsigned char) *p++;
458  if (ttisp->tt_abbrind < 0 ||
459  ttisp->tt_abbrind > sp->charcnt)
460  goto oops;
461  }
462  for (i = 0; i < sp->charcnt; ++i)
463  sp->chars[i] = *p++;
464  sp->chars[i] = '\0'; /* ensure '\0' at end */
465  for (i = 0; i < sp->leapcnt; ++i) {
466  register struct lsinfo * lsisp;
467 
468  lsisp = &sp->lsis[i];
469  lsisp->ls_trans = (stored == 4) ?
470  detzcode(p) : detzcode64(p);
471  p += stored;
472  lsisp->ls_corr = detzcode(p);
473  p += 4;
474  }
475  for (i = 0; i < sp->typecnt; ++i) {
476  register struct ttinfo * ttisp;
477 
478  ttisp = &sp->ttis[i];
479  if (ttisstdcnt == 0)
480  ttisp->tt_ttisstd = FALSE;
481  else {
482  ttisp->tt_ttisstd = *p++;
483  if (ttisp->tt_ttisstd != TRUE &&
484  ttisp->tt_ttisstd != FALSE)
485  goto oops;
486  }
487  }
488  for (i = 0; i < sp->typecnt; ++i) {
489  register struct ttinfo * ttisp;
490 
491  ttisp = &sp->ttis[i];
492  if (ttisgmtcnt == 0)
493  ttisp->tt_ttisgmt = FALSE;
494  else {
495  ttisp->tt_ttisgmt = *p++;
496  if (ttisp->tt_ttisgmt != TRUE &&
497  ttisp->tt_ttisgmt != FALSE)
498  goto oops;
499  }
500  }
501  /*
502  ** If this is an old file, we're done.
503  */
504  if (up->tzhead.tzh_version[0] == '\0')
505  break;
506  nread -= p - up->buf;
507  for (i = 0; i < nread; ++i)
508  up->buf[i] = p[i];
509  /*
510  ** If this is a signed narrow time_t system, we're done.
511  */
512  if (TYPE_SIGNED(time_t) && stored >= (int) sizeof(time_t))
513  break;
514  }
515  if (doextend && nread > 2 &&
516  up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
517  sp->typecnt + 2 <= TZ_MAX_TYPES) {
518  struct state ts;
519  register int result;
520 
521  up->buf[nread - 1] = '\0';
522  result = tzparse(&up->buf[1], &ts, FALSE);
523  if (result == 0 && ts.typecnt == 2 &&
524  sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
525  for (i = 0; i < 2; ++i)
526  ts.ttis[i].tt_abbrind +=
527  sp->charcnt;
528  for (i = 0; i < ts.charcnt; ++i)
529  sp->chars[sp->charcnt++] =
530  ts.chars[i];
531  i = 0;
532  while (i < ts.timecnt &&
533  ts.ats[i] <=
534  sp->ats[sp->timecnt - 1])
535  ++i;
536  while (i < ts.timecnt &&
537  sp->timecnt < TZ_MAX_TIMES) {
538  sp->ats[sp->timecnt] =
539  ts.ats[i];
540  sp->types[sp->timecnt] =
541  sp->typecnt +
542  ts.types[i];
543  ++sp->timecnt;
544  ++i;
545  }
546  sp->ttis[sp->typecnt++] = ts.ttis[0];
547  sp->ttis[sp->typecnt++] = ts.ttis[1];
548  }
549  }
550  if (sp->timecnt > 1) {
551  for (i = 1; i < sp->timecnt; ++i)
552  if (typesequiv(sp, sp->types[i], sp->types[0]) &&
553  differ_by_repeat(sp->ats[i], sp->ats[0])) {
554  sp->goback = TRUE;
555  break;
556  }
557  for (i = sp->timecnt - 2; i >= 0; --i)
558  if (typesequiv(sp, sp->types[sp->timecnt - 1],
559  sp->types[i]) &&
560  differ_by_repeat(sp->ats[sp->timecnt - 1],
561  sp->ats[i])) {
562  sp->goahead = TRUE;
563  break;
564  }
565  }
566  /*
567  ** If type 0 is is unused in transitions,
568  ** it's the type to use for early times.
569  */
570  for (i = 0; i < sp->typecnt; ++i)
571  if (sp->types[i] == 0)
572  break;
573  i = (i >= sp->typecnt) ? 0 : -1;
574  /*
575  ** Absent the above,
576  ** if there are transition times
577  ** and the first transition is to a daylight time
578  ** find the standard type less than and closest to
579  ** the type of the first transition.
580  */
581  if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
582  i = sp->types[0];
583  while (--i >= 0)
584  if (!sp->ttis[i].tt_isdst)
585  break;
586  }
587  /*
588  ** If no result yet, find the first standard type.
589  ** If there is none, punt to type zero.
590  */
591  if (i < 0) {
592  i = 0;
593  while (sp->ttis[i].tt_isdst)
594  if (++i >= sp->typecnt) {
595  i = 0;
596  break;
597  }
598  }
599  sp->defaulttype = i;
600 #ifdef ALL_STATE
601  free(up);
602 #endif /* defined ALL_STATE */
603  return 0;
604 oops:
605 #ifdef ALL_STATE
606  free(up);
607 #endif /* defined ALL_STATE */
608  return -1;
609 }
610 
611 static int
612 typesequiv(const struct state *const sp, const int a, const int b)
613 {
614  register int result;
615 
616  if (sp == NULL ||
617  a < 0 || a >= sp->typecnt ||
618  b < 0 || b >= sp->typecnt)
619  result = FALSE;
620  else {
621  register const struct ttinfo * ap = &sp->ttis[a];
622  register const struct ttinfo * bp = &sp->ttis[b];
623  result = ap->tt_gmtoff == bp->tt_gmtoff &&
624  ap->tt_isdst == bp->tt_isdst &&
625  ap->tt_ttisstd == bp->tt_ttisstd &&
626  ap->tt_ttisgmt == bp->tt_ttisgmt &&
627  strcmp(&sp->chars[ap->tt_abbrind],
628  &sp->chars[bp->tt_abbrind]) == 0;
629  }
630  return result;
631 }
632 
633 static const int mon_lengths[2][MONSPERYEAR] = {
634  { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
635  { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
636 };
637 
638 static const int year_lengths[2] = {
640 };
641 
642 /*
643 ** Given a pointer into a time zone string, scan until a character that is not
644 ** a valid character in a zone name is found. Return a pointer to that
645 ** character.
646 */
647 
648 static const char *
649 getzname(register const char *strp)
650 {
651  register char c;
652 
653  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
654  c != '+')
655  ++strp;
656  return strp;
657 }
658 
659 /*
660 ** Given a pointer into an extended time zone string, scan until the ending
661 ** delimiter of the zone name is located. Return a pointer to the delimiter.
662 **
663 ** As with getzname above, the legal character set is actually quite
664 ** restricted, with other characters producing undefined results.
665 ** We don't do any checking here; checking is done later in common-case code.
666 */
667 
668 static const char *
669 getqzname(register const char *strp, const int delim)
670 {
671  register int c;
672 
673  while ((c = *strp) != '\0' && c != delim)
674  ++strp;
675  return strp;
676 }
677 
678 /*
679 ** Given a pointer into a time zone string, extract a number from that string.
680 ** Check that the number is within a specified range; if it is not, return
681 ** NULL.
682 ** Otherwise, return a pointer to the first character not part of the number.
683 */
684 
685 static const char *
686 getnum(register const char *strp, int *const nump, const int min, const int max)
687 {
688  register char c;
689  register int num;
690 
691  if (strp == NULL || !is_digit(c = *strp))
692  return NULL;
693  num = 0;
694  do {
695  num = num * 10 + (c - '0');
696  if (num > max)
697  return NULL; /* illegal value */
698  c = *++strp;
699  } while (is_digit(c));
700  if (num < min)
701  return NULL; /* illegal value */
702  *nump = num;
703  return strp;
704 }
705 
706 /*
707 ** Given a pointer into a time zone string, extract a number of seconds,
708 ** in hh[:mm[:ss]] form, from the string.
709 ** If any error occurs, return NULL.
710 ** Otherwise, return a pointer to the first character not part of the number
711 ** of seconds.
712 */
713 
714 static const char *
715 getsecs(register const char *strp, int_fast32_t *const secsp)
716 {
717  int num;
718 
719  /*
720  ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
721  ** "M10.4.6/26", which does not conform to Posix,
722  ** but which specifies the equivalent of
723  ** ``02:00 on the first Sunday on or after 23 Oct''.
724  */
725  strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
726  if (strp == NULL)
727  return NULL;
728  *secsp = num * (int_fast32_t) SECSPERHOUR;
729  if (*strp == ':') {
730  ++strp;
731  strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
732  if (strp == NULL)
733  return NULL;
734  *secsp += num * SECSPERMIN;
735  if (*strp == ':') {
736  ++strp;
737  /* `SECSPERMIN' allows for leap seconds. */
738  strp = getnum(strp, &num, 0, SECSPERMIN);
739  if (strp == NULL)
740  return NULL;
741  *secsp += num;
742  }
743  }
744  return strp;
745 }
746 
747 /*
748 ** Given a pointer into a time zone string, extract an offset, in
749 ** [+-]hh[:mm[:ss]] form, from the string.
750 ** If any error occurs, return NULL.
751 ** Otherwise, return a pointer to the first character not part of the time.
752 */
753 
754 static const char *
755 getoffset(register const char *strp, int_fast32_t *const offsetp)
756 {
757  register int neg = 0;
758 
759  if (*strp == '-') {
760  neg = 1;
761  ++strp;
762  } else if (*strp == '+')
763  ++strp;
764  strp = getsecs(strp, offsetp);
765  if (strp == NULL)
766  return NULL; /* illegal time */
767  if (neg)
768  *offsetp = -*offsetp;
769  return strp;
770 }
771 
772 /*
773 ** Given a pointer into a time zone string, extract a rule in the form
774 ** date[/time]. See POSIX section 8 for the format of "date" and "time".
775 ** If a valid rule is not found, return NULL.
776 ** Otherwise, return a pointer to the first character not part of the rule.
777 */
778 
779 static const char *
780 getrule(const char *strp, register struct rule *const rulep)
781 {
782  if (*strp == 'J') {
783  /*
784  ** Julian day.
785  */
786  rulep->r_type = JULIAN_DAY;
787  ++strp;
788  strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
789  } else if (*strp == 'M') {
790  /*
791  ** Month, week, day.
792  */
793  rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
794  ++strp;
795  strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
796  if (strp == NULL)
797  return NULL;
798  if (*strp++ != '.')
799  return NULL;
800  strp = getnum(strp, &rulep->r_week, 1, 5);
801  if (strp == NULL)
802  return NULL;
803  if (*strp++ != '.')
804  return NULL;
805  strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
806  } else if (is_digit(*strp)) {
807  /*
808  ** Day of year.
809  */
810  rulep->r_type = DAY_OF_YEAR;
811  strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
812  } else return NULL; /* invalid format */
813  if (strp == NULL)
814  return NULL;
815  if (*strp == '/') {
816  /*
817  ** Time specified.
818  */
819  ++strp;
820  strp = getoffset(strp, &rulep->r_time);
821  } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
822  return strp;
823 }
824 
825 /*
826 ** Given a year, a rule, and the offset from UT at the time that rule takes
827 ** effect, calculate the year-relative time that rule takes effect.
828 */
829 
830 static int_fast32_t
831 transtime(const int year, register const struct rule *const rulep,
832  const int_fast32_t offset)
833 {
834  register int leapyear;
835  register int_fast32_t value;
836  register int i;
837  int d, m1, yy0, yy1, yy2, dow;
838 
839  INITIALIZE(value);
840  leapyear = isleap(year);
841  switch (rulep->r_type) {
842 
843  case JULIAN_DAY:
844  /*
845  ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
846  ** years.
847  ** In non-leap years, or if the day number is 59 or less, just
848  ** add SECSPERDAY times the day number-1 to the time of
849  ** January 1, midnight, to get the day.
850  */
851  value = (rulep->r_day - 1) * SECSPERDAY;
852  if (leapyear && rulep->r_day >= 60)
853  value += SECSPERDAY;
854  break;
855 
856  case DAY_OF_YEAR:
857  /*
858  ** n - day of year.
859  ** Just add SECSPERDAY times the day number to the time of
860  ** January 1, midnight, to get the day.
861  */
862  value = rulep->r_day * SECSPERDAY;
863  break;
864 
866  /*
867  ** Mm.n.d - nth "dth day" of month m.
868  */
869 
870  /*
871  ** Use Zeller's Congruence to get day-of-week of first day of
872  ** month.
873  */
874  m1 = (rulep->r_mon + 9) % 12 + 1;
875  yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
876  yy1 = yy0 / 100;
877  yy2 = yy0 % 100;
878  dow = ((26 * m1 - 2) / 10 +
879  1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
880  if (dow < 0)
881  dow += DAYSPERWEEK;
882 
883  /*
884  ** "dow" is the day-of-week of the first day of the month. Get
885  ** the day-of-month (zero-origin) of the first "dow" day of the
886  ** month.
887  */
888  d = rulep->r_day - dow;
889  if (d < 0)
890  d += DAYSPERWEEK;
891  for (i = 1; i < rulep->r_week; ++i) {
892  if (d + DAYSPERWEEK >=
893  mon_lengths[leapyear][rulep->r_mon - 1])
894  break;
895  d += DAYSPERWEEK;
896  }
897 
898  /*
899  ** "d" is the day-of-month (zero-origin) of the day we want.
900  */
901  value = d * SECSPERDAY;
902  for (i = 0; i < rulep->r_mon - 1; ++i)
903  value += mon_lengths[leapyear][i] * SECSPERDAY;
904  break;
905  }
906 
907  /*
908  ** "value" is the year-relative time of 00:00:00 UT on the day in
909  ** question. To get the year-relative time of the specified local
910  ** time on that day, add the transition time and the current offset
911  ** from UT.
912  */
913  return value + rulep->r_time + offset;
914 }
915 
916 /*
917 ** Given a POSIX section 8-style TZ string, fill in the rule tables as
918 ** appropriate.
919 */
920 
921 static int
922 tzparse(const char *name, register struct state *const sp,
923  const int lastditch)
924 {
925  const char * stdname;
926  const char * dstname;
927  size_t stdlen;
928  size_t dstlen;
929  int_fast32_t stdoffset;
930  int_fast32_t dstoffset;
931  register char * cp;
932  register int load_result;
933  static struct ttinfo zttinfo;
934 
935  INITIALIZE(dstname);
936  stdname = name;
937  if (lastditch) {
938  stdlen = strlen(name); /* length of standard zone name */
939  name += stdlen;
940  if (stdlen >= sizeof sp->chars)
941  stdlen = (sizeof sp->chars) - 1;
942  stdoffset = 0;
943  } else {
944  if (*name == '<') {
945  name++;
946  stdname = name;
947  name = getqzname(name, '>');
948  if (*name != '>')
949  return (-1);
950  stdlen = name - stdname;
951  name++;
952  } else {
953  name = getzname(name);
954  stdlen = name - stdname;
955  }
956  if (*name == '\0')
957  return -1;
958  name = getoffset(name, &stdoffset);
959  if (name == NULL)
960  return -1;
961  }
962  load_result = tzload(TZDEFRULES, sp, FALSE);
963  if (load_result != 0)
964  sp->leapcnt = 0; /* so, we're off a little */
965  if (*name != '\0') {
966  if (*name == '<') {
967  dstname = ++name;
968  name = getqzname(name, '>');
969  if (*name != '>')
970  return -1;
971  dstlen = name - dstname;
972  name++;
973  } else {
974  dstname = name;
975  name = getzname(name);
976  dstlen = name - dstname; /* length of DST zone name */
977  }
978  if (*name != '\0' && *name != ',' && *name != ';') {
979  name = getoffset(name, &dstoffset);
980  if (name == NULL)
981  return -1;
982  } else dstoffset = stdoffset - SECSPERHOUR;
983  if (*name == '\0' && load_result != 0)
985  if (*name == ',' || *name == ';') {
986  struct rule start;
987  struct rule end;
988  register int year;
989  register int yearlim;
990  register int timecnt;
991  time_t janfirst;
992 
993  ++name;
994  if ((name = getrule(name, &start)) == NULL)
995  return -1;
996  if (*name++ != ',')
997  return -1;
998  if ((name = getrule(name, &end)) == NULL)
999  return -1;
1000  if (*name != '\0')
1001  return -1;
1002  sp->typecnt = 2; /* standard time and DST */
1003  /*
1004  ** Two transitions per year, from EPOCH_YEAR forward.
1005  */
1006  sp->ttis[0] = sp->ttis[1] = zttinfo;
1007  sp->ttis[0].tt_gmtoff = -dstoffset;
1008  sp->ttis[0].tt_isdst = 1;
1009  sp->ttis[0].tt_abbrind = stdlen + 1;
1010  sp->ttis[1].tt_gmtoff = -stdoffset;
1011  sp->ttis[1].tt_isdst = 0;
1012  sp->ttis[1].tt_abbrind = 0;
1013  sp->defaulttype = 0;
1014  timecnt = 0;
1015  janfirst = 0;
1016  yearlim = EPOCH_YEAR + YEARSPERREPEAT;
1017  for (year = EPOCH_YEAR; year < yearlim; year++) {
1018  int_fast32_t
1019  starttime = transtime(year, &start, stdoffset),
1020  endtime = transtime(year, &end, dstoffset);
1021  int_fast32_t
1022  yearsecs = (year_lengths[isleap(year)]
1023  * SECSPERDAY);
1024  int reversed = endtime < starttime;
1025  if (reversed) {
1026  int_fast32_t swap = starttime;
1027  starttime = endtime;
1028  endtime = swap;
1029  }
1030  if (reversed
1031  || (starttime < endtime
1032  && (endtime - starttime
1033  < (yearsecs
1034  + (stdoffset - dstoffset))))) {
1035  if (TZ_MAX_TIMES - 2 < timecnt)
1036  break;
1037  yearlim = year + YEARSPERREPEAT + 1;
1038  sp->ats[timecnt] = janfirst;
1040  (&sp->ats[timecnt], starttime))
1041  break;
1042  sp->types[timecnt++] = reversed;
1043  sp->ats[timecnt] = janfirst;
1045  (&sp->ats[timecnt], endtime))
1046  break;
1047  sp->types[timecnt++] = !reversed;
1048  }
1049  if (increment_overflow_time(&janfirst, yearsecs))
1050  break;
1051  }
1052  sp->timecnt = timecnt;
1053  if (!timecnt)
1054  sp->typecnt = 1; /* Perpetual DST. */
1055  } else {
1056  register int_fast32_t theirstdoffset;
1057  register int_fast32_t theirdstoffset;
1058  register int_fast32_t theiroffset;
1059  register int isdst;
1060  register int i;
1061  register int j;
1062 
1063  if (*name != '\0')
1064  return -1;
1065  /*
1066  ** Initial values of theirstdoffset and theirdstoffset.
1067  */
1068  theirstdoffset = 0;
1069  for (i = 0; i < sp->timecnt; ++i) {
1070  j = sp->types[i];
1071  if (!sp->ttis[j].tt_isdst) {
1072  theirstdoffset =
1073  -sp->ttis[j].tt_gmtoff;
1074  break;
1075  }
1076  }
1077  theirdstoffset = 0;
1078  for (i = 0; i < sp->timecnt; ++i) {
1079  j = sp->types[i];
1080  if (sp->ttis[j].tt_isdst) {
1081  theirdstoffset =
1082  -sp->ttis[j].tt_gmtoff;
1083  break;
1084  }
1085  }
1086  /*
1087  ** Initially we're assumed to be in standard time.
1088  */
1089  isdst = FALSE;
1090  theiroffset = theirstdoffset;
1091  /*
1092  ** Now juggle transition times and types
1093  ** tracking offsets as you do.
1094  */
1095  for (i = 0; i < sp->timecnt; ++i) {
1096  j = sp->types[i];
1097  sp->types[i] = sp->ttis[j].tt_isdst;
1098  if (sp->ttis[j].tt_ttisgmt) {
1099  /* No adjustment to transition time */
1100  } else {
1101  /*
1102  ** If summer time is in effect, and the
1103  ** transition time was not specified as
1104  ** standard time, add the summer time
1105  ** offset to the transition time;
1106  ** otherwise, add the standard time
1107  ** offset to the transition time.
1108  */
1109  /*
1110  ** Transitions from DST to DDST
1111  ** will effectively disappear since
1112  ** POSIX provides for only one DST
1113  ** offset.
1114  */
1115  if (isdst && !sp->ttis[j].tt_ttisstd) {
1116  sp->ats[i] += dstoffset -
1117  theirdstoffset;
1118  } else {
1119  sp->ats[i] += stdoffset -
1120  theirstdoffset;
1121  }
1122  }
1123  theiroffset = -sp->ttis[j].tt_gmtoff;
1124  if (sp->ttis[j].tt_isdst)
1125  theirdstoffset = theiroffset;
1126  else theirstdoffset = theiroffset;
1127  }
1128  /*
1129  ** Finally, fill in ttis.
1130  */
1131  sp->ttis[0] = sp->ttis[1] = zttinfo;
1132  sp->ttis[0].tt_gmtoff = -stdoffset;
1133  sp->ttis[0].tt_isdst = FALSE;
1134  sp->ttis[0].tt_abbrind = 0;
1135  sp->ttis[1].tt_gmtoff = -dstoffset;
1136  sp->ttis[1].tt_isdst = TRUE;
1137  sp->ttis[1].tt_abbrind = stdlen + 1;
1138  sp->typecnt = 2;
1139  sp->defaulttype = 0;
1140  }
1141  } else {
1142  dstlen = 0;
1143  sp->typecnt = 1; /* only standard time */
1144  sp->timecnt = 0;
1145  sp->ttis[0] = zttinfo;
1146  sp->ttis[0].tt_gmtoff = -stdoffset;
1147  sp->ttis[0].tt_isdst = 0;
1148  sp->ttis[0].tt_abbrind = 0;
1149  sp->defaulttype = 0;
1150  }
1151  sp->charcnt = stdlen + 1;
1152  if (dstlen != 0)
1153  sp->charcnt += dstlen + 1;
1154  if ((size_t) sp->charcnt > sizeof sp->chars)
1155  return -1;
1156  cp = sp->chars;
1157  (void) strncpy(cp, stdname, stdlen);
1158  cp += stdlen;
1159  *cp++ = '\0';
1160  if (dstlen != 0) {
1161  (void) strncpy(cp, dstname, dstlen);
1162  *(cp + dstlen) = '\0';
1163  }
1164  return 0;
1165 }
1166 
1167 static void
1168 gmtload(struct state *const sp)
1169 {
1170  if (tzload(gmt, sp, TRUE) != 0)
1171  (void) tzparse(gmt, sp, TRUE);
1172 }
1173 
1174 #ifndef STD_INSPIRED
1175 /*
1176 ** A non-static declaration of tzsetwall in a system header file
1177 ** may cause a warning about this upcoming static declaration...
1178 */
1179 static
1180 #endif /* !defined STD_INSPIRED */
1181 void
1183 {
1184  if (lcl_is_set < 0)
1185  return;
1186  lcl_is_set = -1;
1187 
1188 #ifdef ALL_STATE
1189  if (lclptr == NULL) {
1190  lclptr = malloc(sizeof *lclptr);
1191  if (lclptr == NULL) {
1192  settzname(); /* all we can do */
1193  return;
1194  }
1195  }
1196 #endif /* defined ALL_STATE */
1197  if (tzload(NULL, lclptr, TRUE) != 0)
1198  gmtload(lclptr);
1199  settzname();
1200 }
1201 
1202 void
1203 tzset(void)
1204 {
1205  register const char * name;
1206 
1207  name = getenv("TZ");
1208  if (name == NULL) {
1209  tzsetwall();
1210  return;
1211  }
1212 
1213  if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
1214  return;
1215  lcl_is_set = strlen(name) < sizeof lcl_TZname;
1216  if (lcl_is_set)
1217  (void) strcpy(lcl_TZname, name);
1218 
1219 #ifdef ALL_STATE
1220  if (lclptr == NULL) {
1221  lclptr = malloc(sizeof *lclptr);
1222  if (lclptr == NULL) {
1223  settzname(); /* all we can do */
1224  return;
1225  }
1226  }
1227 #endif /* defined ALL_STATE */
1228  if (*name == '\0') {
1229  /*
1230  ** User wants it fast rather than right.
1231  */
1232  lclptr->leapcnt = 0; /* so, we're off a little */
1233  lclptr->timecnt = 0;
1234  lclptr->typecnt = 0;
1235  lclptr->ttis[0].tt_isdst = 0;
1236  lclptr->ttis[0].tt_gmtoff = 0;
1237  lclptr->ttis[0].tt_abbrind = 0;
1238  (void) strcpy(lclptr->chars, gmt);
1239  } else if (tzload(name, lclptr, TRUE) != 0)
1240  if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
1241  (void) gmtload(lclptr);
1242  settzname();
1243 }
1244 
1245 /*
1246 ** The easy way to behave "as if no library function calls" localtime
1247 ** is to not call it--so we drop its guts into "localsub", which can be
1248 ** freely called. (And no, the PANS doesn't require the above behavior--
1249 ** but it *is* desirable.)
1250 **
1251 ** The unused offset argument is for the benefit of mktime variants.
1252 */
1253 
1254 /*ARGSUSED*/
1255 static struct tm *
1256 localsub(const time_t *const timep, const int_fast32_t offset,
1257  struct tm *const tmp)
1258 {
1259  register struct state * sp;
1260  register const struct ttinfo * ttisp;
1261  register int i;
1262  register struct tm * result;
1263  const time_t t = *timep;
1264 
1265  sp = lclptr;
1266  if (sp == NULL)
1267  return gmtsub(timep, offset, tmp);
1268  if ((sp->goback && t < sp->ats[0]) ||
1269  (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1270  time_t newt = t;
1271  register time_t seconds;
1272  register time_t years;
1273 
1274  if (t < sp->ats[0])
1275  seconds = sp->ats[0] - t;
1276  else seconds = t - sp->ats[sp->timecnt - 1];
1277  --seconds;
1278  years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1279  seconds = years * AVGSECSPERYEAR;
1280  if (t < sp->ats[0])
1281  newt += seconds;
1282  else newt -= seconds;
1283  if (newt < sp->ats[0] ||
1284  newt > sp->ats[sp->timecnt - 1])
1285  return NULL; /* "cannot happen" */
1286  result = localsub(&newt, offset, tmp);
1287  if (result == tmp) {
1288  register time_t newy;
1289 
1290  newy = tmp->tm_year;
1291  if (t < sp->ats[0])
1292  newy -= years;
1293  else newy += years;
1294  tmp->tm_year = newy;
1295  if (tmp->tm_year != newy)
1296  return NULL;
1297  }
1298  return result;
1299  }
1300  if (sp->timecnt == 0 || t < sp->ats[0]) {
1301  i = sp->defaulttype;
1302  } else {
1303  register int lo = 1;
1304  register int hi = sp->timecnt;
1305 
1306  while (lo < hi) {
1307  register int mid = (lo + hi) >> 1;
1308 
1309  if (t < sp->ats[mid])
1310  hi = mid;
1311  else lo = mid + 1;
1312  }
1313  i = (int) sp->types[lo - 1];
1314  }
1315  ttisp = &sp->ttis[i];
1316  /*
1317  ** To get (wrong) behavior that's compatible with System V Release 2.0
1318  ** you'd replace the statement below with
1319  ** t += ttisp->tt_gmtoff;
1320  ** timesub(&t, 0L, sp, tmp);
1321  */
1322  result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1323  tmp->tm_isdst = ttisp->tt_isdst;
1324  tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
1325 #ifdef TM_ZONE
1326  tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
1327 #endif /* defined TM_ZONE */
1328  return result;
1329 }
1330 
1331 struct tm *
1332 localtime(const time_t *const timep)
1333 {
1334  tzset();
1335  return localsub(timep, 0L, &tm);
1336 }
1337 
1338 /*
1339 ** Re-entrant version of localtime.
1340 */
1341 
1342 struct tm *
1343 localtime_r(const time_t *const timep, struct tm *tmp)
1344 {
1345  return localsub(timep, 0L, tmp);
1346 }
1347 
1348 /*
1349 ** gmtsub is to gmtime as localsub is to localtime.
1350 */
1351 
1352 static struct tm *
1353 gmtsub(const time_t *const timep, const int_fast32_t offset,
1354  struct tm *const tmp)
1355 {
1356  register struct tm * result;
1357 
1358  if (!gmt_is_set) {
1359  gmt_is_set = TRUE;
1360 #ifdef ALL_STATE
1361  gmtptr = malloc(sizeof *gmtptr);
1362 #endif /* defined ALL_STATE */
1363  if (gmtptr != NULL)
1364  gmtload(gmtptr);
1365  }
1366  result = timesub(timep, offset, gmtptr, tmp);
1367 #ifdef TM_ZONE
1368  /*
1369  ** Could get fancy here and deliver something such as
1370  ** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
1371  ** but this is no time for a treasure hunt.
1372  */
1373  tmp->TM_ZONE = offset ? wildabbr : gmtptr ? gmtptr->chars : gmt;
1374 #endif /* defined TM_ZONE */
1375  return result;
1376 }
1377 
1378 struct tm *
1379 gmtime(const time_t *const timep)
1380 {
1381  return gmtsub(timep, 0L, &tm);
1382 }
1383 
1384 /*
1385 * Re-entrant version of gmtime.
1386 */
1387 
1388 struct tm *
1389 gmtime_r(const time_t *const timep, struct tm *tmp)
1390 {
1391  return gmtsub(timep, 0L, tmp);
1392 }
1393 
1394 #ifdef STD_INSPIRED
1395 
1396 struct tm *
1397 offtime(const time_t *const timep, const long offset)
1398 {
1399  return gmtsub(timep, offset, &tm);
1400 }
1401 
1402 #endif /* defined STD_INSPIRED */
1403 
1404 /*
1405 ** Return the number of leap years through the end of the given year
1406 ** where, to make the math easy, the answer for year zero is defined as zero.
1407 */
1408 
1409 static int
1410 leaps_thru_end_of(register const int y)
1411 {
1412  return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1413  -(leaps_thru_end_of(-(y + 1)) + 1);
1414 }
1415 
1416 static struct tm *
1417 timesub(const time_t *const timep, const int_fast32_t offset,
1418  register const struct state *const sp,
1419  register struct tm *const tmp)
1420 {
1421  register const struct lsinfo * lp;
1422  register time_t tdays;
1423  register int idays; /* unsigned would be so 2003 */
1424  register int_fast64_t rem;
1425  int y;
1426  register const int * ip;
1427  register int_fast64_t corr;
1428  register int hit;
1429  register int i;
1430 
1431  corr = 0;
1432  hit = 0;
1433  i = (sp == NULL) ? 0 : sp->leapcnt;
1434  while (--i >= 0) {
1435  lp = &sp->lsis[i];
1436  if (*timep >= lp->ls_trans) {
1437  if (*timep == lp->ls_trans) {
1438  hit = ((i == 0 && lp->ls_corr > 0) ||
1439  lp->ls_corr > sp->lsis[i - 1].ls_corr);
1440  if (hit)
1441  while (i > 0 &&
1442  sp->lsis[i].ls_trans ==
1443  sp->lsis[i - 1].ls_trans + 1 &&
1444  sp->lsis[i].ls_corr ==
1445  sp->lsis[i - 1].ls_corr + 1) {
1446  ++hit;
1447  --i;
1448  }
1449  }
1450  corr = lp->ls_corr;
1451  break;
1452  }
1453  }
1454  y = EPOCH_YEAR;
1455  tdays = *timep / SECSPERDAY;
1456  rem = *timep - tdays * SECSPERDAY;
1457  while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1458  int newy;
1459  register time_t tdelta;
1460  register int idelta;
1461  register int leapdays;
1462 
1463  tdelta = tdays / DAYSPERLYEAR;
1464  if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
1465  && tdelta <= INT_MAX))
1466  return NULL;
1467  idelta = tdelta;
1468  if (idelta == 0)
1469  idelta = (tdays < 0) ? -1 : 1;
1470  newy = y;
1471  if (increment_overflow(&newy, idelta))
1472  return NULL;
1473  leapdays = leaps_thru_end_of(newy - 1) -
1474  leaps_thru_end_of(y - 1);
1475  tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1476  tdays -= leapdays;
1477  y = newy;
1478  }
1479  {
1480  register int_fast32_t seconds;
1481 
1482  seconds = tdays * SECSPERDAY;
1483  tdays = seconds / SECSPERDAY;
1484  rem += seconds - tdays * SECSPERDAY;
1485  }
1486  /*
1487  ** Given the range, we can now fearlessly cast...
1488  */
1489  idays = tdays;
1490  rem += offset - corr;
1491  while (rem < 0) {
1492  rem += SECSPERDAY;
1493  --idays;
1494  }
1495  while (rem >= SECSPERDAY) {
1496  rem -= SECSPERDAY;
1497  ++idays;
1498  }
1499  while (idays < 0) {
1500  if (increment_overflow(&y, -1))
1501  return NULL;
1502  idays += year_lengths[isleap(y)];
1503  }
1504  while (idays >= year_lengths[isleap(y)]) {
1505  idays -= year_lengths[isleap(y)];
1506  if (increment_overflow(&y, 1))
1507  return NULL;
1508  }
1509  tmp->tm_year = y;
1510  if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1511  return NULL;
1512  tmp->tm_yday = idays;
1513  /*
1514  ** The "extra" mods below avoid overflow problems.
1515  */
1516  tmp->tm_wday = EPOCH_WDAY +
1517  ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1519  leaps_thru_end_of(y - 1) -
1521  idays;
1522  tmp->tm_wday %= DAYSPERWEEK;
1523  if (tmp->tm_wday < 0)
1524  tmp->tm_wday += DAYSPERWEEK;
1525  tmp->tm_hour = (int) (rem / SECSPERHOUR);
1526  rem %= SECSPERHOUR;
1527  tmp->tm_min = (int) (rem / SECSPERMIN);
1528  /*
1529  ** A positive leap second requires a special
1530  ** representation. This uses "... ??:59:60" et seq.
1531  */
1532  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1533  ip = mon_lengths[isleap(y)];
1534  for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1535  idays -= ip[tmp->tm_mon];
1536  tmp->tm_mday = (int) (idays + 1);
1537  tmp->tm_isdst = 0;
1538 #ifdef TM_GMTOFF
1539  tmp->TM_GMTOFF = offset;
1540 #endif /* defined TM_GMTOFF */
1541  return tmp;
1542 }
1543 
1544 char *
1545 ctime(const time_t *const timep)
1546 {
1547 /*
1548 ** Section 4.12.3.2 of X3.159-1989 requires that
1549 ** The ctime function converts the calendar time pointed to by timer
1550 ** to local time in the form of a string. It is equivalent to
1551 ** asctime(localtime(timer))
1552 */
1553  return asctime(localtime(timep));
1554 }
1555 
1556 char *
1557 ctime_r(const time_t *const timep, char *buf)
1558 {
1559  struct tm mytm;
1560 
1561  return asctime_r(localtime_r(timep, &mytm), buf);
1562 }
1563 
1564 /*
1565 ** Adapted from code provided by Robert Elz, who writes:
1566 ** The "best" way to do mktime I think is based on an idea of Bob
1567 ** Kridle's (so its said...) from a long time ago.
1568 ** It does a binary search of the time_t space. Since time_t's are
1569 ** just 32 bits, its a max of 32 iterations (even at 64 bits it
1570 ** would still be very reasonable).
1571 */
1572 
1573 #ifndef WRONG
1574 #define WRONG (-1)
1575 #endif /* !defined WRONG */
1576 
1577 /*
1578 ** Normalize logic courtesy Paul Eggert.
1579 */
1580 
1581 static int
1582 increment_overflow(int *const ip, int j)
1583 {
1584  register int const i = *ip;
1585 
1586  /*
1587  ** If i >= 0 there can only be overflow if i + j > INT_MAX
1588  ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1589  ** If i < 0 there can only be overflow if i + j < INT_MIN
1590  ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1591  */
1592  if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1593  return TRUE;
1594  *ip += j;
1595  return FALSE;
1596 }
1597 
1598 static int
1600 {
1601  register int_fast32_t const l = *lp;
1602 
1603  if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
1604  return TRUE;
1605  *lp += m;
1606  return FALSE;
1607 }
1608 
1609 static int
1611 {
1612  /*
1613  ** This is like
1614  ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1615  ** except that it does the right thing even if *tp + j would overflow.
1616  */
1617  if (! (j < 0
1618  ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1619  : *tp <= time_t_max - j))
1620  return TRUE;
1621  *tp += j;
1622  return FALSE;
1623 }
1624 
1625 static int
1626 normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
1627 {
1628  register int tensdelta;
1629 
1630  tensdelta = (*unitsptr >= 0) ?
1631  (*unitsptr / base) :
1632  (-1 - (-1 - *unitsptr) / base);
1633  *unitsptr -= tensdelta * base;
1634  return increment_overflow(tensptr, tensdelta);
1635 }
1636 
1637 static int
1638 normalize_overflow32(int_fast32_t *const tensptr, int *const unitsptr,
1639  const int base)
1640 {
1641  register int tensdelta;
1642 
1643  tensdelta = (*unitsptr >= 0) ?
1644  (*unitsptr / base) :
1645  (-1 - (-1 - *unitsptr) / base);
1646  *unitsptr -= tensdelta * base;
1647  return increment_overflow32(tensptr, tensdelta);
1648 }
1649 
1650 static int
1651 tmcomp(register const struct tm *const atmp,
1652  register const struct tm *const btmp)
1653 {
1654  register int result;
1655 
1656  if (atmp->tm_year != btmp->tm_year)
1657  return atmp->tm_year < btmp->tm_year ? -1 : 1;
1658  if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1659  (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1660  (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1661  (result = (atmp->tm_min - btmp->tm_min)) == 0)
1662  result = atmp->tm_sec - btmp->tm_sec;
1663  return result;
1664 }
1665 
1666 static time_t
1667 time2sub(struct tm *const tmp,
1668  struct tm *(*const funcp)(const time_t *, int_fast32_t, struct tm *),
1669  const int_fast32_t offset,
1670  int *const okayp,
1671  const int do_norm_secs)
1672 {
1673  register const struct state * sp;
1674  register int dir;
1675  register int i, j;
1676  register int saved_seconds;
1677  register int_fast32_t li;
1678  register time_t lo;
1679  register time_t hi;
1680  int_fast32_t y;
1681  time_t newt;
1682  time_t t;
1683  struct tm yourtm, mytm;
1684 
1685  *okayp = FALSE;
1686  yourtm = *tmp;
1687  if (do_norm_secs) {
1688  if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1689  SECSPERMIN))
1690  return WRONG;
1691  }
1692  if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1693  return WRONG;
1694  if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1695  return WRONG;
1696  y = yourtm.tm_year;
1697  if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
1698  return WRONG;
1699  /*
1700  ** Turn y into an actual year number for now.
1701  ** It is converted back to an offset from TM_YEAR_BASE later.
1702  */
1704  return WRONG;
1705  while (yourtm.tm_mday <= 0) {
1706  if (increment_overflow32(&y, -1))
1707  return WRONG;
1708  li = y + (1 < yourtm.tm_mon);
1709  yourtm.tm_mday += year_lengths[isleap(li)];
1710  }
1711  while (yourtm.tm_mday > DAYSPERLYEAR) {
1712  li = y + (1 < yourtm.tm_mon);
1713  yourtm.tm_mday -= year_lengths[isleap(li)];
1714  if (increment_overflow32(&y, 1))
1715  return WRONG;
1716  }
1717  for ( ; ; ) {
1718  i = mon_lengths[isleap(y)][yourtm.tm_mon];
1719  if (yourtm.tm_mday <= i)
1720  break;
1721  yourtm.tm_mday -= i;
1722  if (++yourtm.tm_mon >= MONSPERYEAR) {
1723  yourtm.tm_mon = 0;
1724  if (increment_overflow32(&y, 1))
1725  return WRONG;
1726  }
1727  }
1729  return WRONG;
1730  yourtm.tm_year = y;
1731  if (yourtm.tm_year != y)
1732  return WRONG;
1733  if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1734  saved_seconds = 0;
1735  else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1736  /*
1737  ** We can't set tm_sec to 0, because that might push the
1738  ** time below the minimum representable time.
1739  ** Set tm_sec to 59 instead.
1740  ** This assumes that the minimum representable time is
1741  ** not in the same minute that a leap second was deleted from,
1742  ** which is a safer assumption than using 58 would be.
1743  */
1744  if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1745  return WRONG;
1746  saved_seconds = yourtm.tm_sec;
1747  yourtm.tm_sec = SECSPERMIN - 1;
1748  } else {
1749  saved_seconds = yourtm.tm_sec;
1750  yourtm.tm_sec = 0;
1751  }
1752  /*
1753  ** Do a binary search (this works whatever time_t's type is).
1754  */
1755  if (!TYPE_SIGNED(time_t)) {
1756  lo = 0;
1757  hi = lo - 1;
1758  } else {
1759  lo = 1;
1760  for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
1761  lo *= 2;
1762  hi = -(lo + 1);
1763  }
1764  for ( ; ; ) {
1765  t = lo / 2 + hi / 2;
1766  if (t < lo)
1767  t = lo;
1768  else if (t > hi)
1769  t = hi;
1770  if ((*funcp)(&t, offset, &mytm) == NULL) {
1771  /*
1772  ** Assume that t is too extreme to be represented in
1773  ** a struct tm; arrange things so that it is less
1774  ** extreme on the next pass.
1775  */
1776  dir = (t > 0) ? 1 : -1;
1777  } else dir = tmcomp(&mytm, &yourtm);
1778  if (dir != 0) {
1779  if (t == lo) {
1780  if (t == time_t_max)
1781  return WRONG;
1782  ++t;
1783  ++lo;
1784  } else if (t == hi) {
1785  if (t == time_t_min)
1786  return WRONG;
1787  --t;
1788  --hi;
1789  }
1790  if (lo > hi)
1791  return WRONG;
1792  if (dir > 0)
1793  hi = t;
1794  else lo = t;
1795  continue;
1796  }
1797  if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
1798  break;
1799  /*
1800  ** Right time, wrong type.
1801  ** Hunt for right time, right type.
1802  ** It's okay to guess wrong since the guess
1803  ** gets checked.
1804  */
1805  sp = (const struct state *)
1806  ((funcp == localsub) ? lclptr : gmtptr);
1807  if (sp == NULL)
1808  return WRONG;
1809  for (i = sp->typecnt - 1; i >= 0; --i) {
1810  if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
1811  continue;
1812  for (j = sp->typecnt - 1; j >= 0; --j) {
1813  if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
1814  continue;
1815  newt = t + sp->ttis[j].tt_gmtoff -
1816  sp->ttis[i].tt_gmtoff;
1817  if ((*funcp)(&newt, offset, &mytm) == NULL)
1818  continue;
1819  if (tmcomp(&mytm, &yourtm) != 0)
1820  continue;
1821  if (mytm.tm_isdst != yourtm.tm_isdst)
1822  continue;
1823  /*
1824  ** We have a match.
1825  */
1826  t = newt;
1827  goto label;
1828  }
1829  }
1830  return WRONG;
1831  }
1832 label:
1833  newt = t + saved_seconds;
1834  if ((newt < t) != (saved_seconds < 0))
1835  return WRONG;
1836  t = newt;
1837  if ((*funcp)(&t, offset, tmp))
1838  *okayp = TRUE;
1839  return t;
1840 }
1841 
1842 static time_t
1843 time2(struct tm * const tmp,
1844  struct tm * (*const funcp)(const time_t *, int_fast32_t, struct tm *),
1845  const int_fast32_t offset,
1846  int *const okayp)
1847 {
1848  time_t t;
1849 
1850  /*
1851  ** First try without normalization of seconds
1852  ** (in case tm_sec contains a value associated with a leap second).
1853  ** If that fails, try with normalization of seconds.
1854  */
1855  t = time2sub(tmp, funcp, offset, okayp, FALSE);
1856  return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
1857 }
1858 
1859 static time_t
1860 time1(struct tm *const tmp,
1861  struct tm *(*const funcp) (const time_t *, int_fast32_t, struct tm *),
1862  const int_fast32_t offset)
1863 {
1864  register time_t t;
1865  register const struct state * sp;
1866  register int samei, otheri;
1867  register int sameind, otherind;
1868  register int i;
1869  register int nseen;
1870  int seen[TZ_MAX_TYPES];
1871  int types[TZ_MAX_TYPES];
1872  int okay;
1873 
1874  if (tmp == NULL) {
1875  errno = EINVAL;
1876  return WRONG;
1877  }
1878  if (tmp->tm_isdst > 1)
1879  tmp->tm_isdst = 1;
1880  t = time2(tmp, funcp, offset, &okay);
1881  if (okay)
1882  return t;
1883  if (tmp->tm_isdst < 0)
1884 #ifdef PCTS
1885  /*
1886  ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
1887  */
1888  tmp->tm_isdst = 0; /* reset to std and try again */
1889 #else
1890  return t;
1891 #endif /* !defined PCTS */
1892  /*
1893  ** We're supposed to assume that somebody took a time of one type
1894  ** and did some math on it that yielded a "struct tm" that's bad.
1895  ** We try to divine the type they started from and adjust to the
1896  ** type they need.
1897  */
1898  sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr);
1899  if (sp == NULL)
1900  return WRONG;
1901  for (i = 0; i < sp->typecnt; ++i)
1902  seen[i] = FALSE;
1903  nseen = 0;
1904  for (i = sp->timecnt - 1; i >= 0; --i)
1905  if (!seen[sp->types[i]]) {
1906  seen[sp->types[i]] = TRUE;
1907  types[nseen++] = sp->types[i];
1908  }
1909  for (sameind = 0; sameind < nseen; ++sameind) {
1910  samei = types[sameind];
1911  if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
1912  continue;
1913  for (otherind = 0; otherind < nseen; ++otherind) {
1914  otheri = types[otherind];
1915  if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
1916  continue;
1917  tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
1918  sp->ttis[samei].tt_gmtoff;
1919  tmp->tm_isdst = !tmp->tm_isdst;
1920  t = time2(tmp, funcp, offset, &okay);
1921  if (okay)
1922  return t;
1923  tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
1924  sp->ttis[samei].tt_gmtoff;
1925  tmp->tm_isdst = !tmp->tm_isdst;
1926  }
1927  }
1928  return WRONG;
1929 }
1930 
1931 time_t
1932 mktime(struct tm *const tmp)
1933 {
1934  tzset();
1935  return time1(tmp, localsub, 0L);
1936 }
1937 
1938 #ifdef STD_INSPIRED
1939 
1940 time_t
1941 timelocal(struct tm *const tmp)
1942 {
1943  if (tmp != NULL)
1944  tmp->tm_isdst = -1; /* in case it wasn't initialized */
1945  return mktime(tmp);
1946 }
1947 
1948 time_t
1949 timegm(struct tm *const tmp)
1950 {
1951  if (tmp != NULL)
1952  tmp->tm_isdst = 0;
1953  return time1(tmp, gmtsub, 0L);
1954 }
1955 
1956 time_t
1957 timeoff(struct tm *const tmp, const long offset)
1958 {
1959  if (tmp != NULL)
1960  tmp->tm_isdst = 0;
1961  return time1(tmp, gmtsub, offset);
1962 }
1963 
1964 #endif /* defined STD_INSPIRED */
1965 
1966 #ifdef CMUCS
1967 
1968 /*
1969 ** The following is supplied for compatibility with
1970 ** previous versions of the CMUCS runtime library.
1971 */
1972 
1973 long
1974 gtime(struct tm *const tmp)
1975 {
1976  const time_t t = mktime(tmp);
1977 
1978  if (t == WRONG)
1979  return -1;
1980  return t;
1981 }
1982 
1983 #endif /* defined CMUCS */
1984 
1985 /*
1986 ** XXX--is the below the right way to conditionalize??
1987 */
1988 
1989 #ifdef STD_INSPIRED
1990 
1991 /*
1992 ** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
1993 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
1994 ** is not the case if we are accounting for leap seconds.
1995 ** So, we provide the following conversion routines for use
1996 ** when exchanging timestamps with POSIX conforming systems.
1997 */
1998 
1999 static int_fast64_t
2000 leapcorr(time_t *timep)
2001 {
2002  register struct state * sp;
2003  register struct lsinfo * lp;
2004  register int i;
2005 
2006  sp = lclptr;
2007  i = sp->leapcnt;
2008  while (--i >= 0) {
2009  lp = &sp->lsis[i];
2010  if (*timep >= lp->ls_trans)
2011  return lp->ls_corr;
2012  }
2013  return 0;
2014 }
2015 
2016 time_t
2017 time2posix(time_t t)
2018 {
2019  tzset();
2020  return t - leapcorr(&t);
2021 }
2022 
2023 time_t
2024 posix2time(time_t t)
2025 {
2026  time_t x;
2027  time_t y;
2028 
2029  tzset();
2030  /*
2031  ** For a positive leap second hit, the result
2032  ** is not unique. For a negative leap second
2033  ** hit, the corresponding time doesn't exist,
2034  ** so we return an adjacent second.
2035  */
2036  x = t + leapcorr(&t);
2037  y = x - leapcorr(&x);
2038  if (y < t) {
2039  do {
2040  x++;
2041  y = x - leapcorr(&x);
2042  } while (y < t);
2043  if (t != y)
2044  return x - 1;
2045  } else if (y > t) {
2046  do {
2047  --x;
2048  y = x - leapcorr(&x);
2049  } while (y > t);
2050  if (t != y)
2051  return x + 1;
2052  }
2053  return x;
2054 }
2055 
2056 #endif /* defined STD_INSPIRED */
bp
Definition: action.c:1035
cp
Definition: action.c:1035
#define year
Definition: aptex-macros.h:808
#define name
#define reversed
char * asctime_r(register const struct tm *timeptr, char *buf)
Definition: asctime.c:72
char * asctime(register const struct tm *timeptr)
Definition: asctime.c:129
#define b
Definition: jpegint.h:372
#define ap
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
#define free(a)
Definition: decNumber.cpp:310
#define R_OK
Definition: defs.h:31
const char * delim
Definition: dvistuff.c:159
char * strncpy()
int strcmp()
Definition: coll.cpp:143
char * strcpy()
static void
Definition: fpif.c:118
#define tp
#define t
Definition: afcover.h:96
#define c(n)
Definition: gpos-common.c:150
#define a(n)
Definition: gpos-common.c:148
#define d(n)
Definition: gpos-common.c:151
int base
Definition: gsftopk.c:1502
#define strchr
Definition: gsftopk.c:59
#define TYPE_SIGNED(t)
Definition: intprops.h:41
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
for(n=0;n< outline->n_points;n++)
Definition: ftbbox.c:494
kerning y
Definition: ttdriver.c:212
int32_t int_fast32_t
Definition: stdint.h:106
#define INT_FAST32_MAX
Definition: stdint.h:165
#define INT_FAST32_MIN
Definition: stdint.h:164
int64_t int_fast64_t
Definition: stdint.h:107
char * getenv()
int errno
int num
Definition: disdvi.c:621
#define buf
#define INT_MIN
Definition: c-minmax.h:50
#define INT_MAX
Definition: c-minmax.h:53
#define access
Definition: win32lib.h:59
#define timezone
Definition: win32lib.h:99
#define read
Definition: win32lib.h:88
#define open
Definition: win32lib.h:86
#define close
Definition: win32lib.h:63
#define daylight
Definition: win32lib.h:65
#define malloc
Definition: alloca.c:91
long time_t
Definition: types.h:18
#define ATTRIBUTE_PURE
Definition: private.h:218
#define is_digit(c)
Definition: private.h:113
static time_t const time_t_min
Definition: private.h:329
#define SECSPERREPEAT
Definition: private.h:412
#define AVGSECSPERYEAR
Definition: private.h:408
#define GRANDPARENTED
Definition: private.h:18
#define INITIALIZE(x)
Definition: private.h:370
#define YEARSPERREPEAT
Definition: private.h:400
static time_t const time_t_max
Definition: private.h:333
#define SECSPERREPEAT_BITS
Definition: private.h:416
#define TYPE_BIT(type)
Definition: private.h:321
#define time_t
Definition: includes.h:70
static const int mon_lengths[2][12]
Definition: localtime.c:633
static int lcl_is_set
Definition: localtime.c:200
struct tm * localtime(const time_t *const timep)
Definition: localtime.c:1332
static int normalize_overflow(int *tensptr, int *unitsptr, int base)
Definition: localtime.c:1626
static time_t time2sub(struct tm *tmp, struct tm *(*funcp)(const time_t *, int_fast32_t, struct tm *), int_fast32_t offset, int *okayp, int do_norm_secs)
Definition: localtime.c:1667
static int_fast64_t detzcode64(const char *codep)
Definition: localtime.c:240
static struct tm tm
Definition: localtime.c:216
static struct state gmtmem
Definition: localtime.c:190
static char lcl_TZname[255+1]
Definition: localtime.c:199
#define lclptr
Definition: localtime.c:191
static time_t time2(struct tm *tmp, struct tm *(*funcp)(const time_t *, int_fast32_t, struct tm *), int_fast32_t offset, int *okayp)
Definition: localtime.c:1843
#define TZ_ABBR_ERR_CHAR
Definition: localtime.c:27
static const char * getoffset(const char *strp, int_fast32_t *offsetp)
#define WRONG
Definition: localtime.c:1574
time_t mktime(struct tm *const tmp)
Definition: localtime.c:1932
char * ctime_r(const time_t *const timep, char *buf)
Definition: localtime.c:1557
static int normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
Definition: localtime.c:1638
char * tzname[2]
Definition: localtime.c:203
struct tm * localtime_r(const time_t *const timep, struct tm *tmp)
Definition: localtime.c:1343
static void settzname(void)
Definition: localtime.c:252
#define TZ_STRLEN_MAX
Definition: localtime.c:196
static int differ_by_repeat(time_t t1, time_t t0)
Definition: localtime.c:316
#define DAY_OF_YEAR
Definition: localtime.c:126
static struct state lclmem
Definition: localtime.c:189
#define TZDEFRULESTRING
Definition: localtime.c:76
static const char * getrule(const char *strp, struct rule *rulep)
#define BIGGEST(a, b)
Definition: localtime.c:92
static const char * getzname(const char *strp)
void tzset(void)
Definition: localtime.c:1203
static void gmtload(struct state *sp)
Definition: localtime.c:1168
static int increment_overflow(int *number, int delta)
Definition: localtime.c:1582
#define JULIAN_DAY
Definition: localtime.c:125
static const char * getnum(const char *strp, int *nump, int min, int max)
#define WILDABBR
Definition: localtime.c:61
#define TZ_ABBR_CHAR_SET
Definition: localtime.c:22
static struct tm * localsub(const time_t *timep, int_fast32_t offset, struct tm *tmp)
Definition: localtime.c:1256
static time_t time1(struct tm *tmp, struct tm *(*funcp)(const time_t *, int_fast32_t, struct tm *), int_fast32_t offset)
Definition: localtime.c:1860
static int tmcomp(const struct tm *atmp, const struct tm *btmp)
static int increment_overflow32(int_fast32_t *number, int delta)
Definition: localtime.c:1599
#define MY_TZNAME_MAX
Definition: localtime.c:98
static void tzsetwall(void)
Definition: localtime.c:1182
static struct tm * gmtsub(const time_t *timep, int_fast32_t offset, struct tm *tmp)
Definition: localtime.c:1353
static int_fast32_t detzcode(const char *codep)
Definition: localtime.c:228
struct tm * gmtime_r(const time_t *const timep, struct tm *tmp)
Definition: localtime.c:1389
static const char gmt[]
Definition: localtime.c:66
static int leaps_thru_end_of(int y)
#define OPEN_MODE
Definition: localtime.c:38
#define MONTH_NTH_DAY_OF_WEEK
Definition: localtime.c:127
#define gmtptr
Definition: localtime.c:192
struct tm * gmtime(const time_t *const timep)
Definition: localtime.c:1379
static const char wildabbr[]
Definition: localtime.c:64
static int tzload(const char *name, struct state *sp, int doextend)
static int_fast32_t transtime(int year, const struct rule *rulep, int_fast32_t offset)
static const int year_lengths[2]
Definition: localtime.c:638
static int typesequiv(const struct state *sp, int a, int b)
Definition: localtime.c:612
static int increment_overflow_time(time_t *t, int_fast32_t delta)
Definition: localtime.c:1610
#define TZ_ABBR_MAX_LEN
Definition: localtime.c:18
static int gmt_is_set
Definition: localtime.c:201
static const char * getsecs(const char *strp, int_fast32_t *secsp)
static int tzparse(const char *name, struct state *sp, int lastditch)
static struct tm * timesub(const time_t *timep, int_fast32_t offset, const struct state *sp, struct tm *tmp)
char * ctime(const time_t *const timep)
Definition: localtime.c:1545
static const char * getqzname(const char *strp, const int delim)
static const UChar u_t
float x
Definition: cordic.py:15
union value value
Definition: obx.h:44
#define min(a, b)
Definition: pbmplus.h:223
#define max(a, b)
Definition: pbmto4425.c:11
static int delta
Definition: pbmtolj.c:36
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
#define t0
#define t1
static int offset
Definition: ppmtogif.c:642
#define dir
#define swap(sp)
Definition: interp.c:123
void oops(const char *message,...)
Definition: stackenv.c:90
#define int_fast32_t
Definition: stdint.in.h:291
int_fast64_t ls_corr
Definition: localtime.c:89
time_t ls_trans
Definition: localtime.c:88
Definition: rule.h:21
int r_mon
Definition: localtime.c:121
int r_day
Definition: localtime.c:119
int r_type
Definition: localtime.c:118
int_fast32_t r_time
Definition: localtime.c:122
int r_week
Definition: localtime.c:120
int goback
Definition: localtime.c:106
int timecnt
Definition: localtime.c:103
char chars[((((((50+1) >(sizeof gmt)) ?(50+1) :(sizeof gmt))) >((2 *(255+1)))) ?((((50+1) >(sizeof gmt)) ?(50+1) :(sizeof gmt))) :((2 *(255+1))))]
Definition: localtime.c:112
int charcnt
Definition: localtime.c:105
int typecnt
Definition: localtime.c:104
int leapcnt
Definition: localtime.c:102
struct lsinfo lsis[50]
Definition: localtime.c:113
int goahead
Definition: localtime.c:107
int defaulttype
Definition: localtime.c:114
struct ttinfo ttis[256]
Definition: localtime.c:110
time_t ats[2000]
Definition: localtime.c:108
unsigned char types[2000]
Definition: localtime.c:109
Definition: dvips.h:235
int tt_abbrind
Definition: localtime.c:82
int tt_ttisstd
Definition: localtime.c:83
int tt_isdst
Definition: localtime.c:81
int tt_ttisgmt
Definition: localtime.c:84
int_fast32_t tt_gmtoff
Definition: localtime.c:80
Definition: object.c:319
Definition: tzfile.h:40
struct def_label label[1024]
Definition: t1part.c:286
int j
Definition: t4ht.c:1589
while(temp)
Definition: t4ht.c:858
*job_name strlen((char *) job_name) - 4)
up
Definition: tex4ht.c:2558
m
Definition: tex4ht.c:3990
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
#define sp
Definition: stack.c:11
#define ip
Definition: stack.c:14
#define timegm
Definition: time.c:131
unsigned int * lp
Definition: ttf.c:84
#define SECSPERDAY
Definition: tzfile.h:124
#define TM_YEAR_BASE
Definition: tzfile.h:148
#define SECSPERHOUR
Definition: tzfile.h:123
#define DAYSPERNYEAR
Definition: tzfile.h:121
#define SECSPERMIN
Definition: tzfile.h:117
#define EPOCH_WDAY
Definition: tzfile.h:151
#define MONSPERYEAR
Definition: tzfile.h:125
#define TZ_MAX_CHARS
Definition: tzfile.h:109
#define HOURSPERDAY
Definition: tzfile.h:119
#define isleap(y)
Definition: tzfile.h:153
#define DAYSPERWEEK
Definition: tzfile.h:120
#define EPOCH_YEAR
Definition: tzfile.h:150
#define TZ_MAX_TYPES
Definition: tzfile.h:105
#define TZDIR
Definition: tzfile.h:23
#define TZDEFRULES
Definition: tzfile.h:31
#define MINSPERHOUR
Definition: tzfile.h:118
#define TZ_MAX_TIMES
Definition: tzfile.h:100
#define DAYSPERLYEAR
Definition: tzfile.h:122
#define TZ_MAX_LEAPS
Definition: tzfile.h:114
#define TZDEFAULT
Definition: tzfile.h:27
@ L
Definition: ubidiimp.h:45
Definition: obx.h:51
@ start
Definition: preamble.c:52
#define seconds
Definition: utmscale.cpp:19
#define end(cp)
Definition: zic.c:71
static zic_t corr[50]
Definition: zic.c:413
static int timecnt
Definition: zic.c:202