~ubuntu-branches/ubuntu/utopic/coreutils/utopic-proposed

« back to all changes in this revision

Viewing changes to lib/mktime.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2012-11-28 03:03:42 UTC
  • mfrom: (8.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20121128030342-21zanj8354gas5gr
Tags: 8.20-3ubuntu1
* Resynchronise with Debian.  Remaining changes:
  - Make 'uname -i -p' return the real processor/hardware, instead of
    unknown.
  - Build-depend on gettext:any instead of on gettext, so that apt-get can
    properly resolve build-dependencies on the tool when cross-building.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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-1999, 2002-2007, 2009-2011 Free Software Foundation, Inc.
 
1
/* Convert a 'struct tm' to a time_t value.
 
2
   Copyright (C) 1993-2012 Free Software Foundation, Inc.
5
3
   This file is part of the GNU C Library.
6
4
   Contributed by Paul Eggert <eggert@twinsun.com>.
7
5
 
8
 
   This program is free software; you can redistribute it and/or modify
9
 
   it under the terms of the GNU General Public License as published by
10
 
   the Free Software Foundation; either version 3, or (at your option)
11
 
   any later version.
 
6
   The GNU C Library is free software; you can redistribute it and/or
 
7
   modify it under the terms of the GNU General Public
 
8
   License as published by the Free Software Foundation; either
 
9
   version 3 of the License, or (at your option) any later version.
12
10
 
13
 
   This program is distributed in the hope that it will be useful,
 
11
   The GNU C Library is distributed in the hope that it will be useful,
14
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
   GNU General Public License for more details.
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
   General Public License for more details.
17
15
 
18
 
   You should have received a copy of the GNU General Public License along
19
 
   with this program; if not, write to the Free Software Foundation,
20
 
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
 
16
   You should have received a copy of the GNU General Public
 
17
   License along with the GNU C Library; if not, see
 
18
   <http://www.gnu.org/licenses/>.  */
21
19
 
22
20
/* Define this to have a standalone program to test this implementation of
23
21
   mktime.  */
27
25
# include <config.h>
28
26
#endif
29
27
 
30
 
/* Some of the code in this file assumes that signed integer overflow
31
 
   silently wraps around.  This assumption can't easily be programmed
32
 
   around, nor can it be checked for portably at compile-time or
33
 
   easily eliminated at run-time.
34
 
 
35
 
   Define WRAPV to 1 if the assumption is valid.  Otherwise, define it
36
 
   to 0; this forces the use of slower code that, while not guaranteed
37
 
   by the C Standard, works on all production platforms that we know
38
 
   about.  */
39
 
#ifndef WRAPV
40
 
# if (__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__
41
 
#  pragma GCC optimize ("wrapv")
42
 
#  define WRAPV 1
43
 
# else
44
 
#  define WRAPV 0
45
 
# endif
46
 
#endif
47
 
 
48
28
/* Assume that leap seconds are possible, unless told otherwise.
49
 
   If the host has a `zic' command with a `-L leapsecondfilename' option,
 
29
   If the host has a 'zic' command with a '-L leapsecondfilename' option,
50
30
   then it supports leap seconds; otherwise it probably doesn't.  */
51
31
#ifndef LEAP_SECONDS_POSSIBLE
52
32
# define LEAP_SECONDS_POSSIBLE 1
56
36
 
57
37
#include <limits.h>
58
38
 
59
 
#include <string.h>             /* For the real memcpy prototype.  */
 
39
#include <string.h>             /* For the real memcpy prototype.  */
60
40
 
61
41
#if DEBUG
62
42
# include <stdio.h>
66
46
# define mktime my_mktime
67
47
#endif /* DEBUG */
68
48
 
 
49
/* Some of the code in this file assumes that signed integer overflow
 
50
   silently wraps around.  This assumption can't easily be programmed
 
51
   around, nor can it be checked for portably at compile-time or
 
52
   easily eliminated at run-time.
 
53
 
 
54
   Define WRAPV to 1 if the assumption is valid and if
 
55
     #pragma GCC optimize ("wrapv")
 
56
   does not trigger GCC bug 51793
 
57
   <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51793>.
 
58
   Otherwise, define it to 0; this forces the use of slower code that,
 
59
   while not guaranteed by the C Standard, works on all production
 
60
   platforms that we know about.  */
 
61
#ifndef WRAPV
 
62
# if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \
 
63
      && defined __GLIBC__)
 
