aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/scripts/gen_windows_zones_map.py
blob: 7f547a760025462a5a40eb18724b560881d35c25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/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")