| #!/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") |