Skip to content

Commit 95e3d6e

Browse files
sylvestrecakebaker
andcommitted
l10n: port stty for translation + add french
Co-authored-by: Daniel Hofstetter <[email protected]>
1 parent 05eb7ee commit 95e3d6e

File tree

3 files changed

+180
-38
lines changed

3 files changed

+180
-38
lines changed

src/uu/stty/locales/en-US.ftl

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,25 @@
1-
stty-about = Print or change terminal characteristics.
2-
stty-usage = stty [-F DEVICE | --file=DEVICE] [SETTING]...
3-
stty [-F DEVICE | --file=DEVICE] [-a|--all]
4-
stty [-F DEVICE | --file=DEVICE] [-g|--save]
1+
stty-usage = "stty [-F DEVICE | --file=DEVICE] [SETTING]...
2+
or: stty [-F DEVICE | --file=DEVICE] [-a|--all]
3+
or: stty [-F DEVICE | --file=DEVICE] [-g|--save]"
4+
5+
stty-about = "Print or change terminal characteristics."
6+
7+
stty-option-all = "print all current settings in human-readable form"
8+
stty-option-save = "print all current settings in a stty-readable form"
9+
stty-option-file = "open and use the specified DEVICE instead of stdin"
10+
stty-option-settings = "settings to change"
11+
12+
stty-error-options-mutually-exclusive = "the options for verbose and stty-readable output styles are mutually exclusive"
13+
stty-error-output-style-no-modes = "when specifying an output style, modes may not be set"
14+
stty-error-missing-argument = "missing argument to '{$arg}'"
15+
stty-error-invalid-speed = "invalid {$arg} '{$speed}'"
16+
stty-error-invalid-argument = "invalid argument '{$arg}'"
17+
stty-error-invalid-integer-argument = "invalid integer argument: {$value}"
18+
stty-error-invalid-integer-argument-value-too-large = "invalid integer argument: {$value}: Value too large for defined data type"
19+
20+
# Output format strings
21+
stty-output-speed = speed {$speed} baud;
22+
stty-output-rows-columns = rows {$rows}; columns {$columns};
23+
stty-output-line = line = {$line};
24+
stty-output-undef = <undef>
25+
stty-output-min-time = min = {$min}; time = {$time};

src/uu/stty/locales/fr-FR.ftl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
stty-usage = "stty [-F PÉRIPHÉRIQUE | --file=PÉRIPHÉRIQUE] [PARAMÈTRE]...
2+
ou: stty [-F PÉRIPHÉRIQUE | --file=PÉRIPHÉRIQUE] [-a|--all]
3+
ou: stty [-F PÉRIPHÉRIQUE | --file=PÉRIPHÉRIQUE] [-g|--save]"
4+
5+
stty-about = "Afficher ou modifier les caractéristiques du terminal."
6+
7+
stty-option-all = "afficher tous les paramètres actuels sous forme lisible"
8+
stty-option-save = "afficher tous les paramètres actuels sous forme lisible par stty"
9+
stty-option-file = "ouvrir et utiliser le PÉRIPHÉRIQUE spécifié au lieu de stdin"
10+
stty-option-settings = "paramètres à modifier"
11+
12+
stty-error-options-mutually-exclusive = "les options pour les styles de sortie verbeux et lisible par stty s'excluent mutuellement"
13+
stty-error-output-style-no-modes = "lors de la spécification d'un style de sortie, les modes ne peuvent pas être définis"
14+
stty-error-missing-argument = "argument manquant pour '{$arg}'"
15+
stty-error-invalid-speed = "{$arg} invalide '{$speed}'"
16+
stty-error-invalid-argument = "argument invalide '{$arg}'"
17+
stty-error-invalid-integer-argument = "argument entier invalide : {$value}"
18+
stty-error-invalid-integer-argument-value-too-large = "argument entier invalide : {$value} : Valeur trop grande pour le type de données défini"
19+
20+
# Chaînes de format de sortie
21+
stty-output-speed = vitesse {$speed} bauds ;
22+
stty-output-rows-columns = lignes {$rows} ; colonnes {$columns} ;
23+
stty-output-line = ligne = {$line} ;
24+
stty-output-undef = <indéfini>
25+
stty-output-min-time = min = {$min} ; temps = {$time} ;

src/uu/stty/src/stty.rs