64
#  pragma GCC optimize ("wrapv")
 
65
#  define WRAPV 1
 
66
# else
 
67
#  define WRAPV 0
 
68
# endif
 
69
#endif
 
70
 
69
71
/* Verify a requirement at compile-time (unlike assert, which is runtime).  */
70
72
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
71
73
 
114
116
   your host.  */
115
117
#define TYPE_MINIMUM(t) \
116
118
  ((t) (! TYPE_SIGNED (t) \
117
 
        ? (t) 0 \
118
 
        : ~ TYPE_MAXIMUM (t)))
 
119
        ? (t) 0 \
 
120
        : ~ TYPE_MAXIMUM (t)))
119
121
#define TYPE_MAXIMUM(t) \
120
122
  ((t) (! TYPE_SIGNED (t) \
121
 
        ? (t) -1 \
122
 
        : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
 
123
        ? (t) -1 \
 
124
        : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
123
125
 
124
126
#ifndef TIME_T_MIN
125
127
# define TIME_T_MIN TYPE_MINIMUM (time_t)
131
133
 
132
134
verify (time_t_is_integer, TYPE_IS_INTEGER (time_t));
133
135
verify (twos_complement_arithmetic,
134
 
        (TYPE_TWOS_COMPLEMENT (int)
135
 
         && TYPE_TWOS_COMPLEMENT (long_int)
136
 
         && TYPE_TWOS_COMPLEMENT (time_t)));
 
136
        (TYPE_TWOS_COMPLEMENT (int)
 
137
         && TYPE_TWOS_COMPLEMENT (long_int)
 
138
         && TYPE_TWOS_COMPLEMENT (time_t)));
137
139
 
138
140
#define EPOCH_YEAR 1970
139
141
#define TM_YEAR_BASE 1900
140
142
verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
141
143
 
142
144
/* Return 1 if YEAR + TM_YEAR_BASE is a leap year.  */
143
 
static inline int
 
145
static int
144
146
leapyear (long_int year)
145
147
{
146
148
  /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
148
150
  return
149
151
    ((year & 3) == 0
150
152
     && (year % 100 != 0
151
 
         || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
 
153
         || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
152
154
}
153
155
 
154
156
/* How many days come before each month (0-12).  */
180
182
static int
181
183
isdst_differ (int a, int b)
182
184
{
183
 
  return (!a != !b) & (0 <= a) & (0 <= b);
 
185
  return (!a != !b) && (0 <= a) && (0 <= b);
184
186
}
185
187
 
186
188
/* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
194
196
   The result may overflow.  It is the caller's responsibility to
195
197
   detect overflow.  */
196
198
 
197
 
static inline time_t
 
199
static time_t
198
200
ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
199
 
            int year0, int yday0, int hour0, int min0, int sec0)
 
201
            int year0, int yday0, int hour0, int min0, int sec0)
200
202
{
201
203
  verify (C99_integer_division, -1 / 2 == 0);
202
204
 
277
279
   yield a value equal to *T.  */
278
280
static time_t
279
281
guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
280
 
               const time_t *t, const struct tm *tp)
 
282
               const time_t *t, const struct tm *tp)
281
283
{
282
284
  if (tp)
283
285
    {
284
286
      time_t d = ydhms_diff (year, yday, hour, min, sec,
285
 
                             tp->tm_year, tp->tm_yday,
286
 
                             tp->tm_hour, tp->tm_min, tp->tm_sec);
 
287
                             tp->tm_year, tp->tm_yday,
 
288
                             tp->tm_hour, tp->tm_min, tp->tm_sec);
287
289
      if (time_t_add_ok (*t, d))
288
 
        return *t + d;
 
290
        return *t + d;
289
291
    }
290
292
 
291
293
  /* Overflow occurred one way or another.  Return the nearest result
294
296
     match; and don't oscillate between two values, as that would
295
297
     confuse the spring-forward gap detector.  */
