libstdc++: Embed a static copy of tzdata.zi

This adds a copy of the tzdata.zi file to the library, and allows
configuring to use it instead of a copy read from disk at runtime.
The content of the file is in the public domain, but will need to be
updated to the latest upstream file before making GCC releases.

libstdc++-v3/ChangeLog:

	* acinclude.m4 (GLIBCXX_ZONEINFO_DIR): Replace the
	--with-libstdcxx-zoneinfo-dir configure option with
	--with-libstdcxx-zoneinfo with yes/no/static choices as well as
	a directory.
	* config.h.in: Regenerate.
	* configure: Regenerate.
	* doc/xml/manual/configure.xml: Document configure option.
	* doc/html/manual/configure.html: Regenerate.
	* src/c++20/Makefile.am: Generate tzdata.zi.h header.
	* src/c++20/Makefile.in: Regenerate.
	* src/c++20/tzdb.cc (__gnu_cxx::zoneinfo_dir_override): Return a
	null pointer if no directory is configured.
	(zoneinfo_dir): Replace with ...
	(zoneinfo_file): New function.
	(tzdata_stream): New istream class.
	(remote_version, reload_tzdb): Use tzdata_stream.
	* testsuite/lib/libstdc++.exp (check_effective_target_tzdb):
	Check new _GLIBCXX_STATIC_TZDATA macro and ignore presence of
	tzdata.zi file in default location.
	* src/c++20/tzdata.zi: New file.
This commit is contained in:
Jonathan Wakely 2023-01-14 13:33:58 +00:00
parent ff6c761710
commit 559993b857
10 changed files with 4545 additions and 74 deletions

View file

@ -5157,28 +5157,87 @@ AC_DEFUN([GLIBCXX_EMERGENCY_EH_ALLOC], [
dnl
dnl Allow the location of tzdata files to be configured.
dnl
dnl --with-libstdcxx-zoneinfo-dir=PATH will set the directory to PATH.
dnl --with-libstdcxx-zoneinfo=ARG where ARG can be:
dnl DIR - use DIR/tzdata.zi and DIR/leapseconds files.
dnl static - use static copy of tzdata.zi embedded in the library.
dnl DIR,static - use DIR, but use embedded static copy as fallback.
dnl yes - equivalent to DIR,static with a system-specific value for DIR.
dnl no - disable most tzdb functionality.
dnl
dnl Defines:
dnl _GLIBCXX_ZONEINFO_DIR if std::chrono::tzdb should use a non-default
dnl _GLIBCXX_ZONEINFO_DIR if std::chrono::tzdb should use the specified
dnl directory for the tzdata.zi and leapseconds files.
dnl _GLIBCXX_STATIC_TZDATA if std::chrono::tzdb should use an embedded
dnl static copy of the tzdata.zi file.
dnl
AC_DEFUN([GLIBCXX_ZONEINFO_DIR], [
AC_ARG_WITH([libstdcxx-zoneinfo-dir],
AC_HELP_STRING([--with-libstdcxx-zoneinfo-dir],
[the directory to search for tzdata files]),
[zoneinfo_dir="${withval}"
AC_DEFINE(_GLIBCXX_ZONEINFO_DIR, "${withval}",
[Define if a non-default location should be used for tzdata files.])
],
[
case "$host" in
# *-*-aix*) zoneinfo_dir="/usr/share/lib/zoneinfo" ;;
*) zoneinfo_dir="/usr/share/zoneinfo" ;;
esac
])
AC_ARG_WITH([libstdcxx-zoneinfo],
AC_HELP_STRING([--with-libstdcxx-zoneinfo],
[the location to use for tzdata]),
[],[with_libstdcxx_zoneinfo=yes])
if test "x${with_libstdcxx_zoneinfo}" = xyes; then
# Pick a default when no specific path is set.
case "$host" in
gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu)
# Not all distros ship tzdata.zi in this dir.
zoneinfo_dir="/usr/share/zoneinfo"
;;
*-*-aix*)
# Binary tzfile files are in /usr/share/lib/zoneinfo
# but tzdata.zi is not present there.
zoneinfo_dir=none
;;
*-*-darwin2*)
# Binary tzfile files are in /usr/share/lib/zoneinfo.default
# but tzdata.zi is not present there.
zoneinfo_dir=none
;;
*)
# Binary tzfile files are commonly found in /usr/share/zoneinfo
# but tzdata.zi is not present there.
zoneinfo_dir=none
;;
esac
# Also embed a copy of the tzdata.zi file as a static string.
embed_zoneinfo=yes
elif test "x${with_libstdcxx_zoneinfo}" = xno; then
# Disable tzdb support completely.
zoneinfo_dir=none
embed_zoneinfo=no
else
case "${with_libstdcxx_zoneinfo}" in
static)
# Do not attempt to read from disk, always use embedded data.
zoneinfo_dir=none
embed_zoneinfo=yes
;;
static,* | *,static)
# Try to read from disk, use embedded data as fallback.
zoneinfo_dir="${with_libstdcxx_zoneinfo#static,}"
zoneinfo_dir="${with_libstdcxx_zoneinfo%,static}"
embed_zoneinfo=yes
;;
*)
zoneinfo_dir="${with_libstdcxx_zoneinfo}"
embed_zoneinfo=no
;;
esac
fi
AC_MSG_NOTICE([zoneinfo data directory: ${zoneinfo_dir}])
if test "x${zoneinfo_dir}" != xnone; then
AC_DEFINE_UNQUOTED(_GLIBCXX_ZONEINFO_DIR, "${zoneinfo_dir}",
[Define if a directory should be searched for tzdata files.])
if $GLIBCXX_IS_NATIVE -a ! test -f "$zoneinfo_dir/tzdata.zi"; then
AC_MSG_WARN("$zoneinfo_dir does not contain tzdata.zi file")
fi
fi
GLIBCXX_CONDITIONAL(USE_STATIC_TZDATA, test "${embed_zoneinfo}" = yes)
if test "x${embed_zoneinfo}" = xyes; then
AC_MSG_NOTICE([static tzdata.zi file will be compiled into the library])
AC_DEFINE_UNQUOTED(_GLIBCXX_STATIC_TZDATA, 1,
[Define if static tzdata should be compiled into the library.])
fi
])
# Macros from the top-level gcc directory.

