|
1
|
|
|
<?php |
|
2
|
|
|
/* PROJECT: ReactOS Translation Tool |
|
3
|
|
|
* LICENSE: GPL |
|
4
|
|
|
* AUTHORS: Adam Stachowicz <[email protected]> |
|
5
|
|
|
* AUTHOR URL: http://it-maniak.pl/ |
|
6
|
|
|
*/ |
|
7
|
|
|
|
|
8
|
|
|
include_once 'header.php'; |
|
9
|
|
|
?> |
|
10
|
|
|
|
|
11
|
|
|
<h1>Search missing translation strings</h1> |
|
12
|
|
|
|
|
13
|
|
|
<div id="body"> |
|
14
|
|
|
<center> |
|
15
|
|
|
<form method="GET" class="form-horizontal"> |
|
16
|
|
|
<fieldset> |
|
17
|
|
|
<legend>Please type your <a href="https://beta.wikiversity.org/wiki/List_of_ISO_639-1_codes">language code in ISO 639-1</a>. For example: pl for Polish, de for German</legend> |
|
18
|
|
|
<div class="form-group"> |
|
19
|
|
|
<label class="col-md-4 control-label" for="lang">Language code:</label> |
|
20
|
|
|
<div class="col-md-4"> |
|
21
|
|
|
<input type="text" value="<?php echo isset($_SESSION['lang']) ? $_SESSION['lang'] : '' ?>" id="lang" name="lang" class="form-control input-md" required="required" autofocus="autofocus" pattern="[A-Za-z]{2}" title="Two letter language code"/> |
|
22
|
|
|
</div> |
|
23
|
|
|
</div> |
|
24
|
|
|
<div class="form-group"> |
|
25
|
|
|
<label class="col-md-4 control-label" for="dir">Directories:</label> |
|
26
|
|
|
<div class="col-md-4"> |
|
27
|
|
|
<select id="dir" name="dir" class="form-control"> |
|
28
|
|
|
<option value="1">base, boot</option> |
|
29
|
|
|
<option value="2" <?php if (isset($_GET['dir']) && $_GET['dir'] == '2') { |
|
30
|
|
|
echo 'selected'; |
|
31
|
|
|
}?>>dll</option> |
|
32
|
|
|
<option value="3" <?php if (isset($_GET['dir']) && $_GET['dir'] == '3') { |
|
33
|
|
|
echo 'selected'; |
|
34
|
|
|
}?>>media, subsystems, win32ss</option> |
|
35
|
|
|
<option value="100" <?php if (isset($_GET['dir']) && $_GET['dir'] == '100') { |
|
36
|
|
|
echo 'selected'; |
|
37
|
|
|
}?>>All ReactOS Source dir</option> |
|
38
|
|
|
</select> |
|
39
|
|
|
</div> |
|
40
|
|
|
</div> |
|
41
|
|
|
<div class="form-group"> |
|
42
|
|
|
<button type="submit" class="btn btn-primary">Search</button> |
|
43
|
|
|
</div> |
|
44
|
|
|
</fieldset> |
|
45
|
|
|
</form> |
|
46
|
|
|
</center> |
|
47
|
|
|
<br> |
|
48
|
|
|
|
|
49
|
|
|
<?php |
|
50
|
|
|
if (isset($_GET['lang']) && !empty($_GET['lang']) && isset($_GET['dir']) && is_numeric($_GET['dir'])) { |
|
51
|
|
|
$it = new AppendIterator(); |
|
52
|
|
|
|
|
53
|
|
|
// Switch for directories |
|
54
|
|
|
switch ($_GET['dir']) { |
|
55
|
|
|
case '1': |
|
56
|
|
|
$directories = [ |
|
57
|
|
|
new RecursiveDirectoryIterator($ROSDir.'base/applications'), |
|
58
|
|
|
new RecursiveDirectoryIterator($ROSDir.'base/setup'), |
|
59
|
|
|
new RecursiveDirectoryIterator($ROSDir.'base/shell'), |
|
60
|
|
|
new RecursiveDirectoryIterator($ROSDir.'base/system'), |
|
61
|
|
|
new RecursiveDirectoryIterator($ROSDir.'boot/freeldr/fdebug'), |
|
62
|
|
|
]; |
|
63
|
|
|
break; |
|
64
|
|
|
|
|
65
|
|
|
case '2': |
|
66
|
|
|
$directories = [ |
|
67
|
|
|
new RecursiveDirectoryIterator($ROSDir.'dll/cpl'), |
|
68
|
|
|
new RecursiveDirectoryIterator($ROSDir.'dll/shellext'), |
|
69
|
|
|
new RecursiveDirectoryIterator($ROSDir.'dll/win32'), |
|
70
|
|
|
]; |
|
71
|
|
|
break; |
|
72
|
|
|
|
|
73
|
|
|
case '3': |
|
74
|
|
|
$directories = [ |
|
75
|
|
|
new RecursiveDirectoryIterator($ROSDir.'media/themes'), |
|
76
|
|
|
new RecursiveDirectoryIterator($ROSDir.'subsystems/mvdm/ntvdm'), |
|
77
|
|
|
new RecursiveDirectoryIterator($ROSDir.'win32ss/user'), |
|
78
|
|
|
]; |
|
79
|
|
|
break; |
|
80
|
|
|
|
|
81
|
|
|
case '100': |
|
82
|
|
|
$directories = [ |
|
83
|
|
|
new RecursiveDirectoryIterator($ROSDir), |
|
84
|
|
|
]; |
|
85
|
|
|
break; |
|
86
|
|
|
|
|
87
|
|
|
default: |
|
88
|
|
|
echo 'Something is wrong! Please try again.'; |
|
89
|
|
|
exit; |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
foreach ($directories as $directory) { |
|
93
|
|
|
$it->append(new RecursiveIteratorIterator($directory)); |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
function diff_versions($leftContent, $rightContent) |
|
97
|
|
|
{ |
|
98
|
|
|
$leftVersion = $rightVersion = null; |
|
|
|
|
|
|
99
|
|
|
|
|
100
|
|
|
// FIXME: Search multi-line with ""some text"" |
|
101
|
|
|
$pattern = '/^(?!FONT|\\s*\\*|\\#\\include|\\s*\\ICON)[^"\\n]*"\\K(?!\\s*(?:"|\\n))([^"]+)/m'; |
|
102
|
|
|
|
|
103
|
|
|
if (preg_match_all($pattern, $leftContent, $matches) <= 0) { |
|
104
|
|
|
throw new Exception('Left content has no version line.'); |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
$leftVersion = $matches[1]; |
|
108
|
|
|
|
|
109
|
|
|
if (preg_match_all($pattern, $rightContent, $matches) <= 0) { |
|
110
|
|
|
throw new Exception('Right content has no version line.'); |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
$rightVersion = $matches[1]; |
|
114
|
|
|
|
|
115
|
|
|
return [ |
|
116
|
|
|
'diff' => array_intersect($leftVersion, $rightVersion), |
|
117
|
|
|
'leftVersion' => $leftVersion, |
|
118
|
|
|
'rightVersion' => $rightVersion, |
|
119
|
|
|
]; |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
function exceptions_error_handler($severity, $message, $filename, $lineno) |
|
123
|
|
|
{ |
|
124
|
|
|
if (error_reporting() == 0) { |
|
125
|
|
|
return; |
|
126
|
|
|
} |
|
127
|
|
|
if (error_reporting() & $severity) { |
|
128
|
|
|
throw new ErrorException($message, 0, $severity, $filename, $lineno); |
|
129
|
|
|
} |
|
130
|
|
|
} |
|
131
|
|
|
|
|
132
|
|
|
set_error_handler('exceptions_error_handler'); |
|
133
|
|
|
|
|
134
|
|
|
$regex = new RegexIterator($it, '/^.+'.$langDir.'.+('.$originLang.')\.'.$fileExt.'$/i', RecursiveRegexIterator::GET_MATCH); |
|
135
|
|
|
|
|
136
|
|
|
$missing = $allStrings = 0; |
|
137
|
|
|
|
|
138
|
|
|
$lang = htmlspecialchars($_GET['lang']); |
|
139
|
|
|
// Search for eg. PL,Pl,pl |
|
140
|
|
|
$fileSearch = strtoupper($lang).','.ucfirst($lang).','.strtolower($lang); |
|
141
|
|
|
|
|
142
|
|
|
// ReactOS and Wine Strings - array |
|
143
|
|
|
$ignoredROSStrings = file($ROSSpellFilename, FILE_IGNORE_NEW_LINES); |
|
144
|
|
|
$ignoredWineStrings = file($wineSpellFilename, FILE_IGNORE_NEW_LINES); |
|
145
|
|
|
|
|
146
|
|
|
$regex->rewind(); |
|
147
|
|
|
while ($regex->valid()) { |
|
148
|
|
|
if (!$regex->isDot()) { |
|
149
|
|
|
$file = glob($regex->getPathInfo().'/*{'.$fileSearch.'}*.'.$fileExt, GLOB_BRACE); |
|
150
|
|
|
|
|
151
|
|
|
$isFile = array_filter($file); |
|
152
|
|
|
|
|
153
|
|
|
if (empty($isFile)) { |
|
154
|
|
|
echo '<b>No translation</b> for path '.$regex->getPathInfo().'<hr>'; |
|
155
|
|
|
} else { |
|
156
|
|
|
$fileContent1 = file_get_contents($regex->key()); |
|
157
|
|
|
$fileContent2 = file_get_contents($file[0]); |
|
158
|
|
|
|
|
159
|
|
|
$array = diff_versions($fileContent1, $fileContent2); |
|
160
|
|
|
|
|
161
|
|
|
if ($array['diff']) { |
|
162
|
|
|
echo $regex->getPathInfo().'<br><br>'; |
|
163
|
|
|
|
|
164
|
|
|
$currentMissing = $missing; |
|
165
|
|
|
|
|
166
|
|
|
foreach ($array['leftVersion'] as $index => $english) { |
|
167
|
|
|
// Catch offset error |
|
168
|
|
|
try { |
|
169
|
|
|
// Check if this same and ignore some words |
|
170
|
|
|
if ($english === $array['rightVersion'][$index] && !in_array($english, $ignoredROSStrings) && !in_array($english, $ignoredWineStrings)) { |
|
171
|
|
|
echo '<b>Missing translation:</b> '.htmlspecialchars($english).'<br>'; |
|
172
|
|
|
$missing++; |
|
173
|
|
|
} |
|
174
|
|
|
$allStrings++; |
|
175
|
|
|
} catch (Exception $e) { |
|
176
|
|
|
echo 'Missing stuff in your language<br>'; |
|
177
|
|
|
$allStrings++; |
|
178
|
|
|
$missing++; |
|
179
|
|
|
} |
|
180
|
|
|
} |
|
181
|
|
|
if ($currentMissing == $missing) { |
|
182
|
|
|
echo 'Seems <b>OK :)</b> Some strings was ignored by ReactOS and Wine spell files.<br>'; |
|
183
|
|
|
} |
|
184
|
|
|
|
|
185
|
|
|
echo '<hr>'; |
|
186
|
|
|
} |
|
187
|
|
|
} |
|
188
|
|
|
} |
|
189
|
|
|
$regex->next(); |
|
190
|
|
|
} |
|
191
|
|
|
echo "<h3>All strings for english: $allStrings</h3>"; |
|
192
|
|
|
echo "<h3>Missing translations for your language ($lang): $missing</h3>"; |
|
193
|
|
|
|
|
194
|
|
|
// Rounded percent |
|
195
|
|
|
$percent = round((($allStrings - $missing) / $allStrings) * 100, 2); |
|
196
|
|
|
echo "<h3>Language $lang translated in $percent%</h3>"; |
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
include_once 'footer.php'; |
|
200
|
|
|
|
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.