1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

l10n: port truncate to translation + add french

This commit is contained in:
Sylvestre Ledru 2025-06-08 11:19:37 +02:00 committed by Sylvestre Ledru
parent a769fc7904
commit ac265279fc
3 changed files with 116 additions and 31 deletions

View file

@ -16,3 +16,18 @@ truncate-after-help = SIZE is an integer with an optional prefix and optional un
'>' => at least '>' => at least
'/' => round down to multiple of '/' => round down to multiple of
'%' => round up to multiple of '%' => round up to multiple of
# Help messages
truncate-help-io-blocks = treat SIZE as the number of I/O blocks of the file rather than bytes (NOT IMPLEMENTED)
truncate-help-no-create = do not create files that do not exist
truncate-help-reference = base the size of each file on the size of RFILE
truncate-help-size = set or adjust the size of each file according to SIZE, which is in bytes unless --io-blocks is specified
# Error messages
truncate-error-missing-file-operand = missing file operand
truncate-error-cannot-open-no-device = cannot open { $filename } for writing: No such device or address
truncate-error-cannot-open-for-writing = cannot open { $filename } for writing
truncate-error-invalid-number = Invalid number: { $error }
truncate-error-must-specify-relative-size = you must specify a relative '--size' with '--reference'
truncate-error-division-by-zero = division by zero
truncate-error-cannot-stat-no-such-file = cannot stat { $filename }: No such file or directory

View file

@ -0,0 +1,33 @@
truncate-about = Réduire ou étendre la taille de chaque fichier à la taille spécifiée.
truncate-usage = truncate [OPTION]... [FICHIER]...
truncate-after-help = TAILLE est un entier avec un préfixe optionnel et une unité optionnelle.
Les unités disponibles (K, M, G, T, P, E, Z, et Y) utilisent le format suivant :
'KB' => 1000 (kilooctets)
'K' => 1024 (kibioctets)
'MB' => 1000*1000 (mégaoctets)
'M' => 1024*1024 (mébioctets)
'GB' => 1000*1000*1000 (gigaoctets)
'G' => 1024*1024*1024 (gibioctets)
TAILLE peut aussi être préfixée par l'un des éléments suivants pour ajuster la taille de chaque
fichier basé sur sa taille actuelle :
'+' => étendre de
'-' => réduire de
'<' => au maximum
'>' => au minimum
'/' => arrondir vers le bas au multiple de
'%' => arrondir vers le haut au multiple de
# Messages d'aide
truncate-help-io-blocks = traiter TAILLE comme le nombre de blocs I/O du fichier plutôt que des octets (NON IMPLÉMENTÉ)
truncate-help-no-create = ne pas créer les fichiers qui n'existent pas
truncate-help-reference = baser la taille de chaque fichier sur la taille de RFICHIER
truncate-help-size = définir ou ajuster la taille de chaque fichier selon TAILLE, qui est en octets sauf si --io-blocks est spécifié
# Messages d'erreur
truncate-error-missing-file-operand = opérande de fichier manquant
truncate-error-cannot-open-no-device = impossible d'ouvrir { $filename } en écriture : Aucun périphérique ou adresse de ce type
truncate-error-cannot-open-for-writing = impossible d'ouvrir { $filename } en écriture
truncate-error-invalid-number = Nombre invalide : { $error }
truncate-error-must-specify-relative-size = vous devez spécifier une '--size' relative avec '--reference'
truncate-error-division-by-zero = division par zéro
truncate-error-cannot-stat-no-such-file = impossible d'obtenir les informations de { $filename } : Aucun fichier ou répertoire de ce type

View file

