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