e703cd29ebe81a1055fdc93490568a520f0612d3
[debian/tar] / gnu / mktime.c
1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* Convert a 'struct tm' to a time_t value.
4    Copyright (C) 1993-2013 Free Software Foundation, Inc.
5    This file is part of the GNU C Library.
6    Contributed by Paul Eggert <eggert@twinsun.com>.
7
8    The GNU C Library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public
10    License as published by the Free Software Foundation; either
11    version 3 of the License, or (at your option) any later version.
12
13    The GNU C Library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public
19    License along with the GNU C Library; if not, see
20    <http://www.gnu.org/licenses/>.  */
21
22 /* Define this to have a standalone program to test this implementation of
23    mktime.  */
24 /* #define DEBUG 1 */
25
26 #ifndef _LIBC
27 # include <config.h>
28 #endif
29
30 /* Assume that leap seconds are possible, unless told otherwise.
31    If the host has a 'zic' command with a '-L leapsecondfilename' option,
32    then it supports leap seconds; otherwise it probably doesn't.  */
33 #ifndef LEAP_SECONDS_POSSIBLE
34 # define LEAP_SECONDS_POSSIBLE 1
35 #endif
36
37 #include <time.h>
38
39 #include <limits.h>
40
41 #include <string.h>             /* For the real memcpy prototype.  */
42
43 #if DEBUG
44 # include <stdio.h>
45 # include <stdlib.h>
46 /* Make it work even if the system's libc has its own mktime routine.  */
47 # undef mktime
48 # define mktime my_mktime
49 #endif /* DEBUG */
50
51 /* Some of the code in this file assumes that signed integer overflow
52    silently wraps around.  This assumption can't easily be programmed
53    around, nor can it be checked for portably at compile-time or
54    easily eliminated at run-time.
55
56    Define WRAPV to 1 if the assumption is valid and if
57      #pragma GCC optimize ("wrapv")
58    does not trigger GCC bug 51793
59    <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51793>.
60    Otherwise, define it to 0; this forces the use of slower code that,
61    while not guaranteed by the C Standard, works on all production
62    platforms that we know about.  */
63 #ifndef WRAPV
64 # if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \
65       && defined __GLIBC__)
66 #  pragma GCC optimize ("wrapv")
67 #  define WRAPV 1
68 # else
69 #  define WRAPV 0
70 # endif
71 #endif
72
73 /* Verify a requirement at compile-time (unlike assert, which is runtime).  */
74 #define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
75
76 /* A signed type that is at least one bit wider than int.  */
77 #if INT_MAX <= LONG_MAX / 2
78 typedef long int long_int;
79 #else
80 typedef long long int long_int;
81 #endif
82 verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2);
83
84 /* Shift A right by B bits portably, by dividing A by 2**B and
85    truncating towards minus infinity.  A and B should be free of side
86    effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
87    INT_BITS is the number of useful bits in an int.  GNU code can
88    assume that INT_BITS is at least 32.
89
90    ISO C99 says that A >> B is implementation-defined if A < 0.  Some
91    implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
92    right in the usual way when A < 0, so SHR falls back on division if
93    ordinary A >> B doesn't seem to be the usual signed shift.  */
94 #define SHR(a, b)                                               \
95   ((-1 >> 1 == -1                                               \
96     && (long_int) -1 >> 1 == -1                                 \
97     && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t)))      \
98    ? (a) >> (b)                                                 \
99    : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
100
101 /* The extra casts in the following macros work around compiler bugs,
102    e.g., in Cray C 5.0.3.0.  */
103
104 /* True if the arithmetic type T is an integer type.  bool counts as
105    an integer.  */
106 #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
107
108 /* True if negative values of the signed integer type T use two's
109    complement, or if T is an unsigned integer type.  */
110 #define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
111
112 /* True if the arithmetic type T is signed.  */
113 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
114
115 /* The maximum and minimum values for the integer type T.  These
116    macros have undefined behavior if T is signed and has padding bits.
117    If this is a problem for you, please let us know how to fix it for
118    your host.  */
119 #define TYPE_MINIMUM(t) \
120   ((t) (! TYPE_SIGNED (t) \
121         ? (t) 0 \
122         : ~ TYPE_MAXIMUM (t)))
123 #define TYPE_MAXIMUM(t) \
124   ((t) (! TYPE_SIGNED (t) \
125         ? (t) -1 \
126         : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
127
128 #ifndef TIME_T_MIN
129 # define TIME_T_MIN TYPE_MINIMUM (time_t)
130 #endif
131 #ifndef TIME_T_MAX
132 # define TIME_T_MAX TYPE_MAXIMUM (time_t)
133 #endif
134 #define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
135
136 verify (time_t_is_integer, TYPE_IS_INTEGER (time_t));
137 verify (twos_complement_arithmetic,
138         (TYPE_TWOS_COMPLEMENT (int)
139          && TYPE_TWOS_COMPLEMENT (long_int)
140          && TYPE_TWOS_COMPLEMENT (time_t)));
141
142 #define EPOCH_YEAR 1970
143 #define TM_YEAR_BASE 1900
144 verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
145
146 /* Return 1 if YEAR + TM_YEAR_BASE is a leap year.  */
147 static int
148 leapyear (long_int year)
149 {
150   /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
151      Also, work even if YEAR is negative.  */
152   return
153     ((year & 3) == 0
154      && (year % 100 != 0
155          || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
156 }
157
158 /* How many days come before each month (0-12).  */
159 #ifndef _LIBC
160 static
161 #endif
162 const unsigned short int __mon_yday[2][13] =
163   {
164     /* Normal years.  */
165     { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
166     /* Leap years.  */
167     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
168   };
169
170
171 #ifndef _LIBC
172 /* Portable standalone applications should supply a <time.h> that
173    declares a POSIX-compliant localtime_r, for the benefit of older
174    implementations that lack localtime_r or have a nonstandard one.
175    See the gnulib time_r module for one way to implement this.  */
176 # undef __localtime_r
177 # define __localtime_r localtime_r
178 # define __mktime_internal mktime_internal
179 # include "mktime-internal.h"
180 #endif
181
182 /* Return 1 if the values A and B differ according to the rules for
183    tm_isdst: A and B differ if one is zero and the other positive.  */
184 static int
185 isdst_differ (int a, int b)
186 {
187   return (!a != !b) && (0 <= a) && (0 <= b);
188 }
189
190 /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
191    (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
192    were not adjusted between the time stamps.
193
194    The YEAR values uses the same numbering as TP->tm_year.  Values
195    need not be in the usual range.  However, YEAR1 must not be less
196    than 2 * INT_MIN or greater than 2 * INT_MAX.
197
198    The result may overflow.  It is the caller's responsibility to
199    detect overflow.  */
200
201 static time_t
202 ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
203             int year0, int yday0, int hour0, int min0, int sec0)
204 {
205   verify (C99_integer_division, -1 / 2 == 0);
206
207   /* Compute intervening leap days correctly even if year is negative.
208      Take care to avoid integer overflow here.  */
209   int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3);
210   int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3);
211   int a100 = a4 / 25 - (a4 % 25 < 0);
212   int b100 = b4 / 25 - (b4 % 25 < 0);
213   int a400 = SHR (a100, 2);
214   int b400 = SHR (b100, 2);
215   int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
216
217   /* Compute the desired time in time_t precision.  Overflow might
218      occur here.  */
219   time_t tyear1 = year1;
220   time_t years = tyear1 - year0;
221   time_t days = 365 * years + yday1 - yday0 + intervening_leap_days;
222   time_t hours = 24 * days + hour1 - hour0;
223   time_t minutes = 60 * hours + min1 - min0;
224   time_t seconds = 60 * minutes + sec1 - sec0;
225   return seconds;
226 }
227
228 /* Return the average of A and B, even if A + B would overflow.  */
229 static time_t
230 time_t_avg (time_t a, time_t b)
231 {
232   return SHR (a, 1) + SHR (b, 1) + (a & b & 1);
233 }
234
235 /* Return 1 if A + B does not overflow.  If time_t is unsigned and if
236    B's top bit is set, assume that the sum represents A - -B, and
237    return 1 if the subtraction does not wrap around.  */
238 static int
239 time_t_add_ok (time_t a, time_t b)
240 {
241   if (! TYPE_SIGNED (time_t))
242     {
243       time_t sum = a + b;
244       return (sum < a) == (TIME_T_MIDPOINT <= b);
245     }
246   else if (WRAPV)
247     {
248       time_t sum = a + b;
249       return (sum < a) == (b < 0);
250     }
251   else
252     {
253       time_t avg = time_t_avg (a, b);
254       return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
255     }
256 }
257
258 /* Return 1 if A + B does not overflow.  */
259 static int
260 time_t_int_add_ok (time_t a, int b)
261 {
262   verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX);
263   if (WRAPV)
264     {
265       time_t sum = a + b;
266       return (sum < a) == (b < 0);
267     }
268   else
269     {
270       int a_odd = a & 1;
271       time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b));
272       return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
273     }
274 }
275
276 /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
277    assuming that *T corresponds to *TP and that no clock adjustments
278    occurred between *TP and the desired time.
279    If TP is null, return a value not equal to *T; this avoids false matches.
280    If overflow occurs, yield the minimal or maximal value, except do not
281    yield a value equal to *T.  */
282 static time_t
283 guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
284                const time_t *t, const struct tm *tp)
285 {
286   if (tp)
287     {
288       time_t d = ydhms_diff (year, yday, hour, min, sec,
289                              tp->tm_year, tp->tm_yday,
290                              tp->tm_hour, tp->tm_min, tp->tm_sec);
291       if (time_t_add_ok (*t, d))
292         return *t + d;
293     }
294
295   /* Overflow occurred one way or another.  Return the nearest result
296      that is actually in range, except don't report a zero difference
297      if the actual difference is nonzero, as that would cause a false
298      match; and don't oscillate between two values, as that would
299      confuse the spring-forward gap detector.  */
300   return (*t < TIME_T_MIDPOINT
301           ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN)
302           : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX));
303 }
304
305 /* Use CONVERT to convert *T to a broken down time in *TP.
306    If *T is out of range for conversion, adjust it so that
307    it is the nearest in-range value and then convert that.  */
308 static struct tm *
309 ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
310                 time_t *t, struct tm *tp)
311 {
312   struct tm *r = convert (t, tp);
313
314   if (!r && *t)
315     {
316       time_t bad = *t;
317       time_t ok = 0;
318
319       /* BAD is a known unconvertible time_t, and OK is a known good one.
320          Use binary search to narrow the range between BAD and OK until
321          they differ by 1.  */
322       while (bad != ok + (bad < 0 ? -1 : 1))
323         {
324           time_t mid = *t = time_t_avg (ok, bad);
325           r = convert (t, tp);
326           if (r)
327             ok = mid;
328           else
329             bad = mid;
330         }
331
332       if (!r && ok)
333         {
334           /* The last conversion attempt failed;
335              revert to the most recent successful attempt.  */
336           *t = ok;
337           r = convert (t, tp);
338         }
339     }
340
341   return r;
342 }
343
344
345 /* Convert *TP to a time_t value, inverting
346    the monotonic and mostly-unit-linear conversion function CONVERT.
347    Use *OFFSET to keep track of a guess at the offset of the result,
348    compared to what the result would be for UTC without leap seconds.
349    If *OFFSET's guess is correct, only one CONVERT call is needed.
350    This function is external because it is used also by timegm.c.  */
351 time_t
352 __mktime_internal (struct tm *tp,
353                    struct tm *(*convert) (const time_t *, struct tm *),
354                    time_t *offset)
355 {
356   time_t t, gt, t0, t1, t2;
357   struct tm tm;
358
359   /* The maximum number of probes (calls to CONVERT) should be enough
360      to handle any combinations of time zone rule changes, solar time,
361      leap seconds, and oscillations around a spring-forward gap.
362      POSIX.1 prohibits leap seconds, but some hosts have them anyway.  */
363   int remaining_probes = 6;
364
365   /* Time requested.  Copy it in case CONVERT modifies *TP; this can
366      occur if TP is localtime's returned value and CONVERT is localtime.  */
367   int sec = tp->tm_sec;
368   int min = tp->tm_min;
369   int hour = tp->tm_hour;
370   int mday = tp->tm_mday;
371   int mon = tp->tm_mon;
372   int year_requested = tp->tm_year;
373   int isdst = tp->tm_isdst;
374
375   /* 1 if the previous probe was DST.  */
376   int dst2;
377
378   /* Ensure that mon is in range, and set year accordingly.  */
379   int mon_remainder = mon % 12;
380   int negative_mon_remainder = mon_remainder < 0;
381   int mon_years = mon / 12 - negative_mon_remainder;
382   long_int lyear_requested = year_requested;
383   long_int year = lyear_requested + mon_years;
384
385   /* The other values need not be in range:
386      the remaining code handles minor overflows correctly,
387      assuming int and time_t arithmetic wraps around.
388      Major overflows are caught at the end.  */
389
390   /* Calculate day of year from year, month, and day of month.
391      The result need not be in range.  */
392   int mon_yday = ((__mon_yday[leapyear (year)]
393                    [mon_remainder + 12 * negative_mon_remainder])
394                   - 1);
395   long_int lmday = mday;
396   long_int yday = mon_yday + lmday;
397
398   time_t guessed_offset = *offset;
399
400   int sec_requested = sec;
401
402   if (LEAP_SECONDS_POSSIBLE)
403     {
404       /* Handle out-of-range seconds specially,
405          since ydhms_tm_diff assumes every minute has 60 seconds.  */
406       if (sec < 0)
407         sec = 0;
408       if (59 < sec)
409         sec = 59;
410     }
411
412   /* Invert CONVERT by probing.  First assume the same offset as last
413      time.  */
414
415   t0 = ydhms_diff (year, yday, hour, min, sec,
416                    EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset);
417
418   if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
419     {
420       /* time_t isn't large enough to rule out overflows, so check
421          for major overflows.  A gross check suffices, since if t0
422          has overflowed, it is off by a multiple of TIME_T_MAX -
423          TIME_T_MIN + 1.  So ignore any component of the difference
424          that is bounded by a small value.  */
425
426       /* Approximate log base 2 of the number of time units per
427          biennium.  A biennium is 2 years; use this unit instead of
428          years to avoid integer overflow.  For example, 2 average
429          Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds,
430          which is 63113904 seconds, and rint (log2 (63113904)) is
431          26.  */
432       int ALOG2_SECONDS_PER_BIENNIUM = 26;
433       int ALOG2_MINUTES_PER_BIENNIUM = 20;
434       int ALOG2_HOURS_PER_BIENNIUM = 14;
435       int ALOG2_DAYS_PER_BIENNIUM = 10;
436       int LOG2_YEARS_PER_BIENNIUM = 1;
437
438       int approx_requested_biennia =
439         (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
440          - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
441          + SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
442          + SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
443          + SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
444          + (LEAP_SECONDS_POSSIBLE
445             ? 0
446             : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
447
448       int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
449       int diff = approx_biennia - approx_requested_biennia;
450       int approx_abs_diff = diff < 0 ? -1 - diff : diff;
451
452       /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
453          gives a positive value of 715827882.  Setting a variable
454          first then doing math on it seems to work.
455          (ghazi@caip.rutgers.edu) */
456       time_t time_t_max = TIME_T_MAX;
457       time_t time_t_min = TIME_T_MIN;
458       time_t overflow_threshold =
459         (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
460
461       if (overflow_threshold < approx_abs_diff)
462         {
463           /* Overflow occurred.  Try repairing it; this might work if
464              the time zone offset is enough to undo the overflow.  */
465           time_t repaired_t0 = -1 - t0;
466           approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
467           diff = approx_biennia - approx_requested_biennia;
468           approx_abs_diff = diff < 0 ? -1 - diff : diff;
469           if (overflow_threshold < approx_abs_diff)
470             return -1;
471           guessed_offset += repaired_t0 - t0;
472           t0 = repaired_t0;
473         }
474     }
475
476   /* Repeatedly use the error to improve the guess.  */
477
478   for (t = t1 = t2 = t0, dst2 = 0;
479        (gt = guess_time_tm (year, yday, hour, min, sec, &t,
480                             ranged_convert (convert, &t, &tm)),
481         t != gt);
482        t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0)
483     if (t == t1 && t != t2
484         && (tm.tm_isdst < 0
485             || (isdst < 0
486                 ? dst2 <= (tm.tm_isdst != 0)
487                 : (isdst != 0) != (tm.tm_isdst != 0))))
488       /* We can't possibly find a match, as we are oscillating
489          between two values.  The requested time probably falls
490          within a spring-forward gap of size GT - T.  Follow the common
491          practice in this case, which is to return a time that is GT - T
492          away from the requested time, preferring a time whose
493          tm_isdst differs from the requested value.  (If no tm_isdst
494          was requested and only one of the two values has a nonzero
495          tm_isdst, prefer that value.)  In practice, this is more
496          useful than returning -1.  */
497       goto offset_found;
498     else if (--remaining_probes == 0)
499       return -1;
500
501   /* We have a match.  Check whether tm.tm_isdst has the requested
502      value, if any.  */
503   if (isdst_differ (isdst, tm.tm_isdst))
504     {
505       /* tm.tm_isdst has the wrong value.  Look for a neighboring
506          time with the right value, and use its UTC offset.
507
508          Heuristic: probe the adjacent timestamps in both directions,
509          looking for the desired isdst.  This should work for all real
510          time zone histories in the tz database.  */
511
512       /* Distance between probes when looking for a DST boundary.  In
513          tzdata2003a, the shortest period of DST is 601200 seconds
514          (e.g., America/Recife starting 2000-10-08 01:00), and the
515          shortest period of non-DST surrounded by DST is 694800
516          seconds (Africa/Tunis starting 1943-04-17 01:00).  Use the
517          minimum of these two values, so we don't miss these short
518          periods when probing.  */
519       int stride = 601200;
520
521       /* The longest period of DST in tzdata2003a is 536454000 seconds
522          (e.g., America/Jujuy starting 1946-10-01 01:00).  The longest
523          period of non-DST is much longer, but it makes no real sense
524          to search for more than a year of non-DST, so use the DST
525          max.  */
526       int duration_max = 536454000;
527
528       /* Search in both directions, so the maximum distance is half
529          the duration; add the stride to avoid off-by-1 problems.  */
530       int delta_bound = duration_max / 2 + stride;
531
532       int delta, direction;
533
534       for (delta = stride; delta < delta_bound; delta += stride)
535         for (direction = -1; direction <= 1; direction += 2)
536           if (time_t_int_add_ok (t, delta * direction))
537             {
538               time_t ot = t + delta * direction;
539               struct tm otm;
540               ranged_convert (convert, &ot, &otm);
541               if (! isdst_differ (isdst, otm.tm_isdst))
542                 {
543                   /* We found the desired tm_isdst.
544                      Extrapolate back to the desired time.  */
545                   t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
546                   ranged_convert (convert, &t, &tm);
547                   goto offset_found;
548                 }
549             }
550     }
551
552  offset_found:
553   *offset = guessed_offset + t - t0;
554
555   if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec)
556     {
557       /* Adjust time to reflect the tm_sec requested, not the normalized value.
558          Also, repair any damage from a false match due to a leap second.  */
559       int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec;
560       if (! time_t_int_add_ok (t, sec_requested))
561         return -1;
562       t1 = t + sec_requested;
563       if (! time_t_int_add_ok (t1, sec_adjustment))
564         return -1;
565       t2 = t1 + sec_adjustment;
566       if (! convert (&t2, &tm))
567         return -1;
568       t = t2;
569     }
570
571   *tp = tm;
572   return t;
573 }
574
575
576 /* FIXME: This should use a signed type wide enough to hold any UTC
577    offset in seconds.  'int' should be good enough for GNU code.  We
578    can't fix this unilaterally though, as other modules invoke
579    __mktime_internal.  */
580 static time_t localtime_offset;
581
582 /* Convert *TP to a time_t value.  */
583 time_t
584 mktime (struct tm *tp)
585 {
586 #ifdef _LIBC
587   /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
588      time zone names contained in the external variable 'tzname' shall
589      be set as if the tzset() function had been called.  */
590   __tzset ();
591 #endif
592
593   return __mktime_internal (tp, __localtime_r, &localtime_offset);
594 }
595
596 #ifdef weak_alias
597 weak_alias (mktime, timelocal)
598 #endif
599
600 #ifdef _LIBC
601 libc_hidden_def (mktime)
602 libc_hidden_weak (timelocal)
603 #endif
604 \f
605 #if DEBUG
606
607 static int
608 not_equal_tm (const struct tm *a, const struct tm *b)
609 {
610   return ((a->tm_sec ^ b->tm_sec)
611           | (a->tm_min ^ b->tm_min)
612           | (a->tm_hour ^ b->tm_hour)
613           | (a->tm_mday ^ b->tm_mday)
614           | (a->tm_mon ^ b->tm_mon)
615           | (a->tm_year ^ b->tm_year)
616           | (a->tm_yday ^ b->tm_yday)
617           | isdst_differ (a->tm_isdst, b->tm_isdst));
618 }
619
620 static void
621 print_tm (const struct tm *tp)
622 {
623   if (tp)
624     printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
625             tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
626             tp->tm_hour, tp->tm_min, tp->tm_sec,
627             tp->tm_yday, tp->tm_wday, tp->tm_isdst);
628   else
629     printf ("0");
630 }
631
632 static int
633 check_result (time_t tk, struct tm tmk, time_t tl, const struct tm *lt)
634 {
635   if (tk != tl || !lt || not_equal_tm (&tmk, lt))
636     {
637       printf ("mktime (");
638       print_tm (lt);
639       printf (")\nyields (");
640       print_tm (&tmk);
641       printf (") == %ld, should be %ld\n", (long int) tk, (long int) tl);
642       return 1;
643     }
644
645   return 0;
646 }
647
648 int
649 main (int argc, char **argv)
650 {
651   int status = 0;
652   struct tm tm, tmk, tml;
653   struct tm *lt;
654   time_t tk, tl, tl1;
655   char trailer;
656
657   if ((argc == 3 || argc == 4)
658       && (sscanf (argv[1], "%d-%d-%d%c",
659                   &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
660           == 3)
661       && (sscanf (argv[2], "%d:%d:%d%c",
662                   &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
663           == 3))
664     {
665       tm.tm_year -= TM_YEAR_BASE;
666       tm.tm_mon--;
667       tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
668       tmk = tm;
669       tl = mktime (&tmk);
670       lt = localtime (&tl);
671       if (lt)
672         {
673           tml = *lt;
674           lt = &tml;
675         }
676       printf ("mktime returns %ld == ", (long int) tl);
677       print_tm (&tmk);
678       printf ("\n");
679       status = check_result (tl, tmk, tl, lt);
680     }
681   else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
682     {
683       time_t from = atol (argv[1]);
684       time_t by = atol (argv[2]);
685       time_t to = atol (argv[3]);
686
687       if (argc == 4)
688         for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
689           {
690             lt = localtime (&tl);
691             if (lt)
692               {
693                 tmk = tml = *lt;
694                 tk = mktime (&tmk);
695                 status |= check_result (tk, tmk, tl, &tml);
696               }
697             else
698               {
699                 printf ("localtime (%ld) yields 0\n", (long int) tl);
700                 status = 1;
701               }
702             tl1 = tl + by;
703             if ((tl1 < tl) != (by < 0))
704               break;
705           }
706       else
707         for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
708           {
709             /* Null benchmark.  */
710             lt = localtime (&tl);
711             if (lt)
712               {
713                 tmk = tml = *lt;
714                 tk = tl;
715                 status |= check_result (tk, tmk, tl, &tml);
716               }
717             else
718               {
719                 printf ("localtime (%ld) yields 0\n", (long int) tl);
720                 status = 1;
721               }
722             tl1 = tl + by;
723             if ((tl1 < tl) != (by < 0))
724               break;
725           }
726     }
727   else
728     printf ("Usage:\
729 \t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
730 \t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
731 \t%s FROM BY TO - # Do not test those values (for benchmark).\n",
732             argv[0], argv[0], argv[0]);
733
734   return status;
735 }
736
737 #endif /* DEBUG */
738 \f
739 /*
740 Local Variables:
741 compile-command: "gcc -DDEBUG -I. -Wall -W -O2 -g mktime.c -o mktime"
742 End:
743 */