View file

@ -854,6 +854,9 @@
/* Define if size_t is unsigned int. */
#undef _GLIBCXX_SIZE_T_IS_UINT
/* Define if static tzdata should be compiled into the library. */
#undef _GLIBCXX_STATIC_TZDATA
/* Define to the value of the EOF integer constant. */
#undef _GLIBCXX_STDIO_EOF
@ -1037,7 +1040,7 @@
/* Defined if as can handle rdseed. */
#undef _GLIBCXX_X86_RDSEED
/* Define if a non-default location should be used for tzdata files. */
/* Define if a directory should be searched for tzdata files. */
#undef _GLIBCXX_ZONEINFO_DIR
/* Define to 1 if mutex_timedlock is available. */

123
libstdc++-v3/configure vendored
View file

@ -675,6 +675,8 @@ DOT
DOXYGEN
BUILD_INFO_FALSE
BUILD_INFO_TRUE
USE_STATIC_TZDATA_FALSE
USE_STATIC_TZDATA_TRUE
EH_POOL_FLAGS
ENABLE_BACKTRACE_FALSE
ENABLE_BACKTRACE_TRUE
@ -961,7 +963,7 @@ enable_libstdcxx_filesystem_ts
enable_libstdcxx_backtrace
enable_libstdcxx_static_eh_pool
with_libstdcxx_eh_pool_obj_count
with_libstdcxx_zoneinfo_dir
with_libstdcxx_zoneinfo
enable_cet
with_gxx_include_dir
enable_version_specific_runtime_libs
@ -1705,8 +1707,8 @@ Optional Packages:
--with-libstdcxx-eh-pool-obj-count
the number of exceptions that can be allocated from
the pool if malloc fails
--with-libstdcxx-zoneinfo-dir
the directory to search for tzdata files
--with-libstdcxx-zoneinfo
the location to use for tzdata
--with-gxx-include-dir=DIR
installation directory for include files
--with-toolexeclibdir=DIR
@ -12185,7 +12187,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 12188 "configure"
#line 12190 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -12291,7 +12293,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 12294 "configure"
#line 12296 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -16015,7 +16017,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
# Fake what AC_TRY_COMPILE does.
cat > conftest.$ac_ext << EOF
#line 16018 "configure"
#line 16020 "configure"
int main()
{
typedef bool atomic_type;
@ -16050,7 +16052,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
#line 16053 "configure"
#line 16055 "configure"
int main()
{
typedef short atomic_type;
@ -16085,7 +16087,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
#line 16088 "configure"
#line 16090 "configure"
int main()
{
// NB: _Atomic_word not necessarily int.
@ -16121,7 +16123,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
#line 16124 "configure"
#line 16126 "configure"
int main()
{
typedef long long atomic_type;
@ -16277,7 +16279,7 @@ $as_echo "mutex" >&6; }
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
#line 16280 "configure"
#line 16282 "configure"
int main()
{
_Decimal32 d1;
@ -16319,7 +16321,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
#line 16322 "configure"
#line 16324 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@ -71511,25 +71513,85 @@ fi
# For src/c++20/tzdb.cc defaults.
# Check whether --with-libstdcxx-zoneinfo-dir was given.
if test "${with_libstdcxx_zoneinfo_dir+set}" = set; then :
withval=$with_libstdcxx_zoneinfo_dir; zoneinfo_dir="${withval}"
$as_echo "#define _GLIBCXX_ZONEINFO_DIR \"\${withval}\"" >>confdefs.h
# Check whether --with-libstdcxx-zoneinfo was given.
if test "${with_libstdcxx_zoneinfo+set}" = set; then :
withval=$with_libstdcxx_zoneinfo;
else
case "$host" in
# *-*-aix*) zoneinfo_dir="/usr/share/lib/zoneinfo" ;;
*) zoneinfo_dir="/usr/share/zoneinfo" ;;
esac
with_libstdcxx_zoneinfo=yes
fi
if test "x${with_libstdcxx_zoneinfo}" = xyes; then
# Pick a default when no specific path is set.
case "$host" in
gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu)
# Not all distros ship tzdata.zi in this dir.
zoneinfo_dir="/usr/share/zoneinfo"
;;
*-*-aix*)
# Binary tzfile files are in /usr/share/lib/zoneinfo
# but tzdata.zi is not present there.
zoneinfo_dir=none
;;
*-*-darwin2*)
# Binary tzfile files are in /usr/share/lib/zoneinfo.default
# but tzdata.zi is not present there.
zoneinfo_dir=none
;;
*)
# Binary tzfile files are commonly found in /usr/share/zoneinfo
# but tzdata.zi is not present there.
zoneinfo_dir=none
;;
esac
# Also embed a copy of the tzdata.zi file as a static string.
embed_zoneinfo=yes
elif test "x${with_libstdcxx_zoneinfo}" = xno; then
# Disable tzdb support completely.
zoneinfo_dir=none
embed_zoneinfo=no
else
case "${with_libstdcxx_zoneinfo}" in
static)
# Do not attempt to read from disk, always use embedded data.
zoneinfo_dir=none
embed_zoneinfo=yes
;;
static,* | *,static)
# Try to read from disk, use embedded data as fallback.
zoneinfo_dir="${with_libstdcxx_zoneinfo#static,}"
zoneinfo_dir="${with_libstdcxx_zoneinfo%,static}"
embed_zoneinfo=yes
;;
*)
zoneinfo_dir="${with_libstdcxx_zoneinfo}"
embed_zoneinfo=no
;;
esac
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: zoneinfo data directory: ${zoneinfo_dir}" >&5
$as_echo "$as_me: zoneinfo data directory: ${zoneinfo_dir}" >&6;}
if test "x${zoneinfo_dir}" != xnone; then
cat >>confdefs.h <<_ACEOF
#define _GLIBCXX_ZONEINFO_DIR "${zoneinfo_dir}"
_ACEOF
if $GLIBCXX_IS_NATIVE -a ! test -f "$zoneinfo_dir/tzdata.zi"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"$zoneinfo_dir does not contain tzdata.zi file\"" >&5
$as_echo "$as_me: WARNING: \"$zoneinfo_dir does not contain tzdata.zi file\"" >&2;}
fi
fi
if test "x${embed_zoneinfo}" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: static tzdata.zi file will be compiled into the library" >&5
$as_echo "$as_me: static tzdata.zi file will be compiled into the library" >&6;}
cat >>confdefs.h <<_ACEOF
#define _GLIBCXX_STATIC_TZDATA 1
_ACEOF
fi
# Define documentation rules conditionally.
@ -72365,6 +72427,15 @@ else
fi
if test "${embed_zoneinfo}" = yes; then
USE_STATIC_TZDATA_TRUE=
USE_STATIC_TZDATA_FALSE='#'
else
USE_STATIC_TZDATA_TRUE='#'
USE_STATIC_TZDATA_FALSE=
fi
cat >confcache <<\_ACEOF
@ -72882,6 +72953,10 @@ if test -z "${ENABLE_BACKTRACE_TRUE}" && test -z "${ENABLE_BACKTRACE_FALSE}"; th
as_fn_error $? "conditional \"ENABLE_BACKTRACE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${USE_STATIC_TZDATA_TRUE}" && test -z "${USE_STATIC_TZDATA_FALSE}"; then
as_fn_error $? "conditional \"USE_STATIC_TZDATA\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then
as_fn_error $? "conditional \"BUILD_INFO\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5