296
298
  return (*t < TIME_T_MIDPOINT
297
 
          ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN)
298
 
          : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX));
 
299
          ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN)
 
300
          : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX));
299
301
}
300
302
 
301
303
/* Use CONVERT to convert *T to a broken down time in *TP.
303
305
   it is the nearest in-range value and then convert that.  */
304
306
static struct tm *
305
307
ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
306
 
                time_t *t, struct tm *tp)
 
308
                time_t *t, struct tm *tp)
307
309
{
308
310
  struct tm *r = convert (t, tp);
309
311
 
313
315
      time_t ok = 0;
314
316
 
315
317
      /* BAD is a known unconvertible time_t, and OK is a known good one.
316
 
         Use binary search to narrow the range between BAD and OK until
317
 
         they differ by 1.  */
 
318
         Use binary search to narrow the range between BAD and OK until
 
319
         they differ by 1.  */
318
320
      while (bad != ok + (bad < 0 ? -1 : 1))
319
 
        {
320
 
          time_t mid = *t = time_t_avg (ok, bad);
321
 
          r = convert (t, tp);
322
 
          if (r)
323
 
            ok = mid;
324
 
          else
325
 
            bad = mid;
326
 
        }
 
321
        {
 
322
          time_t mid = *t = time_t_avg (ok, bad);
 
323
          r = convert (t, tp);
 
324
          if (r)
 
325
            ok = mid;
 
326
          else
 
327
            bad = mid;
 
328
        }
327
329
 
328
330
      if (!r && ok)
329
 
        {
330
 
          /* The last conversion attempt failed;
331
 
             revert to the most recent successful attempt.  */
332
 
          *t = ok;
333
 
          r = convert (t, tp);
334
 
        }
 
331
        {
 
332
          /* The last conversion attempt failed;
 
333
             revert to the most recent successful attempt.  */
 
334
          *t = ok;
 
335
          r = convert (t, tp);
 
336
        }
335
337
    }
336
338
 
337
339
  return r;
346
348
   This function is external because it is used also by timegm.c.  */
347
349
time_t
348
350
__mktime_internal (struct tm *tp,
349
 
                   struct tm *(*convert) (const time_t *, struct tm *),
350
 
                   time_t *offset)
 
351
                   struct tm *(*convert) (const time_t *, struct tm *),
 
352
                   time_t *offset)
351
353
{
352
354
  time_t t, gt, t0, t1, t2;
353
355
  struct tm tm;
386
388
  /* Calculate day of year from year, month, and day of month.
387
389
     The result need not be in range.  */
388
390
  int mon_yday = ((__mon_yday[leapyear (year)]
389
 
                   [mon_remainder + 12 * negative_mon_remainder])
390
 
                  - 1);
 
391
                   [mon_remainder + 12 * negative_mon_remainder])
 
392
                  - 1);
391
393
  long_int lmday = mday;
392
394
  long_int yday = mon_yday + lmday;
393
395
 
398
400
  if (LEAP_SECONDS_POSSIBLE)
399
401
    {
400
402
      /* Handle out-of-range seconds specially,
401
 
         since ydhms_tm_diff assumes every minute has 60 seconds.  */
 
403
         since ydhms_tm_diff assumes every minute has 60 seconds.  */
402
404
      if (sec < 0)
403
 
        sec = 0;
 
405
        sec = 0;
404
406
      if (59 < sec)
405
 
        sec = 59;
 
407
        sec = 59;
406
408
    }
407
409
 
408
410
  /* Invert CONVERT by probing.  First assume the same offset as last
409
411
     time.  */
410
412
 
411
413
  t0 = ydhms_diff (year, yday, hour, min, sec,
412
 
                   EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset);
 
414
                   EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset);
413
415
 
414
416
  if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
