| #!/usr/bin/env python3 |
| # |
| # Script to generate the map for libstdc++ std::chrono::current_zone under Windows. |
| # |
| # This file is part of GCC. |
| # |
| # GCC is free software; you can redistribute it and/or modify it under |
| # the terms of the GNU General Public License as published by the Free |
| # Software Foundation; either version 3, or (at your option) any later |
| # version. |
| # |
| # GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
| # WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| # for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with GCC; see the file COPYING3. If not see |
| # <http://www.gnu.org/licenses/>. |
| |
| # To update the Libstdc++ static data in src/c++20/windows_zones-map.h download the latest: |
| # https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml |
| # Then run this script and save the output to |
| # src/c++20/windows_zones-map.h |
| |
| import os |
| import sys |
| import xml.etree.ElementTree as et |
| |
| if len(sys.argv) != 2: |
| print("Usage: %s <windows zones xml>" % sys.argv[0], file=sys.stderr) |
| sys.exit(1) |
| |
| self = os.path.basename(__file__) |
| print("// Generated by scripts/{}, do not edit.".format(self)) |
| print(""" |
| // Copyright The GNU Toolchain Authors. |
| // |
| // This file is part of the GNU ISO C++ Library. This library is free |
| // software; you can redistribute it and/or modify it under the |
| // terms of the GNU General Public License as published by the |
| // Free Software Foundation; either version 3, or (at your option) |
| // any later version. |
| |
| // This library is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU General Public License for more details. |
| |
| // Under Section 7 of GPL version 3, you are granted additional |
| // permissions described in the GCC Runtime Library Exception, version |
| // 3.1, as published by the Free Software Foundation. |
| |
| // You should have received a copy of the GNU General Public License and |
| // a copy of the GCC Runtime Library Exception along with this program; |
| // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
| // <http://www.gnu.org/licenses/>. |
| |
| """) |
| |
| class WindowsZoneMapEntry: |
| def __init__(self, windows, territory, iana): |
| self.windows = windows |
| self.territory = territory |
| self.iana = iana |
| |
| def __lt__(self, other): |
| return (self.windows, self.territory) < (other.windows, other.territory) |
| |
| windows_zone_map = [] |
| |
| tree = et.parse(sys.argv[1]) |
| xml_zone_map = tree.getroot().find("windowsZones").find("mapTimezones") |
| |
| for entry in xml_zone_map.iter("mapZone"): |
| iana = entry.attrib["type"] |
| space = iana.find(" ") |
| if space != -1: |
| iana = iana[0:space] |
| windows_zone_map.append(WindowsZoneMapEntry(entry.attrib["other"], entry.attrib["territory"], iana)) |
| |
| # Sort so we can use binary search on the array. |
| windows_zone_map.sort() |
| |
| # Skip territories which have the same IANA zone as 001, so we can reduce the data. |
| last_windows_zone = "" |
| for entry in windows_zone_map[:]: |
| if entry.windows != last_windows_zone: |
| if entry.territory != "001": |
| raise ValueError('Territory "001" not the first one, this breaks assumptions in tzdb.cc!') |
| last_windows_zone = entry.windows |
| fallback_iana = entry.iana |
| else: |
| if entry.iana == fallback_iana: |
| windows_zone_map.remove(entry) |
| |
| print("""struct windows_zone_map_entry |
| {{ |
| wstring_view windows_name; |
| wstring_view territory; |
| string_view iana_name; |
| }}; |
| |
| static constexpr array<windows_zone_map_entry, {}> windows_zone_map{{ |
| {{""".format(len(windows_zone_map))) |
| |
| for entry in windows_zone_map: |
| print(' {{L"{}", L"{}", "{}"}},'.format(entry.windows, entry.territory, entry.iana)) |
| |
| print(""" } |
| };""") |
| |
| # src/c++20/tzdb.cc gives an error if this macro is not defined. |
| # Do this last, so that the generated output is not usable unless we reach here. |
| print("\n#define _GLIBCXX_WINDOWS_ZONES_MAP_COMPLETE") |