View file

@ -279,4 +279,25 @@
</p></dd><dt><span class="term"><code class="code">--with-libstdcxx-eh-pool-obj-count=NUM</code></span></dt><dd><p>Set the size of the emergency exception handling pool. NUM is the
number of simultaneous allocated exceptions to support.
This does not change the library ABI.
</p></dd><dt><span class="term"><code class="code">--with-libstdcxx-zoneinfo=OPTION</code></span></dt><dd><p>Choose how <code class="classname">std::chrono::tzdb</code> will obtain
the time zone info. The library requires a copy of the
<code class="filename">tzdata.zi</code> and <code class="filename">leapseconds</code>
files from the <a class="link" href="https://www.iana.org/time-zones" target="_top">IANA Time Zone
Database</a>. The choice OPTION=static will embed a copy of the files
into the library, and use that static data when time zone information
is required. The choice OPTION=dir will use the files
<code class="filename">dir/tzdata.zi</code> and
<code class="filename">dir/leapseconds</code> (which must exist when a program
tries to access time zone information). The choice OPTION=dir,static
will try to use files in <code class="filename">dir</code> but if they are
not available the embedded static data will be used instead.
The default choice is OPTION=yes. This is equivalent to OPTION=dir,static
with a system-specific default directory (if a suitable default for
the target is known).
The choice OPTION=no will disable all code for loading time zone info
from file or from the embedded static data, which means that only the
"UTC" and "GMT" time zones are defined. Using OPTION=no results in a
smaller library, so is suitable for systems that will never need to
query the time zone database.
This does not change the library ABI.
</p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="setup.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="setup.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="make.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. Setup </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Make</td></tr></table></div></body></html>

View file

@ -469,6 +469,33 @@
</para>
</listitem></varlistentry>
<varlistentry><term><code>--with-libstdcxx-zoneinfo=OPTION</code></term>
<listitem>
<para>Choose how <classname>std::chrono::tzdb</classname> will obtain
the time zone info. The library requires a copy of the
<filename>tzdata.zi</filename> and <filename>leapseconds</filename>
files from the <link xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="https://www.iana.org/time-zones">IANA Time Zone
Database</link>. The choice OPTION=static will embed a copy of the files
into the library, and use that static data when time zone information
is required. The choice OPTION=dir will use the files
<filename>dir/tzdata.zi</filename> and
<filename>dir/leapseconds</filename> (which must exist when a program
tries to access time zone information). The choice OPTION=dir,static
will try to use files in <filename>dir</filename> but if they are
not available the embedded static data will be used instead.
The default choice is OPTION=yes. This is equivalent to OPTION=dir,static
with a system-specific default directory (if a suitable default for
the target is known).
The choice OPTION=no will disable all code for loading time zone info
from file or from the embedded static data, which means that only the
"UTC" and "GMT" time zones are defined. Using OPTION=no results in a
smaller library, so is suitable for systems that will never need to
query the time zone database.
This does not change the library ABI.
</para>
</listitem></varlistentry>
</variablelist>
</section>

View file

@ -40,6 +40,19 @@ sources = tzdb.cc
vpath % $(top_srcdir)/src/c++20
if USE_STATIC_TZDATA
tzdata.zi.h: $(top_srcdir)/src/c++20/tzdata.zi
echo 'static const char tzdata_chars[] = R"__libstdcxx__(' > $@.tmp
cat $^ >> $@.tmp
echo ')__libstdcxx__";' >> $@.tmp
mv $@.tmp $@
tzdb.lo: tzdb.cc tzdata.zi.h
$(LTCXXCOMPILE) -I. -c $<
tzdb.o: tzdb.cc tzdata.zi.h
$(CXXCOMPILE) -I. -c $<
endif
libc__20convenience_la_SOURCES = $(sources) $(inst_sources)
# AM_CXXFLAGS needs to be in each subdirectory so that it can be

View file

@ -742,6 +742,17 @@ uninstall-am:
vpath % $(top_srcdir)/src/c++20
@USE_STATIC_TZDATA_TRUE@tzdata.zi.h: $(top_srcdir)/src/c++20/tzdata.zi
@USE_STATIC_TZDATA_TRUE@ echo 'static const char tzdata_chars[] = R"__libstdcxx__(' > $@.tmp
@USE_STATIC_TZDATA_TRUE@ cat $^ >> $@.tmp
@USE_STATIC_TZDATA_TRUE@ echo ')__libstdcxx__";' >> $@.tmp
@USE_STATIC_TZDATA_TRUE@ mv $@.tmp $@
@USE_STATIC_TZDATA_TRUE@tzdb.lo: tzdb.cc tzdata.zi.h
@USE_STATIC_TZDATA_TRUE@ $(LTCXXCOMPILE) -I. -c $<
@USE_STATIC_TZDATA_TRUE@tzdb.o: tzdb.cc tzdata.zi.h
@USE_STATIC_TZDATA_TRUE@ $(CXXCOMPILE) -I. -c $<
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

File diff suppressed because it is too large Load diff

View file

@ -60,10 +60,6 @@
# endif
#endif
#ifndef _GLIBCXX_ZONEINFO_DIR
# define _GLIBCXX_ZONEINFO_DIR "/usr/share/zoneinfo"
#endif
namespace __gnu_cxx
{
#ifdef _AIX
@ -75,7 +71,13 @@ namespace __gnu_cxx
#if defined(__APPLE__) || defined(__hpux__)
// Need a weak definition for Mach-O.
[[gnu::weak]] const char* zoneinfo_dir_override()
{ return _GLIBCXX_ZONEINFO_DIR; }
{
#ifdef _GLIBCXX_ZONEINFO_DIR
return _GLIBCXX_ZONEINFO_DIR;
#else
return nullptr;
#endif
}
#endif
#endif
}
@ -1008,22 +1010,83 @@ namespace std::chrono
return info;
}
namespace
{
namespace
{
// If a zoneinfo directory is defined (either when the library was built,
// or via the zoneinfo_dir_override function) then append filename to it.
// The filename should have a leading '/' as one is not added explicitly.
string
zoneinfo_dir()
zoneinfo_file(string_view filename)
{
string path;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Waddress"
static const string dir = __gnu_cxx::zoneinfo_dir_override
? __gnu_cxx::zoneinfo_dir_override()
: _GLIBCXX_ZONEINFO_DIR;
if (__gnu_cxx::zoneinfo_dir_override)
{
if (auto override_dir = __gnu_cxx::zoneinfo_dir_override())
path = override_dir;
#pragma GCC diagnostic pop
return dir;
}
#ifdef _GLIBCXX_ZONEINFO_DIR
else
path = _GLIBCXX_ZONEINFO_DIR;
#endif
if (!path.empty())
path.append(filename);
return path;
}
// N.B. Leading slash as required by zoneinfo_file function.
const string tzdata_file = "/tzdata.zi";
const string leaps_file = "/leapseconds";
#ifdef _GLIBCXX_STATIC_TZDATA
// Static copy of tzdata.zi embedded in the library as tzdata_chars[]
#include "tzdata.zi.h"
#endif
// An istream type that can read from a file or from a string.
struct tzdata_stream : istream
{
// std::spanbuf not available until C++23
struct ispanbuf : streambuf
{
ispanbuf() : streambuf()
{
#ifdef _GLIBCXX_STATIC_TZDATA
char* p = const_cast<char*>(tzdata_chars);
this->setg(p, p, p + std::size(tzdata_chars) - 1);
#endif
}
// N.B. seekoff and seekpos not overridden, not currently needed.
};
union {
filebuf fb;
ispanbuf sb;
};
tzdata_stream() : istream(nullptr)
{
if (string path = zoneinfo_file("/tzdata.zi"); !path.empty())
{
filebuf fbuf;
if (fbuf.open(path, std::ios::in))
{
std::construct_at(&fb, std::move(fbuf));
this->init(&fb);
return;
}
}
std::construct_at(&sb);
this->init(&sb);
}
~tzdata_stream() { std::destroy_at(this->rdbuf()); } // use virtual dtor
bool using_static_data() const { return this->rdbuf() == &sb; }
};
}
// Return leap_second values, and a bool indicating whether the values are
@ -1031,7 +1094,7 @@ namespace std::chrono
pair<vector<leap_second>, bool>
tzdb_list::_Node::_S_read_leap_seconds()
{
const string filename = zoneinfo_dir() + leaps_file;
const string filename = zoneinfo_file(leaps_file);
// This list is valid until at least 2023-06-28 00:00:00 UTC.
auto expires = sys_days{2023y/6/28};
@ -1127,31 +1190,25 @@ namespace std::chrono
namespace
{
// Read the version number from a tzdata.zi file.
// Note that some systems do not have this file available by default
// but we can configure the library to point to an alternate installation.
string
remote_version(istream* zif)
remote_version(istream& zif)
{
ifstream f;
if (!zif)
{
f.open(zoneinfo_dir() + tzdata_file);
zif = &f;
}
char hash;
string label;
string version;
if (*zif >> hash >> label >> version)
if (zif >> hash >> label >> version)
if (hash == '#' && label == "version")
return version;
#if 0 // Ignore these files, because we're not using them anyway.
#if defined __NetBSD__
if (string ver; ifstream(zoneinfo_dir() + "/TZDATA_VERSION") >> ver)
if (string ver; ifstream(zoneinfo_file("/TZDATA_VERSION")) >> ver)
return ver;
#elif defined __APPLE__
// The standard install on macOS has no tzdata.zi, but we can find the
// version from +VERSION.
if (string ver; ifstream(zoneinfo_dir() + "/+VERSION") >> ver)
if (string ver; ifstream(zoneinfo_file("/+VERSION")) >> ver)
return ver;
#endif
#endif
__throw_runtime_error("tzdb: no version found in tzdata.zi");
}
@ -1160,7 +1217,8 @@ namespace std::chrono
// Definition of std::chrono::remote_version()
string remote_version()
{
return remote_version(nullptr);
tzdata_stream zif;
return remote_version(zif);
}
// Used by chrono::reload_tzdb() to add a new node to the front of the list.
@ -1293,8 +1351,8 @@ namespace std::chrono
{
using Node = tzdb_list::_Node;
ifstream zif(zoneinfo_dir() + tzdata_file);
const string version = remote_version(&zif);
tzdata_stream zif;
const string version = remote_version(zif);
#if USE_ATOMIC_SHARED_PTR
auto head = Node::_S_head_owner.load(memory_order::acquire);
@ -1311,7 +1369,7 @@ namespace std::chrono
#endif
auto [leaps, leaps_ok] = Node::_S_read_leap_seconds();
if (!leaps_ok)
if (!leaps_ok && !zif.using_static_data())
__throw_runtime_error("tzdb: cannot parse leapseconds file");
auto node = std::make_shared<Node>();

View file

@ -1415,11 +1415,8 @@ proc check_effective_target_tzdb { } {
return 0
}
return [check_v3_target_prop_cached et_tzdb {
set cond "defined _GLIBCXX_ZONEINFO_DIR"
if {[v3_check_preprocessor_condition tzdb $cond]} {
return 1
}
return [file exists /usr/share/zoneinfo/tzdata.zi]
set cond "defined _GLIBCXX_ZONEINFO_DIR || _GLIBCXX_STATIC_TZDATA"
return [v3_check_preprocessor_condition tzdb $cond]
}]
}