1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

make_unicode: Generate the time zone registry keys.

Based on a script written by Giovanni Mascellani.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2022-06-24 10:54:22 +02:00
parent 630f605c26
commit 3ec7c467cd
54 changed files with 69539 additions and 68593 deletions

View file

@ -949,8 +949,6 @@ static void test_GetTimeZoneInformationForYear(void)
USHORT year;
LONG bias, std_bias, dlt_bias;
WORD std_month, std_day, dlt_month, dlt_day;
int tzinfo_todo : 1, bias_todo : 1, std_bias_todo : 1, dlt_bias_todo : 1;
int std_month_todo : 1, std_day_todo : 1, dlt_month_todo : 1, dlt_day_todo : 1;
}
test_data[] =
{
@ -961,10 +959,10 @@ static void test_GetTimeZoneInformationForYear(void)
{ L"Easter Island Standard Time", 2015, 300, 0, -60, 0, 0, 0, 0 },
{ L"Easter Island Standard Time", 2016, 360, 0, -60, 5, 14, 8, 13 },
{ L"Egypt Standard Time", 2013, -120, 0, -60, 0, 0, 0, 0 },
{ L"Egypt Standard Time", 2014, -120, 0, -60, 9, 25, 5, 15, 0, 0, 0, 0, 0, 1, 0, 1 },
{ L"Egypt Standard Time", 2014, -120, 0, -60, 9, 25, 5, 15 },
{ L"Egypt Standard Time", 2015, -120, 0, -60, 0, 0, 0, 0 },
{ L"Egypt Standard Time", 2016, -120, 0, -60, 0, 0, 0, 0 },
{ L"Altai Standard Time", 2016, -420, 0, 60, 3, 27, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1 },
{ L"Altai Standard Time", 2016, -420, 0, 60, 3, 27, 1, 1 },
{ L"Altai Standard Time", 2017, -420, 0, -60, 0, 0, 0, 0 },
{ L"Altai Standard Time", 2018, -420, 0, -60, 0, 0, 0, 0 },
};
@ -1038,33 +1036,25 @@ static void test_GetTimeZoneInformationForYear(void)
dyn_tzinfo.DynamicDaylightTimeDisabled = FALSE;
ret = pGetTimeZoneInformationForYear(test_data[i].year, &dyn_tzinfo, &tzinfo);
todo_wine_if(test_data[i].tzinfo_todo)
ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %lu, for %s\n", GetLastError(), wine_dbgstr_w(test_data[i].tzname));
ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %lu, for %s\n", GetLastError(), wine_dbgstr_w(test_data[i].tzname));
if (!ret)
continue;
todo_wine_if(test_data[i].bias_todo)
ok(tzinfo.Bias == test_data[i].bias, "Expected bias %ld, got %ld, for %s\n",
test_data[i].bias, tzinfo.Bias, wine_dbgstr_w(test_data[i].tzname));
todo_wine_if(test_data[i].std_month_todo)
ok(tzinfo.StandardDate.wMonth == test_data[i].std_month, "Expected standard month %d, got %d, for %s\n",
test_data[i].std_month, tzinfo.StandardDate.wMonth, wine_dbgstr_w(test_data[i].tzname));
ok(tzinfo.Bias == test_data[i].bias, "Expected bias %ld, got %ld, for %s\n",
test_data[i].bias, tzinfo.Bias, wine_dbgstr_w(test_data[i].tzname));
ok(tzinfo.StandardDate.wMonth == test_data[i].std_month, "Expected standard month %d, got %d, for %s\n",
test_data[i].std_month, tzinfo.StandardDate.wMonth, wine_dbgstr_w(test_data[i].tzname));
std_day = day_of_month(&tzinfo.StandardDate, test_data[i].year);
todo_wine_if(test_data[i].std_day_todo)
ok(std_day == test_data[i].std_day, "Expected standard day %d, got %d, for %s\n",
test_data[i].std_day, std_day, wine_dbgstr_w(test_data[i].tzname));
todo_wine_if(test_data[i].std_bias_todo)
ok(tzinfo.StandardBias == test_data[i].std_bias, "Expected standard bias %ld, got %ld, for %s\n",
test_data[i].std_bias, tzinfo.StandardBias, wine_dbgstr_w(test_data[i].tzname));
todo_wine_if(test_data[i].dlt_month_todo)
ok(tzinfo.DaylightDate.wMonth == test_data[i].dlt_month, "Expected daylight month %d, got %d, for %s\n",
test_data[i].dlt_month, tzinfo.DaylightDate.wMonth, wine_dbgstr_w(test_data[i].tzname));
ok(std_day == test_data[i].std_day, "Expected standard day %d, got %d, for %s\n",
test_data[i].std_day, std_day, wine_dbgstr_w(test_data[i].tzname));
ok(tzinfo.StandardBias == test_data[i].std_bias, "Expected standard bias %ld, got %ld, for %s\n",
test_data[i].std_bias, tzinfo.StandardBias, wine_dbgstr_w(test_data[i].tzname));
ok(tzinfo.DaylightDate.wMonth == test_data[i].dlt_month, "Expected daylight month %d, got %d, for %s\n",
test_data[i].dlt_month, tzinfo.DaylightDate.wMonth, wine_dbgstr_w(test_data[i].tzname));
dlt_day = day_of_month(&tzinfo.DaylightDate, test_data[i].year);
todo_wine_if(test_data[i].dlt_day_todo)
ok(dlt_day == test_data[i].dlt_day, "Expected daylight day %d, got %d, for %s\n",
test_data[i].dlt_day, dlt_day, wine_dbgstr_w(test_data[i].tzname));
todo_wine_if(test_data[i].dlt_bias_todo)
ok(tzinfo.DaylightBias == test_data[i].dlt_bias, "Expected daylight bias %ld, got %ld, for %s\n",
test_data[i].dlt_bias, tzinfo.DaylightBias, wine_dbgstr_w(test_data[i].tzname));
ok(dlt_day == test_data[i].dlt_day, "Expected daylight day %d, got %d, for %s\n",
test_data[i].dlt_day, dlt_day, wine_dbgstr_w(test_data[i].tzname));
ok(tzinfo.DaylightBias == test_data[i].dlt_bias, "Expected daylight bias %ld, got %ld, for %s\n",
test_data[i].dlt_bias, tzinfo.DaylightBias, wine_dbgstr_w(test_data[i].tzname));
if (i > 0 && test_data[i-1].tzname == test_data[i].tzname)
{

File diff suppressed because it is too large Load diff

View file

@ -1,22 +1,4 @@
/*
* Time zone resources
*
* Copyright 2018 Akihiro Sagawa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Automatically generated; DO NOT EDIT!! */
#include "winresrc.h"

File diff suppressed because it is too large Load diff

4356
po/ar.po

File diff suppressed because it is too large Load diff

814
po/ast.po

File diff suppressed because it is too large Load diff

3566
po/bg.po

File diff suppressed because it is too large Load diff

814
po/ca.po

File diff suppressed because it is too large Load diff

4356
po/cs.po

File diff suppressed because it is too large Load diff

4356
po/da.po

File diff suppressed because it is too large Load diff

814
po/de.po

File diff suppressed because it is too large Load diff

3566
po/el.po

File diff suppressed because it is too large Load diff

814
po/en.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

4356
po/eo.po

File diff suppressed because it is too large Load diff

814
po/es.po

File diff suppressed because it is too large Load diff

4058
po/fa.po

File diff suppressed because it is too large Load diff

814
po/fi.po

File diff suppressed because it is too large Load diff

1282
po/fr.po

File diff suppressed because it is too large Load diff

4358
po/he.po

File diff suppressed because it is too large Load diff

3566
po/hi.po

File diff suppressed because it is too large Load diff

4356
po/hr.po

File diff suppressed because it is too large Load diff

4356
po/hu.po

File diff suppressed because it is too large Load diff

4356
po/it.po

File diff suppressed because it is too large Load diff

814
po/ja.po

File diff suppressed because it is too large Load diff

814
po/ko.po

File diff suppressed because it is too large Load diff

814
po/lt.po

File diff suppressed because it is too large Load diff

3566
po/ml.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

814
po/nl.po

File diff suppressed because it is too large Load diff

3566
po/or.po

File diff suppressed because it is too large Load diff

3566
po/pa.po

File diff suppressed because it is too large Load diff

814
po/pl.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3566
po/rm.po

File diff suppressed because it is too large Load diff

4356
po/ro.po

File diff suppressed because it is too large Load diff

814
po/ru.po

File diff suppressed because it is too large Load diff

912
po/si.po

File diff suppressed because it is too large Load diff

4522
po/sk.po

File diff suppressed because it is too large Load diff

4356
po/sl.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

4356
po/sv.po

File diff suppressed because it is too large Load diff

3566
po/ta.po

File diff suppressed because it is too large Load diff

3566
po/te.po

File diff suppressed because it is too large Load diff

4058
po/th.po

File diff suppressed because it is too large Load diff

954
po/tr.po

File diff suppressed because it is too large Load diff

814
po/uk.po

File diff suppressed because it is too large Load diff

4058
po/wa.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -21,7 +21,9 @@
use strict;
use XML::LibXML;
use Digest::SHA;
use Encode;
use Time::Local qw(timegm_modern);
# base URLs for www.unicode.org files
my $UNIVERSION = "14.0.0";
@ -40,6 +42,9 @@ my $CLDR33DATA = "https://www.unicode.org/Public/cldr/33/cldr-common-33.0.zip";
my $ISO639VERSION = "20220120";
my $ISO639 = "https://iso639-3.sil.org/sites/iso639-3/files/downloads/iso-639-3_Code_Tables_$ISO639VERSION.zip";
my $TZVERSION = "2022a";
my $TZDATA = "https://data.iana.org/time-zones/releases/tzdata$TZVERSION.tar.gz";
# Default char for undefined mappings
my $DEF_CHAR = ord '?';
@ -47,6 +52,7 @@ my $DEF_CHAR = ord '?';
my $MAX_CHAR = 0x10ffff;
my $nlskey = "-SYSTEM\\-CurrentControlSet\\-Control\\-Nls";
my $zonekey = "-Software\\-Microsoft\\-Windows NT\\-CurrentVersion\\Time Zones";
my @allfiles =
(
@ -118,6 +124,7 @@ my @allfiles =
"CodpageFiles/28605.txt",
);
my @timezone_files = qw(africa antarctica asia australasia europe northamerica southamerica etcetera backward);
my %ctype =
(
@ -1889,6 +1896,17 @@ sub open_data_file($$)
}
open FILE, "-|", "unzip", "-p", "$cache/$zip", $name or die "cannot extract $name from $zip";
}
elsif ($base =~ /.*\/([^\/]+)\.tar\.gz$/)
{
my $tar = "$1$suffix.tar.gz";
unless (-f "$cache/$tar")
{
system "mkdir", "-p", $cache;
print "Fetching $base...\n";
!system "wget", "-q", "-O", "$cache/$tar", $base or die "cannot fetch $base";
}
open FILE, "-|", "tar", "-x", "-f", "$cache/$tar", "-O", $name or die "cannot extract $name from $tar";
}
else
{
(my $dest = "$cache/$name") =~ s/(.*)(\.[^\/.]+)$/$1$suffix$2/;
@ -5284,6 +5302,423 @@ sub dump_locales($$)
}
################################################################
# return the day of week of the first of the month
sub month_first_dow($$)
{
my ($year, $month) = @_;
my @time = gmtime( timegm_modern( 0, 0, 0, 1, $month - 1, $year ));
return $time[6];
}
################################################################
# compare system time values
sub compare_systime($$)
{
my ($a, $b) = @_;
return $a->[0] <=> $b->[0] ||
$a->[1] <=> $b->[1] ||
$a->[2] <=> $b->[2] ||
$a->[3] <=> $b->[3] ||
$a->[4] <=> $b->[4] ||
$a->[5] <=> $b->[5] ||
$a->[6] <=> $b->[6];
}
################################################################
# compare the zone transition date with the rule date
sub compare_transition_date($$$$)
{
my ($stdoff, $isdst, $zone, $rule) = @_;
if (scalar @{$zone} <= 1)
{
return (!defined($zone->[0]) || $zone->[0] > $rule->[0]) ? 1 : -1;
}
my @date = parse_transition_date( $stdoff, $isdst, $zone->[0], $zone->[1], $zone->[2], $zone->[3] || 0 );
return compare_systime( \@date, $rule );
}
################################################################
# get the Windows zone names from the CLDR data
sub load_windows_zones()
{
my $current_name;
my %names;
my $base = "cldr-release-$CLDRVERSION";
my $INPUT = open_data_file( $CLDRDATA, "$base/common/supplemental/windowsZones.xml" );
while (<$INPUT>)
{
if (/<!-- +(\(UTC.*) -->.*/)
{
$current_name = $1;
}
if (/<mapZone other="(.*)" territory="001" type="(.*)"\/>/)
{
$names{$1} = [ $current_name, $2 ];
}
}
close $INPUT;
return %names;
}
################################################################
# parse a transition date specification from the tzdata files
sub parse_transition_date($$@)
{
use integer;
my ($stdoff, $isdst, $year, $in, $on, $at) = @_;
$on = "1" unless defined $on;
$at = "0" unless defined $at;
my %months = ( Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6,
Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12 );
my %days = ( Sun => 0, Mon => 1, Tue => 2, Wed => 3, Thu => 4, Fri => 5, Sat => 6 );
my $mon = $in ? $months{$in} : 1;
my ($week, $dow, $flag, $time, $sec);
my $first = month_first_dow( $year, $mon );
if ($on =~ /^last(.*)$/)
{
$week = 5;
$dow = $days{$1};
}
elsif ($on =~ /^(.*)>=(\d+)$/)
{
$dow = $days{$1};
my $diff = ($first + 6 - $dow) % 7;
$week = $2 >= 25 ? 5 : ($2 + 6 + $diff) / 7;
}
elsif ($on =~ /^(.*)<=(\d+)$/)
{
$dow = $days{$1};
my $diff = ($first + $2 + 6 - $dow) % 7;
$week = ($2 + 6 - $diff) / 7;
if (!$week)
{
$week = 5;
if (!--$mon) { $mon = 12; $year--; }
}
}
elsif ($on =~ /^\d+$/)
{
$dow = ($first + $on - 1) % 7;
$week = $on >= 25 ? 5 : ($on + 6) / 7;
}
else
{
die "unsupported date specification $year $in $on $at";
}
if ($at =~ /^(\d+):(\d+):(\d+)([uws]?)$/)
{
$time = $1 * 60 + $2;
$sec = $3;
$flag = $4;
}
elsif ($at =~ /^(\d+):(\d+)([uws]?)$/)
{
$time = $1 * 60 + $2;
$flag = $3;
}
elsif ($at =~ /^(\d+)([uws]?)$/)
{
$time = $1 * 60;
$flag = $2;
}
else
{
die "unsupported time specification $year $in $on $at";
}
$flag ||= "w";
$time -= $stdoff if $flag eq "u";
$time += 60 if !$isdst && $flag ne "w";
if ($time < 0) # previous day
{
$week-- if $week < 5 && $dow == month_first_dow( $year, $mon );
$week-- if $week == 5 && $dow == month_first_dow( $year + ($mon == 12), $mon % 12 + 1 );
if (!$week)
{
$week = 5;
if (!--$mon) { $mon = 12; $year--; }
}
$dow = ($dow + 6) % 7;
$time += 24 * 60;
}
return ($year, $mon, $week, $dow, $time / 60, $time % 60, $sec || 0);
}
################################################################
# parse a system time value as a SYSTEMTIME structure
sub pack_systime(@)
{
my ($year, $mon, $week, $dow, $hour, $min, $sec) = @_;
return pack "S<8", 0, $mon, $dow, $week, $hour < 24 ? ($hour, $min, $sec, 0) : (23, 59, 59, 999);
}
################################################################
# parse a timezone offset from the tzdata files
sub parse_tz_offset($)
{
my ($hour, $min) = split /:/, shift;
$min ||= 0;
return $hour < 0 ? -$hour * 60 + $min : -$hour * 60 - $min; # invert sign
}
################################################################
# build the timezone data
sub dump_timezones($@)
{
my $filename = shift;
my $FIRST_YEAR = 2000;
my $LAST_YEAR = 2030;
my %names = load_windows_zones();
my %zones;
my %rules;
my %links;
my %res_indices;
printf "Building $filename\n";
open OUTPUT, ">$filename.new" or die "Cannot create $filename";
print OUTPUT "/* Automatically generated; DO NOT EDIT!! */\n\n";
print OUTPUT "#include \"winresrc.h\"\n\n";
print OUTPUT "#pragma makedep po\n\n";
print OUTPUT "LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\n\n";
print OUTPUT "STRINGTABLE\n{\n";
# load tzdata files
foreach my $filename (@_)
{
my $FILE = open_data_file( $TZDATA, $filename );
my $zonename;
while (<$FILE>)
{
chomp;
s/\#.*$//;
next if /^\s*$/;
my @fields = split /\s+/;
if ($fields[0] eq "Zone" || ($zonename && $fields[0] eq ""))
{
shift @fields;
$zonename = shift @fields unless $zonename;
my ($stdoff, $rules, $dummy, @date) = @fields;
$zones{$zonename} ||= [ ];
push @{$zones{$zonename}}, [ parse_tz_offset( $stdoff ), $rules, @date ];
$zonename = undef unless @date; # last entry doesn't have an until date
next;
}
if ($fields[0] eq "Rule")
{
shift @fields;
my ($rulename, $from, $to, $dummy, $in, $on, $at, $save) = @fields;
$to = $from if $to eq "only";
$to = $LAST_YEAR if $to eq "max";
push @{$rules{$rulename}}, [ parse_tz_offset( $save ), $from, $to, $in, $on, $at ];
next;
}
if ($fields[0] eq "Link")
{
$links{$fields[2]} = $fields[1];
next;
}
die "unrecognized line $_";
}
close $FILE;
}
foreach my $name (sort { uc($a) cmp uc($b) } keys %names)
{
my ($display, $zone) = @{$names{$name}};
$zone = $links{$zone} if defined $links{$zone};
# build list of transitions
my @transitions;
my @from_date = ( 1 );
my $last_stdoff = 0;
for (my $i = 0; $i < scalar @{$zones{$zone}}; $i++)
{
my ($stdoff, $rule, @until_date) = @{$zones{$zone}->[$i]};
my $isdst = ($last_stdoff != $stdoff);
$from_date[0] ||= $LAST_YEAR;
my @systime = parse_transition_date( $stdoff, $isdst, @from_date );
push @transitions, [ $stdoff, -1, \@systime ];
if (defined $rules{$rule})
{
foreach my $r (@{$rules{$rule}})
{
my ($offset, $from, $to, $in, $on, $at) = @{$r};
foreach my $year ($from..$to)
{
next if $year < $from_date[0];
next if $until_date[0] && $year > $until_date[0];
my @systime = parse_transition_date( $stdoff, !!$offset, $year, $in, $on, $at );
next if compare_transition_date( $stdoff, $isdst, \@until_date, \@systime ) <= 0;
my $ret = compare_transition_date( $stdoff, $isdst, \@from_date, \@systime );
next if $ret > 0;
pop @transitions if !$ret; # remove transition if there's a dst change at the same time
push @transitions, [ $stdoff, $offset, \@systime ];
}
}
}
@from_date = @until_date;
$last_stdoff = $stdoff;
}
@transitions = sort { compare_systime( $a->[2], $b->[2] ) } @transitions;
# build per-year dynamic info
my @info;
my $last_dstoff = 0;
my $last_dst = 0;
my $year = $FIRST_YEAR;
while ($year <= $LAST_YEAR)
{
if (@transitions && $transitions[0]->[2]->[0] < $year)
{
$last_stdoff = $transitions[0]->[0];
shift @transitions;
next;
}
my ($std, $dst, @trans);
my $cur_stdoff = $last_stdoff;
my $cur_dstoff = ($name =~ /^UTC/) ? 0 : -60;
while (@transitions && $transitions[0]->[2]->[0] == $year)
{
my $t = shift @transitions;
my ($stdoff, $dstoff, $systime) = @{$t};
$systime = pack_systime( @{$systime} );
if (!$dstoff) # std
{
$cur_stdoff = $stdoff unless $std;
$std = $systime;
}
elsif ($dstoff != -1) # dst
{
$cur_dstoff = $dstoff unless $dst;
$dst ||= $systime;
}
elsif ($stdoff != $last_stdoff) # rule transition
{
# Handle a special case: Samoa moved to the other side of
# the date line between 2011-12-03 and 2012-01-01,
# entirely skipping the day 2011-12-31. We ignore this
# change because it happens on a year boundary and more
# importantly it would generate on offset of -25 hours,
# which some programs (e.g., Mono) do not like. See
# https://bugs.winehq.org/show_bug.cgi?id=51758
if ($last_stdoff - $stdoff < 24 * 60)
{
@trans = ($last_stdoff, $stdoff, $systime);
$cur_stdoff = $stdoff;
}
}
elsif ($dst) # rule transition with no stdoff change
{
$std = $systime;
}
$last_dstoff = ($dstoff == -1) ? 0 : $dstoff;
}
$last_stdoff = $cur_stdoff;
if ($cur_dstoff > 0) # swap std and dst to ensure that offset is negative
{
($std, $dst) = ($dst, $std);
$cur_stdoff += $cur_dstoff;
$cur_dstoff = -$cur_dstoff;
}
if (@trans)
{
# heuristic to prefer switching dst
if ($last_dst == $year - 1 || (!$last_dst && $trans[0] > $trans[1]))
{
$dst ||= $trans[2];
$cur_stdoff = $trans[0];
$cur_dstoff = $trans[1] - $trans[0];
}
else
{
$std ||= $trans[2];
$cur_stdoff = $trans[1];
$cur_dstoff = $trans[0] - $trans[1];
}
}
if ($std || $dst)
{
$std ||= pack_systime( parse_transition_date( 0, 0, $year, "Jan", 1 ));
$dst ||= pack_systime( parse_transition_date( 0, 0, $year, "Jan", 1 ));
$last_dst = $year;
}
else
{
$std = pack "S<8", 0;
$dst = pack "S<8", 0;
$cur_stdoff += $last_dstoff;
}
$info[$year++] = pack( "l<3", $cur_stdoff, 0, $cur_dstoff ) . $std . $dst;
}
# output registry keys
my $std_name = $name eq "UTC" ? "Coordinated Universal Time" : $name;
my $dlt_name = $std_name =~ s/Standard Time/Daylight Time/r;
my $res_idx = hex( substr( Digest::SHA::sha1_hex($name), -3, 3 )) << 4;
$res_idx += 16 while exists $res_indices{$res_idx};
$res_indices{$res_idx} = 1;
add_registry_string_value( $zonekey, $name, "Display", $display );
add_registry_string_value( $zonekey, $name, "Std", $std_name );
add_registry_string_value( $zonekey, $name, "Dlt", $dlt_name );
add_registry_string_value( $zonekey, $name, "MUI_Std", sprintf( "\@tzres.dll,-%u", $res_idx ));
add_registry_string_value( $zonekey, $name, "MUI_Dlt", sprintf( "\@tzres.dll,-%u", $res_idx + 1 ));
add_registry_string_value( $zonekey, $name, "MUI_Display", sprintf( "\@tzres.dll,-%u", $res_idx + 2 ));
add_registry_binary_value( $zonekey, $name, "TZI", $info[$LAST_YEAR] );
printf OUTPUT "%7d \"#msgctxt#maximum 31 characters#%s\"\n", $res_idx, $std_name;
printf OUTPUT "%7d \"#msgctxt#maximum 31 characters#%s\"\n", $res_idx + 1, $dlt_name;
printf OUTPUT "%7d \"%s\"\n", $res_idx + 2, $display;
my $first_year = $FIRST_YEAR;
my $last_year = $LAST_YEAR;
$last_year-- while $last_year > $FIRST_YEAR && $info[$last_year] eq $info[$last_year - 1];
$first_year++ while $first_year < $last_year && $info[$first_year] eq $info[$last_year];
next if $last_year <= $first_year;
foreach my $i ($first_year..$last_year)
{
add_registry_binary_value( $zonekey, "$name\\Dynamic DST", $i, $info[$i] );
}
add_registry_dword_value( $zonekey, "$name\\Dynamic DST", "FirstEntry", $first_year );
add_registry_dword_value( $zonekey, "$name\\Dynamic DST", "LastEntry", $last_year );
}
print OUTPUT "}\n";
close OUTPUT;
save_file($filename);
}
################################################################
# build the script to create registry keys
sub dump_registry_script($%)
@ -5373,6 +5808,7 @@ my $chartypes = dump_sortkey_table( "nls/sortdefault.nls", "Windows 10 Sorting W
dump_locales( "nls/locale.nls", $chartypes );
foreach my $file (@allfiles) { dump_msdata_codepage( $file ); }
dump_eucjp_codepage();
dump_timezones( "dlls/tzres/tzres.rc", @timezone_files );
dump_registry_script( "dlls/kernelbase/kernelbase.rgs", %registry_keys );
exit 0;