Lines changed: 130 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ use nix::sys::termios::{
1515
cfgetospeed, cfsetospeed, tcgetattr, tcsetattr,
1616
};
1717
use nix::{ioctl_read_bad, ioctl_write_ptr_bad};
18+
use std::collections::HashMap;
1819
use std::fs::File;
1920
use std::io::{self, Stdout, stdout};
2021
use std::os::fd::{AsFd, BorrowedFd};
2122
use std::os::unix::fs::OpenOptionsExt;
2223
use std::os::unix::io::{AsRawFd, RawFd};
2324
use uucore::error::{UResult, USimpleError};
2425
use uucore::format_usage;
25-
use uucore::locale::get_message;
26+
use uucore::locale::{get_message, get_message_with_args};
2627

2728
#[cfg(not(any(
2829
target_os = "freebsd",
@@ -104,8 +105,8 @@ enum Device {
104105
}
105106

106107
enum ControlCharMappingError {
107-
IntOutOfRange,
108-
MultipleChars,
108+
IntOutOfRange(String),
109+
MultipleChars(String),
109110
}
110111

111112
enum SpecialSetting {
@@ -226,14 +227,14 @@ fn stty(opts: &Options) -> UResult<()> {
226227
if opts.save && opts.all {
227228
return Err(USimpleError::new(
228229
1,
229-
"the options for verbose and stty-readable output styles are mutually exclusive",
230+
get_message("stty-error-options-mutually-exclusive"),
230231
));
231232
}
232233

233234
if opts.settings.is_some() && (opts.save || opts.all) {
234235
return Err(USimpleError::new(
235236
1,
236-
"when specifying an output style, modes may not be set",
237+
get_message("stty-error-output-style-no-modes"),
237238
));
238239
}
239240

@@ -248,18 +249,26 @@ fn stty(opts: &Options) -> UResult<()> {
248249
if let Some(mapping) = args_iter.next() {
249250
let cc_mapping = string_to_control_char(mapping).map_err(|e| {
250251
let message = match e {
251-
ControlCharMappingError::IntOutOfRange => format!(
252-
"invalid integer argument: '{mapping}': Value too large for defined data type"
252+
ControlCharMappingError::IntOutOfRange(val) => get_message_with_args(
253+
"stty-error-invalid-integer-argument-value-too-large",
254+
HashMap::from([("value".to_string(), format!("'{}'", val))]),
255+
),
256+
ControlCharMappingError::MultipleChars(val) => get_message_with_args(
257+
"stty-error-invalid-integer-argument",
258+
HashMap::from([("value".to_string(), format!("'{}'", val))]),
253259
),
254-
ControlCharMappingError::MultipleChars => {
255-
format!("invalid integer argument: '{mapping}'")
256-
}
257260
};
258261
USimpleError::new(1, message)
259262
})?;
260263
valid_args.push(ArgOptions::Mapping((char_index, cc_mapping)));
261264
} else {
262-
return Err(USimpleError::new(1, format!("missing argument to '{arg}'")));
265+
return Err(USimpleError::new(
266+
1,
267+
get_message_with_args(
268+
"stty-error-missing-argument",
269+
HashMap::from([("arg".to_string(), arg.to_string())]),
270+
),
271+
));
263272
}
264273
// ispeed/ospeed baud rate setting
265274
} else if *arg == "ispeed" || *arg == "ospeed" {
@@ -268,11 +277,26 @@ fn stty(opts: &Options) -> UResult<()> {
268277
if let Some(baud_flag) = string_to_baud(speed) {
269278
valid_args.push(ArgOptions::Flags(baud_flag));
270279
} else {
271-
return Err(USimpleError::new(1, format!("invalid {arg} '{speed}'")));
280+
return Err(USimpleError::new(
281+
1,
282+
get_message_with_args(
283+
"stty-error-invalid-speed",
284+
HashMap::from([
285+
("arg".to_string(), arg.to_string()),
286+
("speed".to_string(), speed.to_string()),
287+
]),
288+
),
289+
));
272290
}
273291
}
274292
None => {
275-
return Err(USimpleError::new(1, format!("missing argument to '{arg}'")));
293+
return Err(USimpleError::new(
294+
1,
295+
get_message_with_args(
296+
"stty-error-missing-argument",
297+
HashMap::from([("arg".to_string(), arg.to_string())]),
298+
),
299+
));
276300
}
277301
}
278302
// baud rate setting
@@ -288,7 +312,13 @@ fn stty(opts: &Options) -> UResult<()> {
288312
AllFlags::OutputFlags((flag, remove)) => check_flag_group(flag, remove),
289313
};
290314
if remove_group {
291-
return Err(USimpleError::new(1, format!("invalid argument '{arg}'")));
315+
return Err(USimpleError::new(
316+
1,
317+
get_message_with_args(
318+
"stty-error-invalid-argument",
319+
HashMap::from([("arg".to_string(), arg.to_string())]),
320+
),
321+
));
292322
}
293323
valid_args.push(flag.into());
294324
} else if *arg == "rows" {
@@ -298,11 +328,20 @@ fn stty(opts: &Options) -> UResult<()> {
298328
} else {
299329
return Err(USimpleError::new(
300330
1,
301-
format!("invalid integer argument: '{rows}'"),
331+
get_message_with_args(
332+
"stty-error-invalid-integer-argument",
333+
HashMap::from([("value".to_string(), format!("'{}'", rows))]),
334+
),
302335
));
303336
}
304337
} else {
305-
return Err(USimpleError::new(1, format!("missing argument to '{arg}'")));
338+
return Err(USimpleError::new(
339+
1,
340+
get_message_with_args(
341+
"stty-error-missing-argument",
342+
HashMap::from([("arg".to_string(), arg.to_string())]),
343+
),
344+
));
306345
}
307346
} else if *arg == "columns" || *arg == "cols" {
308347
if let Some(cols) = args_iter.next() {
@@ -311,17 +350,32 @@ fn stty(opts: &Options) -> UResult<()> {
311350
} else {
312351
return Err(USimpleError::new(
313352
1,
314-
format!("invalid integer argument: '{cols}'"),
353+
get_message_with_args(
354+
"stty-error-invalid-integer-argument",
355+
HashMap::from([("value".to_string(), format!("'{}'", cols))]),
356+
),
315357
));
316358
}
317359
} else {
318-
return Err(USimpleError::new(1, format!("missing argument to '{arg}'")));
360+
return Err(USimpleError::new(
361+
1,
362+
get_message_with_args(
363+
"stty-error-missing-argument",
364+
HashMap::from([("arg".to_string(), arg.to_string())]),
365+
),
366+
));
319367
}
320368
} else if *arg == "size" {
321369
valid_args.push(ArgOptions::Print(PrintSetting::Size));
322370
// not a valid option
323371
} else {
324-
return Err(USimpleError::new(1, format!("invalid argument '{arg}'")));
372+
return Err(USimpleError::new(
373+
1,
374+
get_message_with_args(
375+
"stty-error-invalid-argument",
376+
HashMap::from([("arg".to_string(), arg.to_string())]),
377+
),
378+
));
325379
}
326380
}
327381

