master
ps1 183 lines 4.4 KB
Raw
1 # Script to generate Localization.h from resources.resw
2
3
4 param( [Parameter(Mandatory=$true)] $OutFile)
5
6 $ErrorActionPreference = "Stop"
7
8 $resourceFolder = "$($PSScriptRoot)\..\localization\strings"
9 $defaultLanguage = "en-US"
10 $languages = @($defaultLanguage) + (Get-ChildItem -Path $resourceFolder | % { $_.name} | Where { $_ -Ne $defaultLanguage })
11
12 $content = @"
13 // Copyright (C) Microsoft Corporation. All rights reserved.
14 //
15 // This file is generated by generateLocalizationHeader.ps1, do not edit it manually.
16
17 #pragma once
18
19 #include <vector>
20 #include <stringshared.h>
21
22 namespace wsl::shared {
23
24 class Localization
25 {
26 public:
27
28 #ifdef WIN32
29
30 #define ARGS std::make_wformat_args
31 using TChar = wchar_t;
32
33 #else
34
35 #define ARGS std::make_format_args
36 using TChar = char;
37
38 #define TEXT(X) X
39
40 #endif
41
42 using TString = std::basic_string<TChar>;
43
44 enum class Options
45 {
46 Default = 0,
47 DontImpersonate = 1
48 };
49 "@
50
51 function getArgumentsFromInserts
52 {
53 param(
54 [string]$Name,
55 [string]$Content)
56
57 [System.Collections.ArrayList]$Arguments = @()
58
59 $Content = $Content -Replace '{{', ''
60
61 return ([regex]::Matches($Content, "{" )).count
62 }
63
64 function generateEntry
65 {
66 param(
67 [string]$Name,
68 [hashtable]$AllStrings)
69
70 $content = $AllStrings[$defaultLanguage][$Name]
71 $map = "static const std::vector<std::pair<TString, const TChar*>> strings {`r`n {TEXT(`"$defaultLanguage`"), TEXT(R`"($content)`")}"
72
73 foreach ($language in $AllStrings.Keys)
74 {
75 if ($language -eq $defaultLanguage)
76 {
77 continue
78 }
79
80 $strings = $AllStrings[$language]
81
82 if (!$strings.ContainsKey($Name))
83 {
84 Write-Host "Warning: string $Name not found in language: $language"
85 continue
86 }
87
88 $map += ",`r`n {TEXT(`"$language`"), TEXT(R`"($($strings[$Name]))`")}"
89 }
90
91 $map += "}"
92
93
94 $ArgumentsCount = getArgumentsFromInserts -Name $Name -Content $Content
95 if ($ArgumentsCount -eq 0)
96 {
97 return '
98 /* Message: {1}*/
99 static inline TString {0}(Options options = Options::Default)
100 {{
101 {2};
102
103 return LookupString(strings, options);
104 }}
105 ' -f $Name, $Content.split("`n")[0], $map
106 }
107 else
108 {
109 $ArgumentTypes = [string]::Join(', ', ((1..$ArgumentsCount) |% {"typename T$_"}))
110 $ArgumentHeaders = [string]::Join(', ', ((1..$ArgumentsCount) |% {"const T$_& arg$_"}))
111 $Arguments = [string]::Join(', ', ((1..$ArgumentsCount) |% {"arg$_"}))
112 return '
113 /* Message: {4}*/
114
115 template <{1}>
116 static TString {0}({2}, Options options = Options::Default)
117 {{
118 {5};
119
120 auto message = LookupString(strings, options);
121 return std::vformat(message, ARGS({3}));
122 }}
123 ' -f $Name, $ArgumentTypes, $ArgumentHeaders, $Arguments, $Content.split("`n")[0], $map
124
125 }
126 }
127
128 function loadStrings
129 {
130 param([string]$language)
131 $xml = [xml](Get-Content "$resourceFolder/$language/Resources.resw" -raw)
132
133 $strings = @{}
134
135 foreach($entry in $xml.root.data)
136 {
137 if ($strings.ContainsKey($entry.name))
138 {
139 throw "Entry $($entry.name) duplicated in resource for: $language"
140 }
141
142 # Skip generating strings intended for WSL Settings. These strings are
143 # unused in native C++ code. Further, their naming is incompatible with
144 # the function names generated for the localization header (contain '.').
145 if ($entry.name.StartsWith("Settings_"))
146 {
147 continue
148 }
149
150 $strings[$entry.name] = $entry.value
151 }
152
153 return $strings
154 }
155
156 $allStrings = @{}
157
158 foreach ($language in $languages)
159 {
160 $allStrings[$language] = loadStrings -language $language
161 }
162
163 foreach($entry in $allStrings[$defaultLanguage].Keys)
164 {
165 $content += generateEntry -Name $entry -allStrings $allStrings
166 }
167
168 $content += @"
169 public:
170 #ifdef WIN32
171 static bool IsCurrentLanguageEnglish(Options options = Options::Default);
172 #endif
173 private:
174 static const TChar* LookupString(const std::vector<std::pair<TString, const TChar*>>& strings, Options options);
175 };
176
177 } // namespace wsl::windows::common
178
179 #undef ARGS
180 "@
181
182
183 Set-Content -Path $OutFile -Encoding UTF8 $content