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