CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Tools/langtool/src/main.rs
Views: 1401
1
use std::io;
2
3
mod section;
4
5
mod inifile;
6
use inifile::IniFile;
7
8
use clap::Parser;
9
10
#[derive(Parser, Debug)]
11
struct Args {
12
#[command(subcommand)]
13
cmd: Command,
14
#[arg(short, long)]
15
dry_run: bool,
16
}
17
18
#[derive(Parser, Debug)]
19
enum Command {
20
CopyMissingLines {
21
#[arg(short, long)]
22
dont_comment_missing: bool,
23
},
24
CommentUnknownLines {},
25
RemoveUnknownLines {},
26
AddNewKey {
27
section: String,
28
key: String,
29
},
30
AddNewKeyValue {
31
section: String,
32
key: String,
33
value: String,
34
},
35
MoveKey {
36
old: String,
37
new: String,
38
key: String,
39
},
40
CopyKey {
41
old: String,
42
new: String,
43
key: String,
44
},
45
RenameKey {
46
section: String,
47
old: String,
48
new: String,
49
},
50
SortSection {
51
section: String,
52
},
53
RemoveKey {
54
section: String,
55
key: String,
56
},
57
}
58
59
fn copy_missing_lines(
60
reference_ini: &IniFile,
61
target_ini: &mut IniFile,
62
comment_missing: bool,
63
) -> io::Result<()> {
64
for reference_section in &reference_ini.sections {
65
// Insert any missing full sections.
66
if !target_ini.insert_section_if_missing(reference_section) {
67
if let Some(target_section) = target_ini.get_section_mut(&reference_section.name) {
68
for line in &reference_section.lines {
69
target_section.insert_line_if_missing(line);
70
}
71
72
//target_section.remove_lines_if_not_in(reference_section);
73
if comment_missing {
74
target_section.comment_out_lines_if_not_in(reference_section);
75
}
76
}
77
} else {
78
// Note: insert_section_if_missing will copy the entire section,
79
// no need to loop over the lines here.
80
println!("Inserted missing section: {}", reference_section.name);
81
}
82
}
83
Ok(())
84
}
85
86
fn deal_with_unknown_lines(
87
reference_ini: &IniFile,
88
target_ini: &mut IniFile,
89
remove: bool,
90
) -> io::Result<()> {
91
for reference_section in &reference_ini.sections {
92
if let Some(target_section) = target_ini.get_section_mut(&reference_section.name) {
93
if remove {
94
target_section.remove_lines_if_not_in(reference_section);
95
} else {
96
target_section.comment_out_lines_if_not_in(reference_section);
97
}
98
}
99
}
100
Ok(())
101
}
102
103
fn move_key(target_ini: &mut IniFile, old: &str, new: &str, key: &str) -> io::Result<()> {
104
if let Some(old_section) = target_ini.get_section_mut(old) {
105
if let Some(line) = old_section.remove_line(key) {
106
if let Some(new_section) = target_ini.get_section_mut(new) {
107
new_section.insert_line_if_missing(&line);
108
} else {
109
println!("No new section {}", new);
110
}
111
} else {
112
println!("No key {} in section {}", key, old);
113
}
114
} else {
115
println!("No old section {}", old);
116
}
117
Ok(())
118
}
119
120
fn copy_key(target_ini: &mut IniFile, old: &str, new: &str, key: &str) -> io::Result<()> {
121
if let Some(old_section) = target_ini.get_section_mut(old) {
122
if let Some(line) = old_section.get_line(key) {
123
if let Some(new_section) = target_ini.get_section_mut(new) {
124
new_section.insert_line_if_missing(&line);
125
} else {
126
println!("No new section {}", new);
127
}
128
} else {
129
println!("No key {} in section {}", key, old);
130
}
131
} else {
132
println!("No old section {}", old);
133
}
134
Ok(())
135
}
136
137
fn remove_key(target_ini: &mut IniFile, section: &str, key: &str) -> io::Result<()> {
138
if let Some(old_section) = target_ini.get_section_mut(section) {
139
old_section.remove_line(key);
140
} else {
141
println!("No section {}", section);
142
}
143
Ok(())
144
}
145
146
fn add_new_key(target_ini: &mut IniFile, section: &str, key: &str, value: &str) -> io::Result<()> {
147
if let Some(section) = target_ini.get_section_mut(section) {
148
section.insert_line_if_missing(&format!("{} = {}", key, value));
149
} else {
150
println!("No section {}", section);
151
}
152
Ok(())
153
}
154
155
fn rename_key(target_ini: &mut IniFile, section: &str, old: &str, new: &str) -> io::Result<()> {
156
if let Some(section) = target_ini.get_section_mut(section) {
157
section.rename_key(old, new);
158
} else {
159
println!("No section {}", section);
160
}
161
Ok(())
162
}
163
164
fn sort_section(target_ini: &mut IniFile, section: &str) -> io::Result<()> {
165
if let Some(section) = target_ini.get_section_mut(section) {
166
section.sort();
167
} else {
168
println!("No section {}", section);
169
}
170
Ok(())
171
}
172
173
// TODO: Look into using https://github.com/Byron/google-apis-rs/tree/main/gen/translate2 for initial translations.
174
175
fn main() {
176
let opt = Args::parse();
177
178
// TODO: Grab extra arguments from opt somehow.
179
let args: Vec<String> = vec![]; //std::env::args().skip(1).collect();
180
let mut filenames = args;
181
182
let root = "../../assets/lang";
183
let reference_ini_filename = "en_US.ini";
184
185
let mut reference_ini =
186
IniFile::parse(&format!("{}/{}", root, reference_ini_filename)).unwrap();
187
188
if filenames.is_empty() {
189
// Grab them all.
190
for path in std::fs::read_dir(root).unwrap() {
191
let path = path.unwrap();
192
if path.file_name() == reference_ini_filename {
193
continue;
194
}
195
let filename = path.file_name();
196
let filename = filename.to_string_lossy();
197
if !filename.ends_with(".ini") {
198
continue;
199
}
200
filenames.push(path.file_name().to_string_lossy().to_string());
201
}
202
}
203
204
for filename in filenames {
205
let reference_ini = &reference_ini;
206
if filename == "langtool" {
207
// Get this from cargo run for some reason.
208
continue;
209
}
210
let target_ini_filename = format!("{}/{}", root, filename);
211
println!("Langtool processing {}", target_ini_filename);
212
213
let mut target_ini = IniFile::parse(&target_ini_filename).unwrap();
214
215
match opt.cmd {
216
Command::CopyMissingLines {
217
dont_comment_missing,
218
} => {
219
copy_missing_lines(reference_ini, &mut target_ini, !dont_comment_missing).unwrap();
220
}
221
Command::CommentUnknownLines {} => {
222
deal_with_unknown_lines(reference_ini, &mut target_ini, false).unwrap();
223
}
224
Command::RemoveUnknownLines {} => {
225
deal_with_unknown_lines(reference_ini, &mut target_ini, true).unwrap();
226
}
227
Command::SortSection { ref section } => sort_section(&mut target_ini, section).unwrap(),
228
Command::RenameKey {
229
ref section,
230
ref old,
231
ref new,
232
} => rename_key(&mut target_ini, section, old, new).unwrap(),
233
Command::AddNewKey {
234
ref section,
235
ref key,
236
} => add_new_key(&mut target_ini, section, key, key).unwrap(),
237
Command::AddNewKeyValue {
238
ref section,
239
ref key,
240
ref value,
241
} => add_new_key(&mut target_ini, section, key, value).unwrap(),
242
Command::MoveKey {
243
ref old,
244
ref new,
245
ref key,
246
} => {
247
move_key(&mut target_ini, old, new, key).unwrap();
248
}
249
Command::CopyKey {
250
ref old,
251
ref new,
252
ref key,
253
} => {
254
copy_key(&mut target_ini, old, new, key).unwrap();
255
}
256
Command::RemoveKey {
257
ref section,
258
ref key,
259
} => {
260
remove_key(&mut target_ini, section, key).unwrap();
261
}
262
}
263
264
if !opt.dry_run {
265
target_ini.write().unwrap();
266
}
267
}
268
269
println!("Langtool processing {}", reference_ini_filename);
270
271
// Some commands also apply to the reference ini.
272
match opt.cmd {
273
Command::AddNewKey {
274
ref section,
275
ref key,
276
} => {
277
add_new_key(&mut reference_ini, section, key, key).unwrap();
278
}
279
Command::AddNewKeyValue {
280
ref section,
281
ref key,
282
ref value,
283
} => {
284
add_new_key(&mut reference_ini, section, key, value).unwrap();
285
}
286
Command::SortSection { ref section } => sort_section(&mut reference_ini, section).unwrap(),
287
Command::RenameKey {
288
ref section,
289
ref old,
290
ref new,
291
} => {
292
if old == new {
293
println!("WARNING: old == new");
294
}
295
rename_key(&mut reference_ini, section, old, new).unwrap();
296
}
297
Command::MoveKey {
298
ref old,
299
ref new,
300
ref key,
301
} => {
302
move_key(&mut reference_ini, old, new, key).unwrap();
303
}
304
Command::CopyKey {
305
ref old,
306
ref new,
307
ref key,
308
} => {
309
copy_key(&mut reference_ini, old, new, key).unwrap();
310
}
311
Command::RemoveKey {
312
ref section,
313
ref key,
314
} => {
315
remove_key(&mut reference_ini, section, key).unwrap();
316
}
317
_ => {}
318
}
319
320
if !opt.dry_run {
321
reference_ini.write().unwrap();
322
}
323
}
324
325