The current AC_STRUCT_TIMEZONE macro does the following to check for the
external tzname array:

[AC_TRY_LINK(
[#include <time.h>
#ifndef tzname /* For SGI.  */
extern char *tzname[]; /* RS6000 and others reject char **tzname.  */
#endif
],
[atoi(*tzname);], ac_cv_var_tzname=yes, ac_cv_var_tzname=no)])

The atoi() makes no sense.  It doesn't actually matter, since the code is
never run and the result isn't used anyway, but someone looking at this
code may get very confused as to what autoconf expects to find in tzname.

The tzname array on every platform I'm familiar with, if present, contains
the time zone *abbreviations*, stuff like EST or PDT.  I've never seen it
contain anything suitable for passing to atoi().  It's mostly only useful
to use in a comment to help humans figure out what time zone is meant if
they can't read UTC offsets, and is generally accessed using some
variation of:

    tzname[tm->tm_isdst > 0 ? 1 : 0];

Can I suggest the atoi() be replaced by something else that makes more
sense?

Also, what's the autoconf standard for results concerning the presence or
absence of external variables?  Right now, this macro (which is oddly
named) sets HAVE_TZNAME if tzname is available.  This intrudes on the
result space for functions; a similar macro checking for the existence of
the external variable timezone would define HAVE_TIMEZONE, but that's
ambiguous as there's also a *function* timezone() available on BSD hosts.

The macros I'm currently using for INN set HAVE_VAR_TIMEZONE and
HAVE_VAR_TZNAME instead, which seemed at least somewhat better.

A better name for AC_STRUCT_TIMEZONE would be AC_STRUCT_TM_ZONE, and a
complimentary macro AC_STRUCT_TM_GMTOFF would actually be more generally
useful (as knowing the offset from UTC is usually more important than
knowing the symbolic timezone abbreviation, which is what
HAVE_STRUCT_TIMEZONE currently finds).

FWIW, here are the macros I'm currently using (they're in autoconf 2.13
style, not in autoconf 2.50 style; I'm anxiously awaiting the release of
the latter and then intend to completely overhaul INN's configure.in and
update the style of all of our macros, as well as submit the most useful
ones to the macro repository).

Note that this check for tzname is pickier than autoconf's, as it doesn't
attempt its own external definition and instead expects time.h to handle
it.  I think this is a slightly better way of doing the test, but it's
really a matter of preference.

dnl BSD hosts have a tm_gmtoff element in struct tm containing the offset
dnl from GMT/UTC for that time.  This is the strongly preferred way of
dnl getting time zone information.
AC_DEFUN([INN_STRUCT_TM_GMTOFF],
[AC_CACHE_CHECK(for tm_gmtoff in struct tm, inn_cv_struct_tm_gmtoff,
    AC_TRY_LINK([#include <time.h>],
        [struct tm t; t.tm_gmtoff = 3600],
        inn_cv_struct_tm_gmtoff=yes,
        inn_cv_struct_tm_gmtoff=no))
if test x"$inn_cv_struct_tm_gmtoff" = xyes ; then
    AC_DEFINE([HAVE_TM_GMTOFF], 1,
        [Define if your struct tm has a tm_gmtoff member.])
fi])

dnl BSD hosts have the name of the local time zone in struct tm, which is
dnl much nicer to use than the tzname variable (and also potentially handles
dnl renamings of the time zone in the  past).
AC_DEFUN([INN_STRUCT_TM_ZONE],
[AC_CACHE_CHECK(for tm_zone in struct tm, inn_cv_struct_tm_zone,
    AC_TRY_LINK([#include <time.h>],
        [struct tm t; t.tm_zone = "UTC"],
        inn_cv_struct_tm_zone=yes,
        inn_cv_struct_tm_zone=no))
if test x"$inn_cv_struct_tm_zone" = xyes ; then
    AC_DEFINE([HAVE_TM_ZONE], 1,
        [Define if your struct tm has a tm_zone member.])
fi])

dnl Many System V hosts have an external variable timezone containing the
dnl offset of local standard time from GMT/UTC (and the complimentary
dnl variable altzone containing the offset of local summer time).  We can
dnl use this for the timezone offset for current time, although it's not
dnl usable for anything else (like historic times).  Unfortunately, some
dnl BSD varients have a function named timezone instead.  HP-UX 11.00 has
dnl timezone but doesn't have altzone, which isn't good enough.
AC_DEFUN([INN_VAR_TIMEZONE],
[AC_CACHE_CHECK(for timezone variable, inn_cv_var_timezone,
    AC_TRY_LINK([#include <time.h>], [timezone = 3600; altzone = 7200],
        inn_cv_var_timezone=yes,
        inn_cv_var_timezone=no))
if test x"$inn_cv_var_timezone" = xyes ; then
    AC_DEFINE([HAVE_VAR_TIMEZONE], 1,
        [Define if timezone is an external variable in <time.h>.])
fi])

dnl Many System V hosts and some BSD systems have an external variable
dnl tzname containing the abbreviations of the main and alternate time
dnl zone.  We can use these as a reasonable approximation of the correct
dnl time zone names, although they could be incorrect if the time zone
dnl name has changed in the past.
AC_DEFUN([INN_VAR_TZNAME],
[AC_CACHE_CHECK(for tzname variable, inn_cv_var_tzname,
    AC_TRY_LINK([#include <time.h>], [*tzname = "UTC"],
        inn_cv_var_tzname=yes, inn_cv_var_tzname=no))
if test x"$inn_cv_var_tzname" = xyes ; then
    AC_DEFINE([HAVE_VAR_TZNAME], 1,
        [Define if tzname is an external variable in <time.h>.])
fi])

-- 
Russ Allbery ([EMAIL PROTECTED])             <http://www.eyrie.org/~eagle/>

Reply via email to