mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #8111 from sylvestre/l10n-truncate
l10n: port truncate to translation + add french
This commit is contained in:
commit
78ee52de0f
3 changed files with 116 additions and 31 deletions
|
@ -16,3 +16,18 @@ truncate-after-help = SIZE is an integer with an optional prefix and optional un
|
|||
'>' => at least
|
||||
'/' => round down 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
|
||||
|
|
33
src/uu/truncate/locales/fr-FR.ftl
Normal file
33
src/uu/truncate/locales/fr-FR.ftl
Normal 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
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
// spell-checker:ignore (ToDO) RFILE refsize rfilename fsize tsize
|
||||
use clap::{Arg, ArgAction, Command};
|
||||
use std::collections::HashMap;
|
||||
use std::fs::{OpenOptions, metadata};
|
||||
use std::io::ErrorKind;
|
||||
#[cfg(unix)]
|
||||
|
@ -13,7 +14,7 @@ use std::path::Path;
|
|||
use uucore::display::Quotable;
|
||||
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
|
||||
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};
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
|
@ -99,7 +100,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
.unwrap_or_default();
|
||||
|
||||
if files.is_empty() {
|
||||
Err(UUsageError::new(1, "missing file operand"))
|
||||
Err(UUsageError::new(
|
||||
1,
|
||||
get_message("truncate-error-missing-file-operand"),
|
||||
))
|
||||
} else {
|
||||
let io_blocks = matches.get_flag(options::IO_BLOCKS);
|
||||
let no_create = matches.get_flag(options::NO_CREATE);
|
||||
|
@ -121,17 +125,14 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::IO_BLOCKS)
|
||||
.short('o')
|
||||
.long(options::IO_BLOCKS)
|
||||
.help(
|
||||
"treat SIZE as the number of I/O blocks of the file rather than bytes \
|
||||
(NOT IMPLEMENTED)",
|
||||
)
|
||||
.help(get_message("truncate-help-io-blocks"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::NO_CREATE)
|
||||
.short('c')
|
||||
.long(options::NO_CREATE)
|
||||
.help("do not create files that do not exist")
|
||||
.help(get_message("truncate-help-no-create"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
|
@ -139,7 +140,7 @@ pub fn uu_app() -> Command {
|
|||
.short('r')
|
||||
.long(options::REFERENCE)
|
||||
.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_hint(clap::ValueHint::FilePath),
|
||||
)
|
||||
|
@ -148,10 +149,7 @@ pub fn uu_app() -> Command {
|
|||
.short('s')
|
||||
.long(options::SIZE)
|
||||
.required_unless_present(options::REFERENCE)
|
||||
.help(
|
||||
"set or adjust the size of each file according to SIZE, which is in \
|
||||
bytes unless --io-blocks is specified",
|
||||
)
|
||||
.help(get_message("truncate-help-size"))
|
||||
.value_name("SIZE"),
|
||||
)
|
||||
.arg(
|
||||
|
@ -181,20 +179,26 @@ fn file_truncate(filename: &str, create: bool, size: u64) -> UResult<()> {
|
|||
if metadata.file_type().is_fifo() {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"cannot open {} for writing: No such device or address",
|
||||
filename.quote()
|
||||
get_message_with_args(
|
||||
"truncate-error-cannot-open-no-device",
|
||||
HashMap::from([("filename".to_string(), filename.quote().to_string())]),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let path = Path::new(filename);
|
||||
match OpenOptions::new().write(true).create(create).open(path) {
|
||||
Ok(file) => file.set_len(size),
|
||||
Err(e) if e.kind() == ErrorKind::NotFound && !create => Ok(()),
|
||||
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.
|
||||
|
@ -221,33 +225,49 @@ fn truncate_reference_and_size(
|
|||
create: bool,
|
||||
) -> UResult<()> {
|
||||
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(_)) => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
String::from("you must specify a relative '--size' with '--reference'"),
|
||||
get_message("truncate-error-must-specify-relative-size"),
|
||||
));
|
||||
}
|
||||
Ok(m) => m,
|
||||
};
|
||||
|
||||
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() {
|
||||
ErrorKind::NotFound => USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"cannot stat {}: No such file or directory",
|
||||
rfilename.quote()
|
||||
get_message_with_args(
|
||||
"truncate-error-cannot-stat-no-such-file",
|
||||
HashMap::from([("filename".to_string(), rfilename.quote().to_string())]),
|
||||
),
|
||||
),
|
||||
_ => e.map_err_context(String::new),
|
||||
})?;
|
||||
|
||||
let fsize = metadata.len();
|
||||
let tsize = mode.to_size(fsize);
|
||||
|
||||
for filename in filenames {
|
||||
file_truncate(filename, create, tsize)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -272,17 +292,20 @@ fn truncate_reference_file_only(
|
|||
let metadata = metadata(rfilename).map_err(|e| match e.kind() {
|
||||
ErrorKind::NotFound => USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"cannot stat {}: No such file or directory",
|
||||
rfilename.quote()
|
||||
get_message_with_args(
|
||||
"truncate-error-cannot-stat-no-such-file",
|
||||
HashMap::from([("filename".to_string(), rfilename.quote().to_string())]),
|
||||
),
|
||||
),
|
||||
_ => e.map_err_context(String::new),
|
||||
})?;
|
||||
|
||||
let tsize = metadata.len();
|
||||
|
||||
for filename in filenames {
|
||||
file_truncate(filename, create, tsize)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -304,11 +327,23 @@ fn truncate_reference_file_only(
|
|||
///
|
||||
/// 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<()> {
|
||||
let mode = parse_mode_and_size(size_string)
|
||||
.map_err(|e| USimpleError::new(1, format!("Invalid number: {e}")))?;
|
||||
let mode = parse_mode_and_size(size_string).map_err(|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 {
|
||||
return Err(USimpleError::new(1, "division by zero"));
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
get_message("truncate-error-division-by-zero"),
|
||||
));
|
||||
}
|
||||
|
||||
for filename in filenames {
|
||||
let fsize = match metadata(filename) {
|
||||
Ok(m) => {
|
||||
|
@ -316,9 +351,9 @@ fn truncate_size_only(size_string: &str, filenames: &[String], create: bool) ->
|
|||
if m.file_type().is_fifo() {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"cannot open {} for writing: No such device or address",
|
||||
filename.quote()
|
||||
get_message_with_args(
|
||||
"truncate-error-cannot-open-no-device",
|
||||
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
|
||||
file_truncate(filename, create, tsize)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -341,6 +377,7 @@ fn truncate(
|
|||
filenames: &[String],
|
||||
) -> UResult<()> {
|
||||
let create = !no_create;
|
||||
|
||||
// There are four possibilities
|
||||
// - reference file given and size given,
|
||||
// - reference file given but no size given,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue