On Mon, 7 Jul 2025 at 21:26, Björn Schäpers <g...@hazardy.de> wrote:
>
> From: Björn Schäpers <bjo...@hazardy.de>
>
> Sorry for the noise, this is the current version of the Patch.
>
> -- >8 --
> Windows does not provide a tzdata.zi, but msys does. Use this, if
> available, instead of the embedded (and possibly outdated) database.
>
> libstdc++-v3/Changelog:
>
>         Use msys provided time zone information.
>
>         * src/c++20/tzdb.cc (zoneinfo_file): On Windows look relative
>         from the DLL path for the time zone information.
>
> Signed-off-by: Björn Schäpers <bjo...@hazardy.de>
> ---
>  libstdc++-v3/src/c++20/tzdb.cc | 35 ++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
>
> diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
> index 6e244dc656d..cdc487af3f5 100644
> --- a/libstdc++-v3/src/c++20/tzdb.cc
> +++ b/libstdc++-v3/src/c++20/tzdb.cc
> @@ -44,6 +44,12 @@
>  # include <cstdlib>   // getenv
>  #endif
>
> +#if _GLIBCXX_HAVE_WINDOWS_H
> +# define WIN32_LEAN_AND_MEAN
> +# include <windows.h>
> +# include <psapi.h>
> +#endif
> +
>  #if defined __GTHREADS && ATOMIC_POINTER_LOCK_FREE == 2
>  # define USE_ATOMIC_LIST_HEAD 1
>  // TODO benchmark atomic<shared_ptr<>> vs mutex.
> @@ -1144,6 +1150,35 @@ namespace std::chrono
>  #ifdef _GLIBCXX_ZONEINFO_DIR
>        else
>         path = _GLIBCXX_ZONEINFO_DIR;
> +#endif
> +#ifdef _GLIBCXX_HAVE_WINDOWS_H
> +      if (path.empty())
> +       {
> +         HMODULE dll_module;
> +         if (GetModuleHandleExA(
> +                 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
> +                     | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
> +                 reinterpret_cast<const char *>(&zoneinfo_file), 
> &dll_module))
> +           {
> +             char dll_path[MAX_PATH];
> +             if (GetModuleFileNameA(dll_module, dll_path, MAX_PATH) != 0)
> +               {
> +                 string_view dll_path_view = dll_path;
> +                 auto pos = dll_path_view.find_last_of('\\');
> +                 dll_path_view = dll_path_view.substr(0, pos);
> +                 if (dll_path_view.ends_with("\\bin"))
> +                   {
> +                     constexpr string_view remaining_path = 
> "share\\zoneinfo";
> +                     dll_path_view.remove_suffix(3); // Remove bin
> +                     path.resize(dll_path_view.size()
> +                                 + remaining_path.size());
> +                     auto iter
> +                         = ranges::copy(dll_path_view, path.begin()).out;
> +                     ranges::copy(remaining_path, iter);

Why not simply:

  path = dll_path_view;
  path += remaining_path;

?

> +                   }
> +               }
> +           }
> +       }
>  #endif
>        if (!path.empty())
>         path.append(filename);
> --
> 2.50.0
>

Reply via email to