@@ -391,7 +445,13 @@ fn print_terminal_size(termios: &Termios, opts: &Options) -> nix::Result<()> {
391445
target_os = "netbsd",
392446
target_os = "openbsd"
393447
))]
394-
print!("speed {speed} baud; ");
448+
print!(
449+
"{} ",
450+
get_message_with_args(
451+
"stty-output-speed",
452+
HashMap::from([("speed".to_string(), speed.to_string())])
453+
)
454+
);
395455

396456
// Other platforms need to use the baud rate enum, so printing the right value
397457
// becomes slightly more complicated.
@@ -405,15 +465,30 @@ fn print_terminal_size(termios: &Termios, opts: &Options) -> nix::Result<()> {
405465
)))]
406466
for (text, baud_rate) in BAUD_RATES {
407467
if *baud_rate == speed {
408-
print!("speed {text} baud; ");
468+
print!(
469+
"{} ",
470+
get_message_with_args(
471+
"stty-output-speed",
472+
HashMap::from([("speed".to_string(), text.to_string())])
473+
)
474+
);
409475
break;
410476
}
411477
}
412478

413479
if opts.all {
414480
let mut size = TermSize::default();
415481
unsafe { tiocgwinsz(opts.file.as_raw_fd(), &raw mut size)? };
416-
print!("rows {}; columns {}; ", size.rows, size.columns);
482+
print!(
483+
"{} ",
484+
get_message_with_args(
485+
"stty-output-rows-columns",
486+
HashMap::from([
487+
("rows".to_string(), size.rows.to_string()),
488+
("columns".to_string(), size.columns.to_string())
489+
])
490+
)
491+
);
417492
}
418493