415
417
    {
416
418
      /* time_t isn't large enough to rule out overflows, so check
417
 
         for major overflows.  A gross check suffices, since if t0
418
 
         has overflowed, it is off by a multiple of TIME_T_MAX -
419
 
         TIME_T_MIN + 1.  So ignore any component of the difference
420
 
         that is bounded by a small value.  */
 
419
         for major overflows.  A gross check suffices, since if t0
 
420
         has overflowed, it is off by a multiple of TIME_T_MAX -
 
421
         TIME_T_MIN + 1.  So ignore any component of the difference
 
422
         that is bounded by a small value.  */
421
423
 
422
424
      /* Approximate log base 2 of the number of time units per
423
 
         biennium.  A biennium is 2 years; use this unit instead of
424
 
         years to avoid integer overflow.  For example, 2 average
425
 
         Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds,
426
 
         which is 63113904 seconds, and rint (log2 (63113904)) is
427
 
         26.  */
 
425
         biennium.  A biennium is 2 years; use this unit instead of
 
426
         years to avoid integer overflow.  For example, 2 average
 
427
         Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds,
 
428
         which is 63113904 seconds, and rint (log2 (63113904)) is
 
429
         26.  */
428
430
      int ALOG2_SECONDS_PER_BIENNIUM = 26;
429
431
      int ALOG2_MINUTES_PER_BIENNIUM = 20;
430
432
      int ALOG2_HOURS_PER_BIENNIUM = 14;
432
434
      int LOG2_YEARS_PER_BIENNIUM = 1;
433
435
 
434
436
      int approx_requested_biennia =
435
 
        (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
436
 
         - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
437
 
         + SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
438
 
         + SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
439
 
         + SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
440
 
         + (LEAP_SECONDS_POSSIBLE
441
 
            ? 0
442
 
            : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
 
437
        (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
 
438
         - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
 
439
         + SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
 
440
         + SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
 
441
         + SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
 
442
         + (LEAP_SECONDS_POSSIBLE
 
443
            ? 0
 
444
            : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
443
445
 
444
446
      int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
445
447
      int diff = approx_biennia - approx_requested_biennia;
446
 
      int abs_diff = diff < 0 ? -1 - diff : diff;
 
448
      int approx_abs_diff = diff < 0 ? -1 - diff : diff;
447
449
 
448
450
      /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
449
 
         gives a positive value of 715827882.  Setting a variable
450
 
         first then doing math on it seems to work.
451
 
         (ghazi@caip.rutgers.edu) */
 
451
         gives a positive value of 715827882.  Setting a variable
 
452
         first then doing math on it seems to work.
 
453
         (ghazi@caip.rutgers.edu) */
452
454
      time_t time_t_max = TIME_T_MAX;
453
455
      time_t time_t_min = TIME_T_MIN;
454
456
      time_t overflow_threshold =
455
 
        (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
 
457
        (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
456
458
 
457
 
      if (overflow_threshold < abs_diff)
458
 
        {
459
 
          /* Overflow occurred.  Try repairing it; this might work if
460
 
             the time zone offset is enough to undo the overflow.  */
461
 
          time_t repaired_t0 = -1 - t0;
462
 
          approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
463
 
          diff = approx_biennia - approx_requested_biennia;
464
 
          abs_diff = diff < 0 ? -1 - diff : diff;
465
 
          if (overflow_threshold < abs_diff)
466
 
            return -1;
467
 
          guessed_offset += repaired_t0 - t0;
468
 
          t0 = repaired_t0;
469
 
        }
 
459
      if (overflow_threshold < approx_abs_diff)
 
460
        {
 
461
          /* Overflow occurred.  Try repairing it; this might work if
 
462
             the time zone offset is enough to undo the overflow.  */
 
463
          time_t repaired_t0 = -1 - t0;
 
464
          approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
 
465
          diff = approx_biennia - approx_requested_biennia;
 
466
          approx_abs_diff = diff < 0 ? -1 - diff : diff;
 
467
          if (overflow_threshold < approx_abs_diff)
 
468
            return -1;
 
469
          guessed_offset += repaired_t0 - t0;
 
470
          t0 = repaired_t0;
 
471
        }
470
472
    }
471
473
 
472
474
  /* Repeatedly use the error to improve the guess.  */
473
475
 
474
476
  for (t = t1 = t2 = t0, dst2 = 0;
475
477
       (gt = guess_time_tm (year, yday, hour, min, sec, &t,
476
 
                            ranged_convert (convert, &t, &tm)),
477
 
        t != gt);
 
478
                            ranged_convert (convert, &t, &tm)),
 
479
        t != gt);
478
480
       t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0)
479
481
    if (t == t1 && t != t2
480
 
        && (tm.tm_isdst < 0
481
 
            || (isdst < 0
482
 
                ? dst2 <= (tm.tm_isdst != 0)
483
 
                : (isdst != 0) != (tm.tm_isdst != 0))))
 
482
        && (tm.tm_isdst < 0
 
483
            || (isdst < 0
 
484
                ? dst2 <= (tm.tm_isdst != 0)
 
485
                : (isdst != 0) != (tm.tm_isdst != 0))))
484
486
      /* We can't possibly find a match, as we are oscillating
485
 
         between two values.  The requested time probably falls
486
 
         within a spring-forward gap of size GT - T.  Follow the common
487
 
         practice in this case, which is to return a time that is GT - T
488
 
         away from the requested time, preferring a time whose
489
 
         tm_isdst differs from the requested value.  (If no tm_isdst
490
 
         was requested and only one of the two values has a nonzero
491
 
         tm_isdst, prefer that value.)  In practice, this is more
492
 
         useful than returning -1.  */
 
487
         between two values.  The requested time probably falls
 
488
         within a spring-forward gap of size GT - T.  Follow the common
 
489
         practice in this case, which is to return a time that is GT - T
 
490
         away from the requested time, preferring a time whose
 
491
         tm_isdst differs from the requested value.  (If no tm_isdst
 
492
         was requested and only one of the two values has a nonzero
 
493
         tm_isdst, prefer that value.)  In practice, this is more
 
494
         useful than returning -1.  */
493
495
      goto offset_found;
494
496
    else if (--remaining_probes == 0)
495
497
      return -1;
499
501
  if (isdst_differ (isdst, tm.tm_isdst))
500
502
    {
501
503
      /* tm.tm_isdst has the wrong value.  Look for a neighboring
502
 
         time with the right value, and use its UTC offset.
 
504
         time with the right value, and use its UTC offset.
503
505
 
504
 
         Heuristic: probe the adjacent timestamps in both directions,
505
 
         looking for the desired isdst.  This should work for all real
506
 
         time zone histories in the tz database.  */
 
506
         Heuristic: probe the adjacent timestamps in both directions,
 
507
         looking for the desired isdst.  This should work for all real
 
508
         time zone histories in the tz database.  */
507
509
 
508
510
      /* Distance between probes when looking for a DST boundary.  In
509
 
         tzdata2003a, the shortest period of DST is 601200 seconds
510
 
         (e.g., America/Recife starting 2000-10-08 01:00), and the
511
 
         shortest period of non-DST surrounded by DST is 694800
512
 
         seconds (Africa/Tunis starting 1943-04-17 01:00).  Use the
513
 
         minimum of these two values, so we don't miss these short
514
 
         periods when probing.  */
 
511
         tzdata2003a, the shortest period of DST is 601200 seconds
 
512
         (e.g., America/Recife starting 2000-10-08 01:00), and the
 
513
         shortest period of non-DST surrounded by DST is 694800
 
514
         seconds (Africa/Tunis starting 1943-04-17 01:00).  Use the
 
515
         minimum of these two values, so we don't miss these short
 
516
         periods when probing.  */
515
517
      int stride = 601200;
516
518
 
517
519
      /* The longest period of DST in tzdata2003a is 536454000 seconds
518
 
         (e.g., America/Jujuy starting 1946-10-01 01:00).  The longest
519
 
         period of non-DST is much longer, but it makes no real sense
520
 
         to search for more than a year of non-DST, so use the DST
521
 
         max.  */
 
520
         (e.g., America/Jujuy starting 1946-10-01 01:00).  The longest
 
521
         period of non-DST is much longer, but it makes no real sense
 
522
         to search for more than a year of non-DST, so use the DST
 
523
         max.  */
522
524
      int duration_max = 536454000;
523
525
 
524
526
      /* Search in both directions, so the maximum distance is half
525
 
         the duration; add the stride to avoid off-by-1 problems.  */
 
527
         the duration; add the stride to avoid off-by-1 problems.  */
526
528
      int delta_bound = duration_max / 2 + stride;
527
529
 
528
530
      int delta, direction;
529
531
 
530
532
      for (delta = stride; delta < delta_bound; delta += stride)
531
 
        for (direction = -1; direction <= 1; direction += 2)
532
 
          if (time_t_int_add_ok (t, delta * direction))
533
 
            {
534
 
              time_t ot = t + delta * direction;
535
 
              struct tm otm;
536
 
              ranged_convert (convert, &ot, &otm);
537
 
              if (! isdst_differ (isdst, otm.tm_isdst))
538
 
                {
539
 
                  /* We found the desired tm_isdst.
540
 
                     Extrapolate back to the desired time.  */
541
 
                  t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
542
 
                  ranged_convert (convert, &t, &tm);
543
 
                  goto offset_found;
544
 
                }
545
 
            }
 
533
        for (direction = -1; direction <= 1; direction += 2)
 
534
          if (time_t_int_add_ok (t, delta * direction))
 
535
            {
 
536
              time_t ot = t + delta * direction;
 
537
              struct tm otm;
 
538
              ranged_convert (convert, &ot, &otm);
 
539
              if (! isdst_differ (isdst, otm.tm_isdst))
 
540
                {
 
541
                  /* We found the desired tm_isdst.
 
542
                     Extrapolate back to the desired time.  */
 
543
                  t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
 
544
                  ranged_convert (convert, &t, &tm);
 
545
                  goto offset_found;
 
546
                }
 
547
            }
546
548
    }
547
549
 
548
550
 offset_found:
551
553
  if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec)
552
554
    {
553
555
      /* Adjust time to reflect the tm_sec requested, not the normalized value.
554
 
         Also, repair any damage from a false match due to a leap second.  */
 
556
         Also, repair any damage from a false match due to a leap second.  */
555
557
      int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec;
556
558
      if (! time_t_int_add_ok (t, sec_requested))
557
 
        return -1;
 
559
        return -1;
558
560
      t1 = t + sec_requested;
559
561
      if (! time_t_int_add_ok (t1, sec_adjustment))
560
 
        return -1;
 
562
        return -1;
561
563
      t2 = t1 + sec_adjustment;
562
564
      if (! convert (&t2, &tm))
563
 
        return -1;
 
565
        return -1;
564
566
      t = t2;
565
567
    }
566
568
 
581
583
{
582
584
#ifdef _LIBC
583
585
  /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
584
 
     time zone names contained in the external variable `tzname' shall
 
586
     time zone names contained in the external variable 'tzname' shall
585
587
     be set as if the tzset() function had been called.  */
586
588
  __tzset ();
587
589
#endif
604
606
not_equal_tm (const struct tm *a, const struct tm *b)
605
607
{
606
608
  return ((a->tm_sec ^ b->tm_sec)
607
 
          | (a->tm_min ^ b->tm_min)
608
 
          | (a->tm_hour ^ b->tm_hour)
609
 
          | (a->tm_mday ^ b->tm_mday)
610
 
          | (a->tm_mon ^ b->tm_mon)
611
 
          | (a->tm_year ^ b->tm_year)
612
 
          | (a->tm_yday ^ b->tm_yday)
613
 
          | isdst_differ (a->tm_isdst, b->tm_isdst));
 
609
          | (a->tm_min ^ b->tm_min)
 
610
          | (a->tm_hour ^ b->tm_hour)
 
611
          | (a->tm_mday ^ b->tm_mday)
 
612
          | (a->tm_mon ^ b->tm_mon)
 
613
          | (a->tm_year ^ b->tm_year)
 
614
          | (a->tm_yday ^ b->tm_yday)
 
615
          | isdst_differ (a->tm_isdst, b->tm_isdst));
614
616
}
615
617
 
616
618
static void
618
620
{
619
621
  if (tp)
620
622
    printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
621
 
            tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
622
 
            tp->tm_hour, tp->tm_min, tp->tm_sec,
623
 
            tp->tm_yday, tp->tm_wday, tp->tm_isdst);
 
623
            tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
 
624
            tp->tm_hour, tp->tm_min, tp->tm_sec,
 
625
            tp->tm_yday, tp->tm_wday, tp->tm_isdst);
624
626
  else
625
627
    printf ("0");
626
628
}
652
654
 
653
655
  if ((argc == 3 || argc == 4)
654
656
      && (sscanf (argv[1], "%d-%d-%d%c",
655
 
                  &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
656
 
          == 3)
 
657
                  &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
 
658
          == 3)
657
659
      && (sscanf (argv[2], "%d:%d:%d%c",
658
 
                  &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
659
 
          == 3))
 
660
                  &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
 
661
          == 3))
660
662
    {
661
663
      tm.tm_year -= TM_YEAR_BASE;
662
664
      tm.tm_mon--;
665
667
      tl = mktime (&tmk);
666
668
      lt = localtime (&tl);
667
669
      if (lt)
668
 
        {
669
 
          tml = *lt;
670
 
          lt = &tml;
671
 
        }
 
670
        {
 
671
          tml = *lt;
 
672
          lt = &tml;
 
673
        }
672
674
      printf ("mktime returns %ld == ", (long int) tl);
673
675
      print_tm (&tmk);
674
676
      printf ("\n");
681
683
      time_t to = atol (argv[3]);
682
684
 
683
685
      if (argc == 4)
684
 
        for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
685
 
          {
686
 
            lt = localtime (&tl);
687
 
            if (lt)
688
 
              {
689
 
                tmk = tml = *lt;
690
 
                tk = mktime (&tmk);
691
 
                status |= check_result (tk, tmk, tl, &tml);
692
 
              }
693
 
            else
694
 
              {
695
 
                printf ("localtime (%ld) yields 0\n", (long int) tl);
696
 
                status = 1;
697
 
              }
698
 
            tl1 = tl + by;
699
 
            if ((tl1 < tl) != (by < 0))
700
 
              break;
701
 
          }
 
686
        for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
 
687
          {
 
688
            lt = localtime (&tl);
 
689
            if (lt)
 
690
              {
 
691
                tmk = tml = *lt;
 
692
                tk = mktime (&tmk);
 
693
                status |= check_result (tk, tmk, tl, &tml);
 
694
              }
 
695
            else
 
696
              {
 
697
                printf ("localtime (%ld) yields 0\n", (long int) tl);
 
698
                status = 1;
 
699
              }
 
700
            tl1 = tl + by;
 
701
            if ((tl1 < tl) != (by < 0))
 
702
              break;
 
703
          }
702
704
      else
703
 
        for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
704
 
          {
705
 
            /* Null benchmark.  */
706
 
            lt = localtime (&tl);
707
 
            if (lt)
708
 
              {
709
 
                tmk = tml = *lt;
710
 
                tk = tl;
711
 
                status |= check_result (tk, tmk, tl, &tml);
712
 
              }
713
 
            else
714
 
              {
715
 
                printf ("localtime (%ld) yields 0\n", (long int) tl);
716
 
                status = 1;
717
 
              }
718
 
            tl1 = tl + by;
719
 
            if ((tl1 < tl) != (by < 0))
720
 
              break;
721
 
          }
 
705
        for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
 
706
          {
 
707
            /* Null benchmark.  */
 
708
            lt = localtime (&tl);
 
709
            if (lt)
 
710
              {
 
711
                tmk = tml = *lt;
 
712
                tk = tl;
 
713
                status |= check_result (tk, tmk, tl, &tml);
 
714
              }
 
715
            else
 
716
              {
 
717
                printf ("localtime (%ld) yields 0\n", (long int) tl);
 
718
                status = 1;
 
719
              }
 
720
            tl1 = tl + by;
 
721
            if ((tl1 < tl) != (by < 0))
 
722
              break;
 
723
          }
722
724
    }
723
725
  else
724
726
    printf ("Usage:\
725
727
\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
726
728
\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
727
729
\t%s FROM BY TO - # Do not test those values (for benchmark).\n",
728
 
            argv[0], argv[0], argv[0]);
 
730
            argv[0], argv[0], argv[0]);
729
731
 
730
732
  return status;
731
733
}