@ -5,6 +5,7 @@
// spell-checker:ignore (ToDO) RFILE refsize rfilename fsize tsize // spell-checker:ignore (ToDO) RFILE refsize rfilename fsize tsize
use clap::{Arg, ArgAction, Command}; use clap::{Arg, ArgAction, Command};
use std::collections::HashMap;
use std::fs::{OpenOptions, metadata}; use std::fs::{OpenOptions, metadata};
use std::io::ErrorKind; use std::io::ErrorKind;
#[cfg(unix)] #[cfg(unix)]
@ -13,7 +14,7 @@ use std::path::Path;
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::format_usage; use uucore::format_usage;
use uucore::locale::get_message; use uucore::locale::{get_message, get_message_with_args};
use uucore::parser::parse_size::{ParseSizeError, parse_size_u64}; use uucore::parser::parse_size::{ParseSizeError, parse_size_u64};
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
@ -99,7 +100,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
.unwrap_or_default(); .unwrap_or_default();
if files.is_empty() { if files.is_empty() {
Err(UUsageError::new(1, "missing file operand")) Err(UUsageError::new(
1,
get_message("truncate-error-missing-file-operand"),
))
} else { } else {
let io_blocks = matches.get_flag(options::IO_BLOCKS); let io_blocks = matches.get_flag(options::IO_BLOCKS);
let no_create = matches.get_flag(options::NO_CREATE); let no_create = matches.get_flag(options::NO_CREATE);
@ -121,17 +125,14 @@ pub fn uu_app() -> Command {
Arg::new(options::IO_BLOCKS) Arg::new(options::IO_BLOCKS)
.short('o') .short('o')
.long(options::IO_BLOCKS) .long(options::IO_BLOCKS)
.help( .help(get_message("truncate-help-io-blocks"))
"treat SIZE as the number of I/O blocks of the file rather than bytes \
(NOT IMPLEMENTED)",
)
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
Arg::new(options::NO_CREATE) Arg::new(options::NO_CREATE)
.short('c') .short('c')
.long(options::NO_CREATE) .long(options::NO_CREATE)
.help("do not create files that do not exist") .help(get_message("truncate-help-no-create"))
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
@ -139,7 +140,7 @@ pub fn uu_app() -> Command {
.short('r') .short('r')
.long(options::REFERENCE) .long(options::REFERENCE)
.required_unless_present(options::SIZE) .required_unless_present(options::SIZE)
.help("base the size of each file on the size of RFILE") .help(get_message("truncate-help-reference"))
.value_name("RFILE") .value_name("RFILE")
.value_hint(clap::ValueHint::FilePath), .value_hint(clap::ValueHint::FilePath),
) )
@ -148,10 +149,7 @@ pub fn uu_app() -> Command {
.short('s') .short('s')
.long(options::SIZE) .long(options::SIZE)
.required_unless_present(options::REFERENCE) .required_unless_present(options::REFERENCE)
.help( .help(get_message("truncate-help-size"))
"set or adjust the size of each file according to SIZE, which is in \
bytes unless --io-blocks is specified",
)
.value_name("SIZE"), .value_name("SIZE"),
) )
.arg( .arg(
@ -181,20 +179,26 @@ fn file_truncate(filename: &str, create: bool, size: u64) -> UResult<()> {
if metadata.file_type().is_fifo() { if metadata.file_type().is_fifo() {
return Err(USimpleError::new( return Err(USimpleError::new(
1, 1,
format!( get_message_with_args(
"cannot open {} for writing: No such device or address", "truncate-error-cannot-open-no-device",
filename.quote() HashMap::from([("filename".to_string(), filename.quote().to_string())]),
), ),
)); ));
} }
} }
let path = Path::new(filename); let path = Path::new(filename);
match OpenOptions::new().write(true).create(create).open(path) { match OpenOptions::new().write(true).create(create).open(path) {
Ok(file) => file.set_len(size), Ok(file) => file.set_len(size),
Err(e) if e.kind() == ErrorKind::NotFound && !create => Ok(()), Err(e) if e.kind() == ErrorKind::NotFound && !create => Ok(()),
Err(e) => Err(e), Err(e) => Err(e),
} }
.map_err_context(|| format!("cannot open {} for writing", filename.quote())) .map_err_context(|| {
get_message_with_args(
"truncate-error-cannot-open-for-writing",
HashMap::from([("filename".to_string(), filename.quote().to_string())]),
)
})
} }
/// Truncate files to a size relative to a given file. /// Truncate files to a size relative to a given file.
@ -221,33 +225,49 @@ fn truncate_reference_and_size(
create: bool, create: bool,
) -> UResult<()> { ) -> UResult<()> {
let mode = match parse_mode_and_size(size_string) { let mode = match parse_mode_and_size(size_string) {
Err(e) => return Err(USimpleError::new(1, format!("Invalid number: {e}"))), Err(e) => {
return Err(USimpleError::new(
1,
get_message_with_args(
"truncate-error-invalid-number",
HashMap::from([("error".to_string(), e.to_string())]),
),
));
}
Ok(TruncateMode::Absolute(_)) => { Ok(TruncateMode::Absolute(_)) => {
return Err(USimpleError::new( return Err(USimpleError::new(
1, 1,
String::from("you must specify a relative '--size' with '--reference'"), get_message("truncate-error-must-specify-relative-size"),
)); ));
} }
Ok(m) => m, Ok(m) => m,
}; };
if let TruncateMode::RoundDown(0) | TruncateMode::RoundUp(0) = mode { if let TruncateMode::RoundDown(0) | TruncateMode::RoundUp(0) = mode {
return Err(USimpleError::new(1, "division by zero")); return Err(USimpleError::new(
1,
get_message("truncate-error-division-by-zero"),
));
} }
let metadata = metadata(rfilename).map_err(|e| match e.kind() { let metadata = metadata(rfilename).map_err(|e| match e.kind() {
ErrorKind::NotFound => USimpleError::new( ErrorKind::NotFound => USimpleError::new(
1, 1,
format!( get_message_with_args(
"cannot stat {}: No such file or directory", "truncate-error-cannot-stat-no-such-file",
rfilename.quote() HashMap::from([("filename".to_string(), rfilename.quote().to_string())]),
), ),
), ),
_ => e.map_err_context(String::new), _ => e.map_err_context(String::new),
})?; })?;
let fsize = metadata.len(); let fsize = metadata.len();
let tsize = mode.to_size(fsize); let tsize = mode.to_size(fsize);
for filename in filenames { for filename in filenames {
file_truncate(filename, create, tsize)?; file_truncate(filename, create, tsize)?;
} }
Ok(()) Ok(())
} }
@ -272,17 +292,20 @@ fn truncate_reference_file_only(
let metadata = metadata(rfilename).map_err(|e| match e.kind() { let metadata = metadata(rfilename).map_err(|e| match e.kind() {
ErrorKind::NotFound => USimpleError::new( ErrorKind::NotFound => USimpleError::new(
1, 1,
format!( get_message_with_args(
"cannot stat {}: No such file or directory", "truncate-error-cannot-stat-no-such-file",
rfilename.quote() HashMap::from([("filename".to_string(), rfilename.quote().to_string())]),
), ),
), ),
_ => e.map_err_context(String::new), _ => e.map_err_context(String::new),
})?; })?;
let tsize = metadata.len(); let tsize = metadata.len();
for filename in filenames { for filename in filenames {
file_truncate(filename, create, tsize)?; file_truncate(filename, create, tsize)?;
} }
Ok(()) Ok(())
} }
@ -304,11 +327,23 @@ fn truncate_reference_file_only(
/// ///
/// If at least one file is a named pipe (also known as a fifo). /// If at least one file is a named pipe (also known as a fifo).
fn truncate_size_only(size_string: &str, filenames: &[String], create: bool) -> UResult<()> { fn truncate_size_only(size_string: &str, filenames: &[String], create: bool) -> UResult<()> {
let mode = parse_mode_and_size(size_string) let mode = parse_mode_and_size(size_string).map_err(|e| {
.map_err(|e| USimpleError::new(1, format!("Invalid number: {e}")))?; USimpleError::new(
1,
get_message_with_args(
"truncate-error-invalid-number",
HashMap::from([("error".to_string(), e.to_string())]),
),
)
})?;
if let TruncateMode::RoundDown(0) | TruncateMode::RoundUp(0) = mode { if let TruncateMode::RoundDown(0) | TruncateMode::RoundUp(0) = mode {
return Err(USimpleError::new(1, "division by zero")); return Err(USimpleError::new(
1,
get_message("truncate-error-division-by-zero"),
));
} }
for filename in filenames { for filename in filenames {
let fsize = match metadata(filename) { let fsize = match metadata(filename) {
Ok(m) => { Ok(m) => {
@ -316,9 +351,9 @@ fn truncate_size_only(size_string: &str, filenames: &[String], create: bool) ->
if m.file_type().is_fifo() { if m.file_type().is_fifo() {
return Err(USimpleError::new( return Err(USimpleError::new(
1, 1,
format!( get_message_with_args(
"cannot open {} for writing: No such device or address", "truncate-error-cannot-open-no-device",
filename.quote() HashMap::from([("filename".to_string(), filename.quote().to_string())]),
), ),
)); ));
} }
@ -330,6 +365,7 @@ fn truncate_size_only(size_string: &str, filenames: &[String], create: bool) ->
// TODO: Fix duplicate call to stat // TODO: Fix duplicate call to stat
file_truncate(filename, create, tsize)?; file_truncate(filename, create, tsize)?;
} }
Ok(()) Ok(())
} }
@ -341,6 +377,7 @@ fn truncate(
filenames: &[String], filenames: &[String],
) -> UResult<()> { ) -> UResult<()> {
let create = !no_create; let create = !no_create;
// There are four possibilities // There are four possibilities
// - reference file given and size given, // - reference file given and size given,
// - reference file given but no size given, // - reference file given but no size given,