419494
#[cfg(any(target_os = "linux", target_os = "redox"))]
@@ -422,7 +497,13 @@ fn print_terminal_size(termios: &Termios, opts: &Options) -> nix::Result<()> {
422497
// so we get the underlying libc::termios struct to get that information.
423498
let libc_termios: nix::libc::termios = termios.clone().into();
424499
let line = libc_termios.c_line;
425-
print!("line = {line};");
500+
print!(
501+
"{}",
502+
get_message_with_args(
503+
"stty-output-line",
504+
HashMap::from([("line".to_string(), line.to_string())])
505+
)
506+
);
426507
}
427508

428509
println!();
@@ -498,7 +579,7 @@ fn string_to_flag(option: &str) -> Option<AllFlags> {
498579

499580
fn control_char_to_string(cc: nix::libc::cc_t) -> nix::Result<String> {
500581
if cc == 0 {
501-
return Ok("<undef>".to_string());
582+
return Ok(get_message("stty-output-undef"));
502583
}
503584

504585
let (meta_prefix, code) = if cc >= 0x80 {
@@ -535,9 +616,20 @@ fn print_control_chars(termios: &Termios, opts: &Options) -> nix::Result<()> {
535616
);
536617
}
537618
println!(
538-
"min = {}; time = {};",
539-
termios.control_chars[SpecialCharacterIndices::VMIN as usize],
540-
termios.control_chars[SpecialCharacterIndices::VTIME as usize]
619+
"{}",
620+
get_message_with_args(
621+
"stty-output-min-time",
622+
HashMap::from([
623+
(
624+
"min".to_string(),
625+
termios.control_chars[SpecialCharacterIndices::VMIN as usize].to_string()
626+
),
627+
(
628+
"time".to_string(),
629+
termios.control_chars[SpecialCharacterIndices::VTIME as usize].to_string()
630+
)
631+
])
632+
)
541633
);
542634
Ok(())
543635
}
@@ -682,14 +774,18 @@ fn string_to_control_char(s: &str) -> Result<u8, ControlCharMappingError> {
682774
let ascii_num = if let Some(hex) = s.strip_prefix("0x") {
683775
u32::from_str_radix(hex, 16).ok()
684776
} else if let Some(octal) = s.strip_prefix("0") {
685-
u32::from_str_radix(octal, 8).ok()
777+
if octal.is_empty() {
778+
Some(0)
779+
} else {
780+
u32::from_str_radix(octal, 8).ok()
781+
}
686782
} else {
687783
s.parse::<u32>().ok()
688784
};
689785

690786
if let Some(val) = ascii_num {
691787
if val > 255 {
692-
return Err(ControlCharMappingError::IntOutOfRange);
788+
return Err(ControlCharMappingError::IntOutOfRange(s.to_string()));
693789
} else {
694790
return Ok(val as u8);
695791
}
@@ -706,7 +802,7 @@ fn string_to_control_char(s: &str) -> Result<u8, ControlCharMappingError> {
706802
Ok((c.to_ascii_uppercase() as u8).wrapping_sub(b'@'))
707803
}
708804
(Some(c), None) => Ok(c as u8),
709-
(Some(_), Some(_)) => Err(ControlCharMappingError::MultipleChars),
805+
(Some(_), Some(_)) => Err(ControlCharMappingError::MultipleChars(s.to_string())),
710806
_ => unreachable!("No arguments provided: must have been caught earlier"),
711807
}
712808
}
@@ -721,14 +817,14 @@ pub fn uu_app() -> Command {
721817
Arg::new(options::ALL)
722818
.short('a')
723819
.long(options::ALL)
724-
.help("print all current settings in human-readable form")
820+
.help(get_message("stty-option-all"))
725821
.action(ArgAction::SetTrue),
726822
)
727823
.arg(
728824
Arg::new(options::SAVE)
729825
.short('g')
730826
.long(options::SAVE)
731-
.help("print all current settings in a stty-readable form")
827+
.help(get_message("stty-option-save"))
732828
.action(ArgAction::SetTrue),
733829
)
734830
.arg(
@@ -737,13 +833,13 @@ pub fn uu_app() -> Command {
737833
.long(options::FILE)
738834
.value_hint(clap::ValueHint::FilePath)
739835
.value_name("DEVICE")
740-
.help("open and use the specified DEVICE instead of stdin"),
836+
.help(get_message("stty-option-file")),
741837
)
742838
.arg(
743839
Arg::new(options::SETTINGS)
744840
.action(ArgAction::Append)
745841
.allow_hyphen_values(true)
746-
.help("settings to change"),
842+
.help(get_message("stty-option-settings")),
747843
)
748844
}
749845

0 commit comments

Comments
 (0)