Blame m4/mktime.m4

Packit Service fdd496
# serial 28
Packit Service fdd496
dnl Copyright (C) 2002-2003, 2005-2007, 2009-2017 Free Software Foundation,
Packit Service fdd496
dnl Inc.
Packit Service fdd496
dnl This file is free software; the Free Software Foundation
Packit Service fdd496
dnl gives unlimited permission to copy and/or distribute it,
Packit Service fdd496
dnl with or without modifications, as long as this notice is preserved.
Packit Service fdd496
Packit Service fdd496
dnl From Jim Meyering.
Packit Service fdd496
Packit Service fdd496
AC_DEFUN([gl_TIME_T_IS_SIGNED],
Packit Service fdd496
[
Packit Service fdd496
  AC_CACHE_CHECK([whether time_t is signed],
Packit Service fdd496
    [gl_cv_time_t_is_signed],
Packit Service fdd496
    [AC_COMPILE_IFELSE(
Packit Service fdd496
       [AC_LANG_PROGRAM([[#include <time.h>
Packit Service fdd496
                          char time_t_signed[(time_t) -1 < 0 ? 1 : -1];]])],
Packit Service fdd496
       [gl_cv_time_t_is_signed=yes],
Packit Service fdd496
       [gl_cv_time_t_is_signed=no])])
Packit Service fdd496
  if test $gl_cv_time_t_is_signed = yes; then
Packit Service fdd496
    AC_DEFINE([TIME_T_IS_SIGNED], [1], [Define to 1 if time_t is signed.])
Packit Service fdd496
  fi
Packit Service fdd496
])
Packit Service fdd496
Packit Service fdd496
dnl Test whether mktime works. Set gl_cv_func_working_mktime.
Packit Service fdd496
AC_DEFUN([gl_FUNC_MKTIME_WORKS],
Packit Service fdd496
[
Packit Service fdd496
  AC_REQUIRE([gl_TIME_T_IS_SIGNED])
Packit Service fdd496
Packit Service fdd496
  dnl We don't use AC_FUNC_MKTIME any more, because it is no longer maintained
Packit Service fdd496
  dnl in Autoconf and because it invokes AC_LIBOBJ.
Packit Service fdd496
  AC_CHECK_HEADERS_ONCE([unistd.h])
Packit Service fdd496
  AC_CHECK_DECLS_ONCE([alarm])
Packit Service fdd496
  AC_CHECK_FUNCS_ONCE([tzset])
Packit Service fdd496
  AC_REQUIRE([gl_MULTIARCH])
Packit Service fdd496
  if test $APPLE_UNIVERSAL_BUILD = 1; then
Packit Service fdd496
    # A universal build on Apple Mac OS X platforms.
Packit Service fdd496
    # The test result would be 'yes' in 32-bit mode and 'no' in 64-bit mode.
Packit Service fdd496
    # But we need a configuration result that is valid in both modes.
Packit Service fdd496
    gl_cv_func_working_mktime=no
Packit Service fdd496
  fi
Packit Service fdd496
  AC_CACHE_CHECK([for working mktime], [gl_cv_func_working_mktime],
Packit Service fdd496
    [AC_RUN_IFELSE(
Packit Service fdd496
       [AC_LANG_SOURCE(
Packit Service fdd496
[[/* Test program from Paul Eggert and Tony Leneis.  */
Packit Service fdd496
#include <limits.h>
Packit Service fdd496
#include <stdlib.h>
Packit Service fdd496
#include <time.h>
Packit Service fdd496
Packit Service fdd496
#ifdef HAVE_UNISTD_H
Packit Service fdd496
# include <unistd.h>
Packit Service fdd496
#endif
Packit Service fdd496
Packit Service fdd496
#if HAVE_DECL_ALARM
Packit Service fdd496
# include <signal.h>
Packit Service fdd496
#endif
Packit Service fdd496
Packit Service fdd496
/* Work around redefinition to rpl_putenv by other config tests.  */
Packit Service fdd496
#undef putenv
Packit Service fdd496
Packit Service fdd496
static time_t time_t_max;
Packit Service fdd496
static time_t time_t_min;
Packit Service fdd496
Packit Service fdd496
/* Values we'll use to set the TZ environment variable.  */
Packit Service fdd496
static char *tz_strings[] = {
Packit Service fdd496
  (char *) 0, "TZ=GMT0", "TZ=JST-9",
Packit Service fdd496
  "TZ=EST+3EDT+2,M10.1.0/00:00:00,M2.3.0/00:00:00"
Packit Service fdd496
};
Packit Service fdd496
#define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0]))
Packit Service fdd496
Packit Service fdd496
/* Return 0 if mktime fails to convert a date in the spring-forward gap.
Packit Service fdd496
   Based on a problem report from Andreas Jaeger.  */
Packit Service fdd496
static int
Packit Service fdd496
spring_forward_gap ()
Packit Service fdd496
{
Packit Service fdd496
  /* glibc (up to about 1998-10-07) failed this test. */
Packit Service fdd496
  struct tm tm;
Packit Service fdd496
Packit Service fdd496
  /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0"
Packit Service fdd496
     instead of "TZ=America/Vancouver" in order to detect the bug even
Packit Service fdd496
     on systems that don't support the Olson extension, or don't have the
Packit Service fdd496
     full zoneinfo tables installed.  */
Packit Service fdd496
  putenv ("TZ=PST8PDT,M4.1.0,M10.5.0");
Packit Service fdd496
Packit Service fdd496
  tm.tm_year = 98;
Packit Service fdd496
  tm.tm_mon = 3;
Packit Service fdd496
  tm.tm_mday = 5;
Packit Service fdd496
  tm.tm_hour = 2;
Packit Service fdd496
  tm.tm_min = 0;
Packit Service fdd496
  tm.tm_sec = 0;
Packit Service fdd496
  tm.tm_isdst = -1;
Packit Service fdd496
  return mktime (&tm) != (time_t) -1;
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
static int
Packit Service fdd496
mktime_test1 (time_t now)
Packit Service fdd496
{
Packit Service fdd496
  struct tm *lt;
Packit Service fdd496
  return ! (lt = localtime (&now)) || mktime (lt) == now;
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
static int
Packit Service fdd496
mktime_test (time_t now)
Packit Service fdd496
{
Packit Service fdd496
  return (mktime_test1 (now)
Packit Service fdd496
          && mktime_test1 ((time_t) (time_t_max - now))
Packit Service fdd496
          && mktime_test1 ((time_t) (time_t_min + now)));
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
static int
Packit Service fdd496
irix_6_4_bug ()
Packit Service fdd496
{
Packit Service fdd496
  /* Based on code from Ariel Faigon.  */
Packit Service fdd496
  struct tm tm;
Packit Service fdd496
  tm.tm_year = 96;
Packit Service fdd496
  tm.tm_mon = 3;
Packit Service fdd496
  tm.tm_mday = 0;
Packit Service fdd496
  tm.tm_hour = 0;
Packit Service fdd496
  tm.tm_min = 0;
Packit Service fdd496
  tm.tm_sec = 0;
Packit Service fdd496
  tm.tm_isdst = -1;
Packit Service fdd496
  mktime (&tm;;
Packit Service fdd496
  return tm.tm_mon == 2 && tm.tm_mday == 31;
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
static int
Packit Service fdd496
bigtime_test (int j)
Packit Service fdd496
{
Packit Service fdd496
  struct tm tm;
Packit Service fdd496
  time_t now;
Packit Service fdd496
  tm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = j;
Packit Service fdd496
  now = mktime (&tm;;
Packit Service fdd496
  if (now != (time_t) -1)
Packit Service fdd496
    {
Packit Service fdd496
      struct tm *lt = localtime (&now;;
Packit Service fdd496
      if (! (lt
Packit Service fdd496
             && lt->tm_year == tm.tm_year
Packit Service fdd496
             && lt->tm_mon == tm.tm_mon
Packit Service fdd496
             && lt->tm_mday == tm.tm_mday
Packit Service fdd496
             && lt->tm_hour == tm.tm_hour
Packit Service fdd496
             && lt->tm_min == tm.tm_min
Packit Service fdd496
             && lt->tm_sec == tm.tm_sec
Packit Service fdd496
             && lt->tm_yday == tm.tm_yday
Packit Service fdd496
             && lt->tm_wday == tm.tm_wday
Packit Service fdd496
             && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst)
Packit Service fdd496
                  == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst))))
Packit Service fdd496
        return 0;
Packit Service fdd496
    }
Packit Service fdd496
  return 1;
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
static int
Packit Service fdd496
year_2050_test ()
Packit Service fdd496
{
Packit Service fdd496
  /* The correct answer for 2050-02-01 00:00:00 in Pacific time,
Packit Service fdd496
     ignoring leap seconds.  */
Packit Service fdd496
  unsigned long int answer = 2527315200UL;
Packit Service fdd496
Packit Service fdd496
  struct tm tm;
Packit Service fdd496
  time_t t;
Packit Service fdd496
  tm.tm_year = 2050 - 1900;
Packit Service fdd496
  tm.tm_mon = 2 - 1;
Packit Service fdd496
  tm.tm_mday = 1;
Packit Service fdd496
  tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
Packit Service fdd496
  tm.tm_isdst = -1;
Packit Service fdd496
Packit Service fdd496
  /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0"
Packit Service fdd496
     instead of "TZ=America/Vancouver" in order to detect the bug even
Packit Service fdd496
     on systems that don't support the Olson extension, or don't have the
Packit Service fdd496
     full zoneinfo tables installed.  */
Packit Service fdd496
  putenv ("TZ=PST8PDT,M4.1.0,M10.5.0");
Packit Service fdd496
Packit Service fdd496
  t = mktime (&tm;;
Packit Service fdd496
Packit Service fdd496
  /* Check that the result is either a failure, or close enough
Packit Service fdd496
     to the correct answer that we can assume the discrepancy is
Packit Service fdd496
     due to leap seconds.  */
Packit Service fdd496
  return (t == (time_t) -1
Packit Service fdd496
          || (0 < t && answer - 120 <= t && t <= answer + 120));
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
int
Packit Service fdd496
main ()
Packit Service fdd496
{
Packit Service fdd496
  int result = 0;
Packit Service fdd496
  time_t t, delta;
Packit Service fdd496
  int i, j;
Packit Service fdd496
  int time_t_signed_magnitude = (time_t) ~ (time_t) 0 < (time_t) -1;
Packit Service fdd496
Packit Service fdd496
#if HAVE_DECL_ALARM
Packit Service fdd496
  /* This test makes some buggy mktime implementations loop.
Packit Service fdd496
     Give up after 60 seconds; a mktime slower than that
Packit Service fdd496
     isn't worth using anyway.  */
Packit Service fdd496
  signal (SIGALRM, SIG_DFL);
Packit Service fdd496
  alarm (60);
Packit Service fdd496
#endif
Packit Service fdd496
Packit Service fdd496
  time_t_max = (! TIME_T_IS_SIGNED
Packit Service fdd496
                ? (time_t) -1
Packit Service fdd496
                : ((((time_t) 1 << (sizeof (time_t) * CHAR_BIT - 2)) - 1)
Packit Service fdd496
                   * 2 + 1));
Packit Service fdd496
  time_t_min = (! TIME_T_IS_SIGNED
Packit Service fdd496
                ? (time_t) 0
Packit Service fdd496
                : time_t_signed_magnitude
Packit Service fdd496
                ? ~ (time_t) 0
Packit Service fdd496
                : ~ time_t_max);
Packit Service fdd496
Packit Service fdd496
  delta = time_t_max / 997; /* a suitable prime number */
Packit Service fdd496
  for (i = 0; i < N_STRINGS; i++)
Packit Service fdd496
    {
Packit Service fdd496
      if (tz_strings[i])
Packit Service fdd496
        putenv (tz_strings[i]);
Packit Service fdd496
Packit Service fdd496
      for (t = 0; t <= time_t_max - delta && (result & 1) == 0; t += delta)
Packit Service fdd496
        if (! mktime_test (t))
Packit Service fdd496
          result |= 1;
Packit Service fdd496
      if ((result & 2) == 0
Packit Service fdd496
          && ! (mktime_test ((time_t) 1)
Packit Service fdd496
                && mktime_test ((time_t) (60 * 60))
Packit Service fdd496
                && mktime_test ((time_t) (60 * 60 * 24))))
Packit Service fdd496
        result |= 2;
Packit Service fdd496
Packit Service fdd496
      for (j = 1; (result & 4) == 0; j <<= 1)
Packit Service fdd496
        {
Packit Service fdd496
          if (! bigtime_test (j))
Packit Service fdd496
            result |= 4;
Packit Service fdd496
          if (INT_MAX / 2 < j)
Packit Service fdd496
            break;
Packit Service fdd496
        }
Packit Service fdd496
      if ((result & 8) == 0 && ! bigtime_test (INT_MAX))
Packit Service fdd496
        result |= 8;
Packit Service fdd496
    }
Packit Service fdd496
  if (! irix_6_4_bug ())
Packit Service fdd496
    result |= 16;
Packit Service fdd496
  if (! spring_forward_gap ())
Packit Service fdd496
    result |= 32;
Packit Service fdd496
  if (! year_2050_test ())
Packit Service fdd496
    result |= 64;
Packit Service fdd496
  return result;
Packit Service fdd496
}]])],
Packit Service fdd496
       [gl_cv_func_working_mktime=yes],
Packit Service fdd496
       [gl_cv_func_working_mktime=no],
Packit Service fdd496
       [gl_cv_func_working_mktime="guessing no"])
Packit Service fdd496
    ])
Packit Service fdd496
])
Packit Service fdd496
Packit Service fdd496
dnl Main macro of module 'mktime'.
Packit Service fdd496
AC_DEFUN([gl_FUNC_MKTIME],
Packit Service fdd496
[
Packit Service fdd496
  AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
Packit Service fdd496
  AC_REQUIRE([AC_CANONICAL_HOST])
Packit Service fdd496
  AC_REQUIRE([gl_FUNC_MKTIME_WORKS])
Packit Service fdd496
Packit Service fdd496
  REPLACE_MKTIME=0
Packit Service fdd496
  if test "$gl_cv_func_working_mktime" != yes; then
Packit Service fdd496
    REPLACE_MKTIME=1
Packit Service fdd496
    AC_DEFINE([NEED_MKTIME_WORKING], [1],
Packit Service fdd496
      [Define if the compilation of mktime.c should define 'mktime'
Packit Service fdd496
       with the algorithmic workarounds.])
Packit Service fdd496
  fi
Packit Service fdd496
  case "$host_os" in
Packit Service fdd496
    mingw*)
Packit Service fdd496
      REPLACE_MKTIME=1
Packit Service fdd496
      AC_DEFINE([NEED_MKTIME_WINDOWS], [1],
Packit Service fdd496
        [Define if the compilation of mktime.c should define 'mktime'
Packit Service fdd496
         with the native Windows TZ workaround.])
Packit Service fdd496
      ;;
Packit Service fdd496
  esac
Packit Service fdd496
])
Packit Service fdd496
Packit Service fdd496
dnl Main macro of module 'mktime-internal'.
Packit Service fdd496
AC_DEFUN([gl_FUNC_MKTIME_INTERNAL], [
Packit Service fdd496
  AC_REQUIRE([gl_FUNC_MKTIME_WORKS])
Packit Service fdd496
Packit Service fdd496
  WANT_MKTIME_INTERNAL=0
Packit Service fdd496
  dnl BeOS has __mktime_internal in libc, but other platforms don't.
Packit Service fdd496
  AC_CHECK_FUNC([__mktime_internal],
Packit Service fdd496
    [AC_DEFINE([mktime_internal], [__mktime_internal],
Packit Service fdd496
       [Define to the real name of the mktime_internal function.])
Packit Service fdd496
    ],
Packit Service fdd496
    [dnl mktime works but it doesn't export __mktime_internal,
Packit Service fdd496
     dnl so we need to substitute our own mktime implementation.
Packit Service fdd496
     WANT_MKTIME_INTERNAL=1
Packit Service fdd496
     AC_DEFINE([NEED_MKTIME_INTERNAL], [1],
Packit Service fdd496
       [Define if the compilation of mktime.c should define 'mktime_internal'.])
Packit Service fdd496
    ])
Packit Service fdd496
])
Packit Service fdd496
Packit Service fdd496
# Prerequisites of lib/mktime.c.
Packit Service fdd496
AC_DEFUN([gl_PREREQ_MKTIME], [:])