mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
l10n: port sort for translation + add french
This commit is contained in:
parent
05eb7ee374
commit
5be0db5e8c
4 changed files with 361 additions and 96 deletions
|
@ -9,3 +9,75 @@ sort-after-help = The key format is FIELD[.CHAR][OPTIONS][,FIELD[.CHAR]][OPTIONS
|
||||||
If CHAR is set 0, it means the end of the field. CHAR defaults to 1 for the start position and to 0 for the end position.
|
If CHAR is set 0, it means the end of the field. CHAR defaults to 1 for the start position and to 0 for the end position.
|
||||||
|
|
||||||
Valid options are: MbdfhnRrV. They override the global options for this key.
|
Valid options are: MbdfhnRrV. They override the global options for this key.
|
||||||
|
|
||||||
|
# Error messages
|
||||||
|
sort-open-failed = open failed: {$path}: {$error}
|
||||||
|
sort-parse-key-error = failed to parse key {$key}: {$msg}
|
||||||
|
sort-cannot-read = cannot read: {$path}: {$error}
|
||||||
|
sort-open-tmp-file-failed = failed to open temporary file: {$error}
|
||||||
|
sort-compress-prog-execution-failed = couldn't execute compress program: errno {$code}
|
||||||
|
sort-compress-prog-terminated-abnormally = {$prog} terminated abnormally
|
||||||
|
sort-cannot-create-tmp-file = cannot create temporary file in '{$path}':
|
||||||
|
sort-file-operands-combined = extra operand '{$file}'
|
||||||
|
file operands cannot be combined with --files0-from
|
||||||
|
Try '{$help} --help' for more information.
|
||||||
|
sort-multiple-output-files = multiple output files specified
|
||||||
|
sort-minus-in-stdin = when reading file names from stdin, no file name of '-' allowed
|
||||||
|
sort-no-input-from = no input from '{$file}'
|
||||||
|
sort-invalid-zero-length-filename = {$file}:{$line_num}: invalid zero-length file name
|
||||||
|
sort-options-incompatible = options '-{$opt1}{$opt2}' are incompatible
|
||||||
|
sort-invalid-key = invalid key {$key}
|
||||||
|
sort-failed-parse-field-index = failed to parse field index {$field} {$error}
|
||||||
|
sort-field-index-cannot-be-zero = field index can not be 0
|
||||||
|
sort-failed-parse-char-index = failed to parse character index {$char}: {$error}
|
||||||
|
sort-invalid-option = invalid option: '{$option}'
|
||||||
|
sort-invalid-char-index-zero-start = invalid character index 0 for the start position of a field
|
||||||
|
sort-invalid-batch-size-arg = invalid --batch-size argument '{$arg}'
|
||||||
|
sort-minimum-batch-size-two = minimum --batch-size argument is '2'
|
||||||
|
sort-batch-size-too-large = --batch-size argument {$arg} too large
|
||||||
|
sort-maximum-batch-size-rlimit = maximum --batch-size argument with current rlimit is {$rlimit}
|
||||||
|
sort-extra-operand-not-allowed-with-c = extra operand {$operand} not allowed with -c
|
||||||
|
sort-separator-not-valid-unicode = separator is not valid unicode: {$arg}
|
||||||
|
sort-separator-must-be-one-char = separator must be exactly one character long: {$separator}
|
||||||
|
sort-only-one-file-allowed-with-c = only one file allowed with -c
|
||||||
|
sort-failed-fetch-rlimit = Failed to fetch rlimit
|
||||||
|
sort-invalid-suffix-in-option-arg = invalid suffix in --{$option} argument {$arg}
|
||||||
|
sort-invalid-option-arg = invalid --{$option} argument {$arg}
|
||||||
|
sort-option-arg-too-large = --{$option} argument {$arg} too large
|
||||||
|
sort-error-disorder = {$file}:{$line_number}: disorder: {$line}
|
||||||
|
sort-error-buffer-size-too-big = Buffer size {$size} does not fit in address space
|
||||||
|
sort-error-no-match-for-key = ^ no match for key
|
||||||
|
sort-error-write-failed = write failed: {$output}
|
||||||
|
sort-failed-to-delete-temporary-directory = failed to delete temporary directory: {$error}
|
||||||
|
sort-failed-to-set-up-signal-handler = failed to set up signal handler: {$error}
|
||||||
|
|
||||||
|
# Help messages
|
||||||
|
sort-help-help = Print help information.
|
||||||
|
sort-help-version = Print version information.
|
||||||
|
sort-help-human-numeric = compare according to human readable sizes, eg 1M > 100k
|
||||||
|
sort-help-month = compare according to month name abbreviation
|
||||||
|
sort-help-numeric = compare according to string numerical value
|
||||||
|
sort-help-general-numeric = compare according to string general numerical value
|
||||||
|
sort-help-version-sort = Sort by SemVer version number, eg 1.12.2 > 1.1.2
|
||||||
|
sort-help-random = shuffle in random order
|
||||||
|
sort-help-dictionary-order = consider only blanks and alphanumeric characters
|
||||||
|
sort-help-merge = merge already sorted files; do not sort
|
||||||
|
sort-help-check = check for sorted input; do not sort
|
||||||
|
sort-help-check-silent = exit successfully if the given file is already sorted, and exit with status 1 otherwise.
|
||||||
|
sort-help-ignore-case = fold lower case to upper case characters
|
||||||
|
sort-help-ignore-nonprinting = ignore nonprinting characters
|
||||||
|
sort-help-ignore-leading-blanks = ignore leading blanks when finding sort keys in each line
|
||||||
|
sort-help-output = write output to FILENAME instead of stdout
|
||||||
|
sort-help-reverse = reverse the output
|
||||||
|
sort-help-stable = stabilize sort by disabling last-resort comparison
|
||||||
|
sort-help-unique = output only the first of an equal run
|
||||||
|
sort-help-key = sort by a key
|
||||||
|
sort-help-separator = custom separator for -k
|
||||||
|
sort-help-zero-terminated = line delimiter is NUL, not newline
|
||||||
|
sort-help-parallel = change the number of threads running concurrently to NUM_THREADS
|
||||||
|
sort-help-buf-size = sets the maximum SIZE of each segment in number of sorted items
|
||||||
|
sort-help-tmp-dir = use DIR for temporaries, not $TMPDIR or /tmp
|
||||||
|
sort-help-compress-prog = compress temporary files with PROG, decompress with PROG -d; PROG has to take input from stdin and output to stdout
|
||||||
|
sort-help-batch-size = Merge at most N_MERGE inputs at once.
|
||||||
|
sort-help-files0-from = read input from the files specified by NUL-terminated NUL_FILE
|
||||||
|
sort-help-debug = underline the parts of the line that are actually used for sorting
|
||||||
|
|
83
src/uu/sort/locales/fr-FR.ftl
Normal file
83
src/uu/sort/locales/fr-FR.ftl
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
sort-about = Affiche la concaténation triée de tous les FICHIER(s). Sans FICHIER, ou quand FICHIER est -, lit l'entrée standard.
|
||||||
|
sort-usage = sort [OPTION]... [FICHIER]...
|
||||||
|
sort-after-help = Le format de clé est CHAMP[.CAR][OPTIONS][,CHAMP[.CAR]][OPTIONS].
|
||||||
|
|
||||||
|
Les champs sont séparés par défaut par le premier espace blanc après un caractère non-espace. Utilisez -t pour spécifier un séparateur personnalisé.
|
||||||
|
Dans le cas par défaut, les espaces blancs sont ajoutés au début de chaque champ. Les séparateurs personnalisés ne sont cependant pas inclus dans les champs.
|
||||||
|
|
||||||
|
CHAMP et CAR commencent tous deux à 1 (c'est-à-dire qu'ils sont indexés à partir de 1). S'il n'y a pas de fin spécifiée après une virgule, la fin sera la fin de la ligne.
|
||||||
|
Si CAR est défini à 0, cela signifie la fin du champ. CAR par défaut à 1 pour la position de début et à 0 pour la position de fin.
|
||||||
|
|
||||||
|
Les options valides sont : MbdfhnRrV. Elles remplacent les options globales pour cette clé.
|
||||||
|
|
||||||
|
# Messages d'erreur
|
||||||
|
sort-open-failed = échec d'ouverture : {$path} : {$error}
|
||||||
|
sort-parse-key-error = échec d'analyse de la clé {$key} : {$msg}
|
||||||
|
sort-cannot-read = impossible de lire : {$path} : {$error}
|
||||||
|
sort-open-tmp-file-failed = échec d'ouverture du fichier temporaire : {$error}
|
||||||
|
sort-compress-prog-execution-failed = impossible d'exécuter le programme de compression : errno {$code}
|
||||||
|
sort-compress-prog-terminated-abnormally = {$prog} s'est terminé anormalement
|
||||||
|
sort-cannot-create-tmp-file = impossible de créer un fichier temporaire dans '{$path}' :
|
||||||
|
sort-file-operands-combined = opérande supplémentaire '{$file}'
|
||||||
|
les opérandes de fichier ne peuvent pas être combinées avec --files0-from
|
||||||
|
Essayez '{$help} --help' pour plus d'informations.
|
||||||
|
sort-multiple-output-files = plusieurs fichiers de sortie spécifiés
|
||||||
|
sort-minus-in-stdin = lors de la lecture des noms de fichiers depuis stdin, aucun nom de fichier '-' n'est autorisé
|
||||||
|
sort-no-input-from = aucune entrée depuis '{$file}'
|
||||||
|
sort-invalid-zero-length-filename = {$file}:{$line_num} : nom de fichier de longueur zéro invalide
|
||||||
|
sort-options-incompatible = les options '-{$opt1}{$opt2}' sont incompatibles
|
||||||
|
sort-invalid-key = clé invalide {$key}
|
||||||
|
sort-failed-parse-field-index = échec d'analyse de l'index de champ {$field} {$error}
|
||||||
|
sort-field-index-cannot-be-zero = l'index de champ ne peut pas être 0
|
||||||
|
sort-failed-parse-char-index = échec d'analyse de l'index de caractère {$char} : {$error}
|
||||||
|
sort-invalid-option = option invalide : '{$option}'
|
||||||
|
sort-invalid-char-index-zero-start = index de caractère 0 invalide pour la position de début d'un champ
|
||||||
|
sort-invalid-batch-size-arg = argument --batch-size invalide '{$arg}'
|
||||||
|
sort-minimum-batch-size-two = l'argument --batch-size minimum est '2'
|
||||||
|
sort-batch-size-too-large = argument --batch-size {$arg} trop grand
|
||||||
|
sort-maximum-batch-size-rlimit = argument --batch-size maximum avec la rlimit actuelle est {$rlimit}
|
||||||
|
sort-extra-operand-not-allowed-with-c = opérande supplémentaire {$operand} non autorisée avec -c
|
||||||
|
sort-separator-not-valid-unicode = le séparateur n'est pas un unicode valide : {$arg}
|
||||||
|
sort-separator-must-be-one-char = le séparateur doit faire exactement un caractère de long : {$separator}
|
||||||
|
sort-only-one-file-allowed-with-c = un seul fichier autorisé avec -c
|
||||||
|
sort-failed-fetch-rlimit = Échec de récupération de rlimit
|
||||||
|
sort-invalid-suffix-in-option-arg = suffixe invalide dans l'argument --{$option} {$arg}
|
||||||
|
sort-invalid-option-arg = argument --{$option} invalide {$arg}
|
||||||
|
sort-option-arg-too-large = argument --{$option} {$arg} trop grand
|
||||||
|
sort-error-disorder = {$file}:{$line_number}: désordre : {$line}
|
||||||
|
sort-error-buffer-size-too-big = La taille du tampon {$size} ne rentre pas dans l'espace d'adressage
|
||||||
|
sort-error-no-match-for-key = ^ aucune correspondance pour la clé
|
||||||
|
sort-error-write-failed = échec d'écriture : {$output}
|
||||||
|
sort-failed-to-delete-temporary-directory = échec de suppression du répertoire temporaire : {$error}
|
||||||
|
sort-failed-to-set-up-signal-handler = échec de configuration du gestionnaire de signal : {$error}
|
||||||
|
|
||||||
|
# Messages d'aide
|
||||||
|
sort-help-help = Affiche les informations d'aide.
|
||||||
|
sort-help-version = Affiche les informations de version.
|
||||||
|
sort-help-human-numeric = compare selon les tailles lisibles par l'humain, par ex. 1M > 100k
|
||||||
|
sort-help-month = compare selon l'abréviation du nom du mois
|
||||||
|
sort-help-numeric = compare selon la valeur numérique de la chaîne
|
||||||
|
sort-help-general-numeric = compare selon la valeur numérique générale de la chaîne
|
||||||
|
sort-help-version-sort = Trie par numéro de version SemVer, par ex. 1.12.2 > 1.1.2
|
||||||
|
sort-help-random = mélange dans un ordre aléatoire
|
||||||
|
sort-help-dictionary-order = considère seulement les espaces et les caractères alphanumériques
|
||||||
|
sort-help-merge = fusionne les fichiers déjà triés ; ne trie pas
|
||||||
|
sort-help-check = vérifie l'entrée triée ; ne trie pas
|
||||||
|
sort-help-check-silent = réussit si le fichier donné est déjà trié, et sort avec le statut 1 sinon.
|
||||||
|
sort-help-ignore-case = convertit les caractères minuscules en majuscules
|
||||||
|
sort-help-ignore-nonprinting = ignore les caractères non-imprimables
|
||||||
|
sort-help-ignore-leading-blanks = ignore les espaces de début lors de la recherche de clés de tri dans chaque ligne
|
||||||
|
sort-help-output = écrit la sortie vers NOMFICHIER au lieu de stdout
|
||||||
|
sort-help-reverse = inverse la sortie
|
||||||
|
sort-help-stable = stabilise le tri en désactivant la comparaison de dernier recours
|
||||||
|
sort-help-unique = affiche seulement le premier d'une série égale
|
||||||
|
sort-help-key = trie par une clé
|
||||||
|
sort-help-separator = séparateur personnalisé pour -k
|
||||||
|
sort-help-zero-terminated = le délimiteur de ligne est NUL, pas nouvelle ligne
|
||||||
|
sort-help-parallel = change le nombre de threads s'exécutant simultanément vers NUM_THREADS
|
||||||
|
sort-help-buf-size = définit la TAILLE maximale de chaque segment en nombre d'éléments triés
|
||||||
|
sort-help-tmp-dir = utilise RÉP pour les temporaires, pas $TMPDIR ou /tmp
|
||||||
|
sort-help-compress-prog = compresse les fichiers temporaires avec PROG, décompresse avec PROG -d ; PROG doit prendre l'entrée depuis stdin et sortir vers stdout
|
||||||
|
sort-help-batch-size = Fusionne au maximum N_MERGE entrées à la fois.
|
||||||
|
sort-help-files0-from = lit l'entrée depuis les fichiers spécifiés par FICHIER_NUL terminé par NUL
|
||||||
|
sort-help-debug = souligne les parties de la ligne qui sont réellement utilisées pour le tri
|
|
@ -30,6 +30,7 @@ use numeric_str_cmp::{NumInfo, NumInfoParseSettings, human_numeric_str_cmp, nume
|
||||||
use rand::{Rng, rng};
|
use rand::{Rng, rng};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
|
@ -55,7 +56,7 @@ use uucore::{format_usage, show_error};
|
||||||
|
|
||||||
use crate::tmp_dir::TmpDirWrapper;
|
use crate::tmp_dir::TmpDirWrapper;
|
||||||
|
|
||||||
use uucore::locale::get_message;
|
use uucore::locale::{get_message, get_message_with_args};
|
||||||
|
|
||||||
mod options {
|
mod options {
|
||||||
pub mod modes {
|
pub mod modes {
|
||||||
|
@ -131,49 +132,49 @@ pub enum SortError {
|
||||||
silent: bool,
|
silent: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("open failed: {}: {}", .path.maybe_quote(), strip_errno(.error))]
|
#[error("{}", get_message_with_args("sort-open-failed", HashMap::from([("path".to_string(), format!("{}", .path.maybe_quote())), ("error".to_string(), strip_errno(.error))])))]
|
||||||
OpenFailed {
|
OpenFailed {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
error: std::io::Error,
|
error: std::io::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("failed to parse key {}: {}", .key.quote(), .msg)]
|
#[error("{}", get_message_with_args("sort-parse-key-error", HashMap::from([("key".to_string(), .key.quote().to_string()), ("msg".to_string(), .msg.clone())])))]
|
||||||
ParseKeyError { key: String, msg: String },
|
ParseKeyError { key: String, msg: String },
|
||||||
|
|
||||||
#[error("cannot read: {}: {}", .path.maybe_quote(), strip_errno(.error))]
|
#[error("{}", get_message_with_args("sort-cannot-read", HashMap::from([("path".to_string(), format!("{}", .path.maybe_quote())), ("error".to_string(), strip_errno(.error))])))]
|
||||||
ReadFailed {
|
ReadFailed {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
error: std::io::Error,
|
error: std::io::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("failed to open temporary file: {}", strip_errno(.error))]
|
#[error("{}", get_message_with_args("sort-open-tmp-file-failed", HashMap::from([("error".to_string(), strip_errno(.error))])))]
|
||||||
OpenTmpFileFailed { error: std::io::Error },
|
OpenTmpFileFailed { error: std::io::Error },
|
||||||
|
|
||||||
#[error("couldn't execute compress program: errno {code}")]
|
#[error("{}", get_message_with_args("sort-compress-prog-execution-failed", HashMap::from([("code".to_string(), .code.to_string())])))]
|
||||||
CompressProgExecutionFailed { code: i32 },
|
CompressProgExecutionFailed { code: i32 },
|
||||||
|
|
||||||
#[error("{} terminated abnormally", .prog.quote())]
|
#[error("{}", get_message_with_args("sort-compress-prog-terminated-abnormally", HashMap::from([("prog".to_string(), .prog.quote().to_string())])))]
|
||||||
CompressProgTerminatedAbnormally { prog: String },
|
CompressProgTerminatedAbnormally { prog: String },
|
||||||
|
|
||||||
#[error("cannot create temporary file in '{}':", .path.display())]
|
#[error("{}", get_message_with_args("sort-cannot-create-tmp-file", HashMap::from([("path".to_string(), format!("{}", .path.display()))])))]
|
||||||
TmpFileCreationFailed { path: PathBuf },
|
TmpFileCreationFailed { path: PathBuf },
|
||||||
|
|
||||||
#[error("extra operand '{}'\nfile operands cannot be combined with --files0-from\nTry '{} --help' for more information.", .file.display(), uucore::execution_phrase())]
|
#[error("{}", get_message_with_args("sort-file-operands-combined", HashMap::from([("file".to_string(), format!("{}", .file.display())), ("help".to_string(), uucore::execution_phrase().to_string())])))]
|
||||||
FileOperandsCombined { file: PathBuf },
|
FileOperandsCombined { file: PathBuf },
|
||||||
|
|
||||||
#[error("{error}")]
|
#[error("{error}")]
|
||||||
Uft8Error { error: Utf8Error },
|
Uft8Error { error: Utf8Error },
|
||||||
|
|
||||||
#[error("multiple output files specified")]
|
#[error("{}", get_message("sort-multiple-output-files"))]
|
||||||
MultipleOutputFiles,
|
MultipleOutputFiles,
|
||||||
|
|
||||||
#[error("when reading file names from stdin, no file name of '-' allowed")]
|
#[error("{}", get_message("sort-minus-in-stdin"))]
|
||||||
MinusInStdIn,
|
MinusInStdIn,
|
||||||
|
|
||||||
#[error("no input from '{}'", .file.display())]
|
#[error("{}", get_message_with_args("sort-no-input-from", HashMap::from([("file".to_string(), format!("{}", .file.display()))])))]
|
||||||
EmptyInputFile { file: PathBuf },
|
EmptyInputFile { file: PathBuf },
|
||||||
|
|
||||||
#[error("{}:{}: invalid zero-length file name", .file.display(), .line_num)]
|
#[error("{}", get_message_with_args("sort-invalid-zero-length-filename", HashMap::from([("file".to_string(), format!("{}", .file.display())), ("line_num".to_string(), .line_num.to_string())])))]
|
||||||
ZeroLengthFileName { file: PathBuf, line_num: usize },
|
ZeroLengthFileName { file: PathBuf, line_num: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +191,14 @@ fn format_disorder(file: &OsString, line_number: &usize, line: &String, silent:
|
||||||
if *silent {
|
if *silent {
|
||||||
String::new()
|
String::new()
|
||||||
} else {
|
} else {
|
||||||
format!("{}:{}: disorder: {line}", file.maybe_quote(), line_number)
|
get_message_with_args(
|
||||||
|
"sort-error-disorder",
|
||||||
|
HashMap::from([
|
||||||
|
("file".to_string(), file.maybe_quote().to_string()),
|
||||||
|
("line_number".to_string(), line_number.to_string()),
|
||||||
|
("line".to_string(), line.to_owned()),
|
||||||
|
]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +324,10 @@ impl GlobalSettings {
|
||||||
.parse(input.trim())?;
|
.parse(input.trim())?;
|
||||||
|
|
||||||
usize::try_from(size).map_err(|_| {
|
usize::try_from(size).map_err(|_| {
|
||||||
ParseSizeError::SizeTooBig(format!("Buffer size {size} does not fit in address space"))
|
ParseSizeError::SizeTooBig(get_message_with_args(
|
||||||
|
"sort-error-buffer-size-too-big",
|
||||||
|
HashMap::from([("size".to_string(), size.to_string())]),
|
||||||
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,16 +401,26 @@ impl KeySettings {
|
||||||
SortMode::Numeric | SortMode::HumanNumeric | SortMode::GeneralNumeric | SortMode::Month
|
SortMode::Numeric | SortMode::HumanNumeric | SortMode::GeneralNumeric | SortMode::Month
|
||||||
) {
|
) {
|
||||||
if dictionary_order {
|
if dictionary_order {
|
||||||
return Err(format!(
|
return Err(get_message_with_args(
|
||||||
"options '-{}{}' are incompatible",
|
"sort-options-incompatible",
|
||||||
'd',
|
HashMap::from([
|
||||||
mode.get_short_name().unwrap()
|
("opt1".to_string(), "d".to_string()),
|
||||||
|
(
|
||||||
|
"opt2".to_string(),
|
||||||
|
mode.get_short_name().unwrap().to_string(),
|
||||||
|
),
|
||||||
|
]),
|
||||||
));
|
));
|
||||||
} else if ignore_non_printing {
|
} else if ignore_non_printing {
|
||||||
return Err(format!(
|
return Err(get_message_with_args(
|
||||||
"options '-{}{}' are incompatible",
|
"sort-options-incompatible",
|
||||||
'i',
|
HashMap::from([
|
||||||
mode.get_short_name().unwrap()
|
("opt1".to_string(), "i".to_string()),
|
||||||
|
(
|
||||||
|
"opt2".to_string(),
|
||||||
|
mode.get_short_name().unwrap().to_string(),
|
||||||
|
),
|
||||||
|
]),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -408,10 +429,18 @@ impl KeySettings {
|
||||||
|
|
||||||
fn set_sort_mode(&mut self, mode: SortMode) -> Result<(), String> {
|
fn set_sort_mode(&mut self, mode: SortMode) -> Result<(), String> {
|
||||||
if self.mode != SortMode::Default && self.mode != mode {
|
if self.mode != SortMode::Default && self.mode != mode {
|
||||||
return Err(format!(
|
return Err(get_message_with_args(
|
||||||
"options '-{}{}' are incompatible",
|
"sort-options-incompatible",
|
||||||
self.mode.get_short_name().unwrap(),
|
HashMap::from([
|
||||||
mode.get_short_name().unwrap()
|
(
|
||||||
|
"opt1".to_string(),
|
||||||
|
self.mode.get_short_name().unwrap().to_string(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"opt2".to_string(),
|
||||||
|
mode.get_short_name().unwrap().to_string(),
|
||||||
|
),
|
||||||
|
]),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Self::check_compatibility(mode, self.ignore_non_printing, self.dictionary_order)?;
|
Self::check_compatibility(mode, self.ignore_non_printing, self.dictionary_order)?;
|
||||||
|
@ -624,7 +653,7 @@ impl<'a> Line<'a> {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if selection.is_empty() {
|
if selection.is_empty() {
|
||||||
writeln!(writer, "^ no match for key")?;
|
writeln!(writer, "{}", get_message("sort-error-no-match-for-key"))?;
|
||||||
} else {
|
} else {
|
||||||
writeln!(
|
writeln!(
|
||||||
writer,
|
writer,
|
||||||
|
@ -649,7 +678,7 @@ impl<'a> Line<'a> {
|
||||||
{
|
{
|
||||||
// A last resort comparator is in use, underline the whole line.
|
// A last resort comparator is in use, underline the whole line.
|
||||||
if self.line.is_empty() {
|
if self.line.is_empty() {
|
||||||
writeln!(writer, "^ no match for key")?;
|
writeln!(writer, "{}", get_message("sort-error-no-match-for-key"))?;
|
||||||
} else {
|
} else {
|
||||||
writeln!(
|
writeln!(
|
||||||
writer,
|
writer,
|
||||||
|
@ -722,25 +751,41 @@ impl KeyPosition {
|
||||||
fn new(key: &str, default_char_index: usize, ignore_blanks: bool) -> Result<Self, String> {
|
fn new(key: &str, default_char_index: usize, ignore_blanks: bool) -> Result<Self, String> {
|
||||||
let mut field_and_char = key.split('.');
|
let mut field_and_char = key.split('.');
|
||||||
|
|
||||||
let field = field_and_char
|
let field = field_and_char.next().ok_or_else(|| {
|
||||||
.next()
|
get_message_with_args(
|
||||||
.ok_or_else(|| format!("invalid key {}", key.quote()))?;
|
"sort-invalid-key",
|
||||||
|
HashMap::from([("key".to_string(), key.quote().to_string())]),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
let char = field_and_char.next();
|
let char = field_and_char.next();
|
||||||
|
|
||||||
let field = match field.parse::<usize>() {
|
let field = match field.parse::<usize>() {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(e) if *e.kind() == IntErrorKind::PosOverflow => usize::MAX,
|
Err(e) if *e.kind() == IntErrorKind::PosOverflow => usize::MAX,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(format!("failed to parse field index {} {e}", field.quote(),));
|
return Err(get_message_with_args(
|
||||||
|
"sort-failed-parse-field-index",
|
||||||
|
HashMap::from([
|
||||||
|
("field".to_string(), field.quote().to_string()),
|
||||||
|
("error".to_string(), e.to_string()),
|
||||||
|
]),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if field == 0 {
|
if field == 0 {
|
||||||
return Err("field index can not be 0".to_string());
|
return Err(get_message("sort-field-index-cannot-be-zero"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let char = char.map_or(Ok(default_char_index), |char| {
|
let char = char.map_or(Ok(default_char_index), |char| {
|
||||||
char.parse()
|
char.parse().map_err(|e: std::num::ParseIntError| {
|
||||||
.map_err(|e| format!("failed to parse character index {}: {e}", char.quote()))
|
get_message_with_args(
|
||||||
|
"sort-failed-parse-char-index",
|
||||||
|
HashMap::from([
|
||||||
|
("char".to_string(), char.quote().to_string()),
|
||||||
|
("error".to_string(), e.to_string()),
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -839,7 +884,12 @@ impl FieldSelector {
|
||||||
'R' => key_settings.set_sort_mode(SortMode::Random)?,
|
'R' => key_settings.set_sort_mode(SortMode::Random)?,
|
||||||
'r' => key_settings.reverse = true,
|
'r' => key_settings.reverse = true,
|
||||||
'V' => key_settings.set_sort_mode(SortMode::Version)?,
|
'V' => key_settings.set_sort_mode(SortMode::Version)?,
|
||||||
c => return Err(format!("invalid option: '{c}'")),
|
c => {
|
||||||
|
return Err(get_message_with_args(
|
||||||
|
"sort-invalid-option",
|
||||||
|
HashMap::from([("option".to_string(), c.to_string())]),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(ignore_blanks)
|
Ok(ignore_blanks)
|
||||||
|
@ -865,7 +915,7 @@ impl FieldSelector {
|
||||||
settings: KeySettings,
|
settings: KeySettings,
|
||||||
) -> Result<Self, String> {
|
) -> Result<Self, String> {
|
||||||
if from.char == 0 {
|
if from.char == 0 {
|
||||||
Err("invalid character index 0 for the start position of a field".to_string())
|
Err(get_message("sort-invalid-char-index-zero-start"))
|
||||||
} else {
|
} else {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
needs_selection: (from.field != 1
|
needs_selection: (from.field != 1
|
||||||
|
@ -1007,7 +1057,7 @@ impl FieldSelector {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an `Arg` that conflicts with all other sort modes.
|
/// Creates an `Arg` that conflicts with all other sort modes.
|
||||||
fn make_sort_mode_arg(mode: &'static str, short: char, help: &'static str) -> Arg {
|
fn make_sort_mode_arg(mode: &'static str, short: char, help: String) -> Arg {
|
||||||
let mut arg = Arg::new(mode)
|
let mut arg = Arg::new(mode)
|
||||||
.short(short)
|
.short(short)
|
||||||
.long(mode)
|
.long(mode)
|
||||||
|
@ -1029,7 +1079,7 @@ fn get_rlimit() -> UResult<usize> {
|
||||||
};
|
};
|
||||||
match unsafe { getrlimit(RLIMIT_NOFILE, &mut limit) } {
|
match unsafe { getrlimit(RLIMIT_NOFILE, &mut limit) } {
|
||||||
0 => Ok(limit.rlim_cur as usize),
|
0 => Ok(limit.rlim_cur as usize),
|
||||||
_ => Err(UUsageError::new(2, "Failed to fetch rlimit")),
|
_ => Err(UUsageError::new(2, get_message("sort-failed-fetch-rlimit"))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1200,8 +1250,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
match n_merge.parse::<usize>() {
|
match n_merge.parse::<usize>() {
|
||||||
Ok(parsed_value) => {
|
Ok(parsed_value) => {
|
||||||
if parsed_value < 2 {
|
if parsed_value < 2 {
|
||||||
show_error!("invalid --batch-size argument '{n_merge}'");
|
show_error!(
|
||||||
return Err(UUsageError::new(2, "minimum --batch-size argument is '2'"));
|
"{}",
|
||||||
|
get_message_with_args(
|
||||||
|
"sort-invalid-batch-size-arg",
|
||||||
|
HashMap::from([("arg".to_string(), n_merge.to_string())])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return Err(UUsageError::new(
|
||||||
|
2,
|
||||||
|
get_message("sort-minimum-batch-size-two"),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
settings.merge_batch_size = parsed_value;
|
settings.merge_batch_size = parsed_value;
|
||||||
}
|
}
|
||||||
|
@ -1209,19 +1268,31 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let error_message = if *e.kind() == IntErrorKind::PosOverflow {
|
let error_message = if *e.kind() == IntErrorKind::PosOverflow {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
show_error!("--batch-size argument {} too large", n_merge.quote());
|
show_error!(
|
||||||
|
"{}",
|
||||||
|
get_message_with_args(
|
||||||
|
"sort-batch-size-too-large",
|
||||||
|
HashMap::from([("arg".to_string(), n_merge.quote().to_string())])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
format!(
|
get_message_with_args(
|
||||||
"maximum --batch-size argument with current rlimit is {}",
|
"sort-maximum-batch-size-rlimit",
|
||||||
get_rlimit()?
|
HashMap::from([("rlimit".to_string(), get_rlimit()?.to_string())]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
{
|
{
|
||||||
format!("--batch-size argument {} too large", n_merge.quote())
|
get_message_with_args(
|
||||||
|
"sort-batch-size-too-large",
|
||||||
|
HashMap::from([("arg".to_string(), n_merge.quote().to_string())]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
format!("invalid --batch-size argument {}", n_merge.quote())
|
get_message_with_args(
|
||||||
|
"sort-invalid-batch-size-arg",
|
||||||
|
HashMap::from([("arg".to_string(), n_merge.to_string())]),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
return Err(UUsageError::new(2, error_message));
|
return Err(UUsageError::new(2, error_message));
|
||||||
|
@ -1259,7 +1330,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
} else if settings.check && files.len() != 1 {
|
} else if settings.check && files.len() != 1 {
|
||||||
return Err(UUsageError::new(
|
return Err(UUsageError::new(
|
||||||
2,
|
2,
|
||||||
format!("extra operand {} not allowed with -c", files[1].quote()),
|
get_message_with_args(
|
||||||
|
"sort-extra-operand-not-allowed-with-c",
|
||||||
|
HashMap::from([("operand".to_string(), files[1].quote().to_string())]),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1267,7 +1341,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let mut separator = arg.to_str().ok_or_else(|| {
|
let mut separator = arg.to_str().ok_or_else(|| {
|
||||||
UUsageError::new(
|
UUsageError::new(
|
||||||
2,
|
2,
|
||||||
format!("separator is not valid unicode: {}", arg.quote()),
|
get_message_with_args(
|
||||||
|
"sort-separator-not-valid-unicode",
|
||||||
|
HashMap::from([("arg".to_string(), arg.quote().to_string())]),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
if separator == "\\0" {
|
if separator == "\\0" {
|
||||||
|
@ -1279,9 +1356,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
if separator.len() != 1 {
|
if separator.len() != 1 {
|
||||||
return Err(UUsageError::new(
|
return Err(UUsageError::new(
|
||||||
2,
|
2,
|
||||||
format!(
|
get_message_with_args(
|
||||||
"separator must be exactly one character long: {}",
|
"sort-separator-must-be-one-char",
|
||||||
separator.quote()
|
HashMap::from([("separator".to_string(), separator.quote().to_string())]),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -1351,13 +1428,13 @@ pub fn uu_app() -> Command {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::HELP)
|
Arg::new(options::HELP)
|
||||||
.long(options::HELP)
|
.long(options::HELP)
|
||||||
.help("Print help information.")
|
.help(get_message("sort-help-help"))
|
||||||
.action(ArgAction::Help),
|
.action(ArgAction::Help),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::VERSION)
|
Arg::new(options::VERSION)
|
||||||
.long(options::VERSION)
|
.long(options::VERSION)
|
||||||
.help("Print version information.")
|
.help(get_message("sort-help-version"))
|
||||||
.action(ArgAction::Version),
|
.action(ArgAction::Version),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -1376,38 +1453,38 @@ pub fn uu_app() -> Command {
|
||||||
.arg(make_sort_mode_arg(
|
.arg(make_sort_mode_arg(
|
||||||
options::modes::HUMAN_NUMERIC,
|
options::modes::HUMAN_NUMERIC,
|
||||||
'h',
|
'h',
|
||||||
"compare according to human readable sizes, eg 1M > 100k",
|
get_message("sort-help-human-numeric"),
|
||||||
))
|
))
|
||||||
.arg(make_sort_mode_arg(
|
.arg(make_sort_mode_arg(
|
||||||
options::modes::MONTH,
|
options::modes::MONTH,
|
||||||
'M',
|
'M',
|
||||||
"compare according to month name abbreviation",
|
get_message("sort-help-month"),
|
||||||
))
|
))
|
||||||
.arg(make_sort_mode_arg(
|
.arg(make_sort_mode_arg(
|
||||||
options::modes::NUMERIC,
|
options::modes::NUMERIC,
|
||||||
'n',
|
'n',
|
||||||
"compare according to string numerical value",
|
get_message("sort-help-numeric"),
|
||||||
))
|
))
|
||||||
.arg(make_sort_mode_arg(
|
.arg(make_sort_mode_arg(
|
||||||
options::modes::GENERAL_NUMERIC,
|
options::modes::GENERAL_NUMERIC,
|
||||||
'g',
|
'g',
|
||||||
"compare according to string general numerical value",
|
get_message("sort-help-general-numeric"),
|
||||||
))
|
))
|
||||||
.arg(make_sort_mode_arg(
|
.arg(make_sort_mode_arg(
|
||||||
options::modes::VERSION,
|
options::modes::VERSION,
|
||||||
'V',
|
'V',
|
||||||
"Sort by SemVer version number, eg 1.12.2 > 1.1.2",
|
get_message("sort-help-version-sort"),
|
||||||
))
|
))
|
||||||
.arg(make_sort_mode_arg(
|
.arg(make_sort_mode_arg(
|
||||||
options::modes::RANDOM,
|
options::modes::RANDOM,
|
||||||
'R',
|
'R',
|
||||||
"shuffle in random order",
|
get_message("sort-help-random"),
|
||||||
))
|
))
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::DICTIONARY_ORDER)
|
Arg::new(options::DICTIONARY_ORDER)
|
||||||
.short('d')
|
.short('d')
|
||||||
.long(options::DICTIONARY_ORDER)
|
.long(options::DICTIONARY_ORDER)
|
||||||
.help("consider only blanks and alphanumeric characters")
|
.help(get_message("sort-help-dictionary-order"))
|
||||||
.conflicts_with_all([
|
.conflicts_with_all([
|
||||||
options::modes::NUMERIC,
|
options::modes::NUMERIC,
|
||||||
options::modes::GENERAL_NUMERIC,
|
options::modes::GENERAL_NUMERIC,
|
||||||
|
@ -1420,7 +1497,7 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(options::MERGE)
|
Arg::new(options::MERGE)
|
||||||
.short('m')
|
.short('m')
|
||||||
.long(options::MERGE)
|
.long(options::MERGE)
|
||||||
.help("merge already sorted files; do not sort")
|
.help(get_message("sort-help-merge"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -1435,31 +1512,28 @@ pub fn uu_app() -> Command {
|
||||||
options::check::DIAGNOSE_FIRST,
|
options::check::DIAGNOSE_FIRST,
|
||||||
]))
|
]))
|
||||||
.conflicts_with_all([options::OUTPUT, options::check::CHECK_SILENT])
|
.conflicts_with_all([options::OUTPUT, options::check::CHECK_SILENT])
|
||||||
.help("check for sorted input; do not sort"),
|
.help(get_message("sort-help-check")),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::check::CHECK_SILENT)
|
Arg::new(options::check::CHECK_SILENT)
|
||||||
.short('C')
|
.short('C')
|
||||||
.long(options::check::CHECK_SILENT)
|
.long(options::check::CHECK_SILENT)
|
||||||
.conflicts_with_all([options::OUTPUT, options::check::CHECK])
|
.conflicts_with_all([options::OUTPUT, options::check::CHECK])
|
||||||
.help(
|
.help(get_message("sort-help-check-silent"))
|
||||||
"exit successfully if the given file is already sorted, \
|
|
||||||
and exit with status 1 otherwise.",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::IGNORE_CASE)
|
Arg::new(options::IGNORE_CASE)
|
||||||
.short('f')
|
.short('f')
|
||||||
.long(options::IGNORE_CASE)
|
.long(options::IGNORE_CASE)
|
||||||
.help("fold lower case to upper case characters")
|
.help(get_message("sort-help-ignore-case"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::IGNORE_NONPRINTING)
|
Arg::new(options::IGNORE_NONPRINTING)
|
||||||
.short('i')
|
.short('i')
|
||||||
.long(options::IGNORE_NONPRINTING)
|
.long(options::IGNORE_NONPRINTING)
|
||||||
.help("ignore nonprinting characters")
|
.help(get_message("sort-help-ignore-nonprinting"))
|
||||||
.conflicts_with_all([
|
.conflicts_with_all([
|
||||||
options::modes::NUMERIC,
|
options::modes::NUMERIC,
|
||||||
options::modes::GENERAL_NUMERIC,
|
options::modes::GENERAL_NUMERIC,
|
||||||
|
@ -1472,14 +1546,14 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(options::IGNORE_LEADING_BLANKS)
|
Arg::new(options::IGNORE_LEADING_BLANKS)
|
||||||
.short('b')
|
.short('b')
|
||||||
.long(options::IGNORE_LEADING_BLANKS)
|
.long(options::IGNORE_LEADING_BLANKS)
|
||||||
.help("ignore leading blanks when finding sort keys in each line")
|
.help(get_message("sort-help-ignore-leading-blanks"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::OUTPUT)
|
Arg::new(options::OUTPUT)
|
||||||
.short('o')
|
.short('o')
|
||||||
.long(options::OUTPUT)
|
.long(options::OUTPUT)
|
||||||
.help("write output to FILENAME instead of stdout")
|
.help(get_message("sort-help-output"))
|
||||||
.value_parser(ValueParser::os_string())
|
.value_parser(ValueParser::os_string())
|
||||||
.value_name("FILENAME")
|
.value_name("FILENAME")
|
||||||
.value_hint(clap::ValueHint::FilePath)
|
.value_hint(clap::ValueHint::FilePath)
|
||||||
|
@ -1490,28 +1564,28 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(options::REVERSE)
|
Arg::new(options::REVERSE)
|
||||||
.short('r')
|
.short('r')
|
||||||
.long(options::REVERSE)
|
.long(options::REVERSE)
|
||||||
.help("reverse the output")
|
.help(get_message("sort-help-reverse"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::STABLE)
|
Arg::new(options::STABLE)
|
||||||
.short('s')
|
.short('s')
|
||||||
.long(options::STABLE)
|
.long(options::STABLE)
|
||||||
.help("stabilize sort by disabling last-resort comparison")
|
.help(get_message("sort-help-stable"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::UNIQUE)
|
Arg::new(options::UNIQUE)
|
||||||
.short('u')
|
.short('u')
|
||||||
.long(options::UNIQUE)
|
.long(options::UNIQUE)
|
||||||
.help("output only the first of an equal run")
|
.help(get_message("sort-help-unique"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::KEY)
|
Arg::new(options::KEY)
|
||||||
.short('k')
|
.short('k')
|
||||||
.long(options::KEY)
|
.long(options::KEY)
|
||||||
.help("sort by a key")
|
.help(get_message("sort-help-key"))
|
||||||
.action(ArgAction::Append)
|
.action(ArgAction::Append)
|
||||||
.num_args(1),
|
.num_args(1),
|
||||||
)
|
)
|
||||||
|
@ -1519,54 +1593,54 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(options::SEPARATOR)
|
Arg::new(options::SEPARATOR)
|
||||||
.short('t')
|
.short('t')
|
||||||
.long(options::SEPARATOR)
|
.long(options::SEPARATOR)
|
||||||
.help("custom separator for -k")
|
.help(get_message("sort-help-separator"))
|
||||||
.value_parser(ValueParser::os_string()),
|
.value_parser(ValueParser::os_string()),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::ZERO_TERMINATED)
|
Arg::new(options::ZERO_TERMINATED)
|
||||||
.short('z')
|
.short('z')
|
||||||
.long(options::ZERO_TERMINATED)
|
.long(options::ZERO_TERMINATED)
|
||||||
.help("line delimiter is NUL, not newline")
|
.help(get_message("sort-help-zero-terminated"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::PARALLEL)
|
Arg::new(options::PARALLEL)
|
||||||
.long(options::PARALLEL)
|
.long(options::PARALLEL)
|
||||||
.help("change the number of threads running concurrently to NUM_THREADS")
|
.help(get_message("sort-help-parallel"))
|
||||||
.value_name("NUM_THREADS"),
|
.value_name("NUM_THREADS"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::BUF_SIZE)
|
Arg::new(options::BUF_SIZE)
|
||||||
.short('S')
|
.short('S')
|
||||||
.long(options::BUF_SIZE)
|
.long(options::BUF_SIZE)
|
||||||
.help("sets the maximum SIZE of each segment in number of sorted items")
|
.help(get_message("sort-help-buf-size"))
|
||||||
.value_name("SIZE"),
|
.value_name("SIZE"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::TMP_DIR)
|
Arg::new(options::TMP_DIR)
|
||||||
.short('T')
|
.short('T')
|
||||||
.long(options::TMP_DIR)
|
.long(options::TMP_DIR)
|
||||||
.help("use DIR for temporaries, not $TMPDIR or /tmp")
|
.help(get_message("sort-help-tmp-dir"))
|
||||||
.value_name("DIR")
|
.value_name("DIR")
|
||||||
.value_hint(clap::ValueHint::DirPath),
|
.value_hint(clap::ValueHint::DirPath),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::COMPRESS_PROG)
|
Arg::new(options::COMPRESS_PROG)
|
||||||
.long(options::COMPRESS_PROG)
|
.long(options::COMPRESS_PROG)
|
||||||
.help("compress temporary files with PROG, decompress with PROG -d; PROG has to take input from stdin and output to stdout")
|
.help(get_message("sort-help-compress-prog"))
|
||||||
.value_name("PROG")
|
.value_name("PROG")
|
||||||
.value_hint(clap::ValueHint::CommandName),
|
.value_hint(clap::ValueHint::CommandName),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::BATCH_SIZE)
|
Arg::new(options::BATCH_SIZE)
|
||||||
.long(options::BATCH_SIZE)
|
.long(options::BATCH_SIZE)
|
||||||
.help("Merge at most N_MERGE inputs at once.")
|
.help(get_message("sort-help-batch-size"))
|
||||||
.value_name("N_MERGE"),
|
.value_name("N_MERGE"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::FILES0_FROM)
|
Arg::new(options::FILES0_FROM)
|
||||||
.long(options::FILES0_FROM)
|
.long(options::FILES0_FROM)
|
||||||
.help("read input from the files specified by NUL-terminated NUL_FILE")
|
.help(get_message("sort-help-files0-from"))
|
||||||
.value_name("NUL_FILE")
|
.value_name("NUL_FILE")
|
||||||
.value_parser(ValueParser::os_string())
|
.value_parser(ValueParser::os_string())
|
||||||
.value_hint(clap::ValueHint::FilePath),
|
.value_hint(clap::ValueHint::FilePath),
|
||||||
|
@ -1574,7 +1648,7 @@ pub fn uu_app() -> Command {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::DEBUG)
|
Arg::new(options::DEBUG)
|
||||||
.long(options::DEBUG)
|
.long(options::DEBUG)
|
||||||
.help("underline the parts of the line that are actually used for sorting")
|
.help(get_message("sort-help-debug"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -1595,7 +1669,10 @@ fn exec(
|
||||||
merge::merge(files, settings, output, tmp_dir)
|
merge::merge(files, settings, output, tmp_dir)
|
||||||
} else if settings.check {
|
} else if settings.check {
|
||||||
if files.len() > 1 {
|
if files.len() > 1 {
|
||||||
Err(UUsageError::new(2, "only one file allowed with -c"))
|
Err(UUsageError::new(
|
||||||
|
2,
|
||||||
|
get_message("sort-only-one-file-allowed-with-c"),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
check::check(files.first().unwrap(), settings)
|
check::check(files.first().unwrap(), settings)
|
||||||
}
|
}
|
||||||
|
@ -1922,7 +1999,12 @@ fn print_sorted<'a, T: Iterator<Item = &'a Line<'a>>>(
|
||||||
.as_output_name()
|
.as_output_name()
|
||||||
.unwrap_or(OsStr::new("standard output"))
|
.unwrap_or(OsStr::new("standard output"))
|
||||||
.to_owned();
|
.to_owned();
|
||||||
let ctx = || format!("write failed: {}", output_name.maybe_quote());
|
let ctx = || {
|
||||||
|
get_message_with_args(
|
||||||
|
"sort-error-write-failed",
|
||||||
|
HashMap::from([("output".to_string(), output_name.maybe_quote().to_string())]),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let mut writer = output.into_write();
|
let mut writer = output.into_write();
|
||||||
for line in iter {
|
for line in iter {
|
||||||
|
@ -1973,13 +2055,27 @@ fn format_error_message(error: &ParseSizeError, s: &str, option: &str) -> String
|
||||||
// NOTE:
|
// NOTE:
|
||||||
// GNU's sort echos affected flag, -S or --buffer-size, depending on user's selection
|
// GNU's sort echos affected flag, -S or --buffer-size, depending on user's selection
|
||||||
match error {
|
match error {
|
||||||
ParseSizeError::InvalidSuffix(_) => {
|
ParseSizeError::InvalidSuffix(_) => get_message_with_args(
|
||||||
format!("invalid suffix in --{option} argument {}", s.quote())
|
"sort-invalid-suffix-in-option-arg",
|
||||||
}
|
HashMap::from([
|
||||||
ParseSizeError::ParseFailure(_) | ParseSizeError::PhysicalMem(_) => {
|
("option".to_string(), option.to_string()),
|
||||||
format!("invalid --{option} argument {}", s.quote())
|
("arg".to_string(), s.quote().to_string()),
|
||||||
}
|
]),
|
||||||
ParseSizeError::SizeTooBig(_) => format!("--{option} argument {} too large", s.quote()),
|
),
|
||||||
|
ParseSizeError::ParseFailure(_) | ParseSizeError::PhysicalMem(_) => get_message_with_args(
|
||||||
|
"sort-invalid-option-arg",
|
||||||
|
HashMap::from([
|
||||||
|
("option".to_string(), option.to_string()),
|
||||||
|
("arg".to_string(), s.quote().to_string()),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
ParseSizeError::SizeTooBig(_) => get_message_with_args(
|
||||||
|
"sort-option-arg-too-large",
|
||||||
|
HashMap::from([
|
||||||
|
("option".to_string(), option.to_string()),
|
||||||
|
("arg".to_string(), s.quote().to_string()),
|
||||||
|
]),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,11 @@ use std::{
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use uucore::{
|
use uucore::{
|
||||||
error::{UResult, USimpleError},
|
error::{UResult, USimpleError},
|
||||||
|
locale::get_message_with_args,
|
||||||
show_error,
|
show_error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,11 +60,23 @@ impl TmpDirWrapper {
|
||||||
// and the program doesn't terminate before the handler has finished
|
// and the program doesn't terminate before the handler has finished
|
||||||
let _lock = lock.lock().unwrap();
|
let _lock = lock.lock().unwrap();
|
||||||
if let Err(e) = remove_tmp_dir(&path) {
|
if let Err(e) = remove_tmp_dir(&path) {
|
||||||
show_error!("failed to delete temporary directory: {e}");
|
let mut args = HashMap::new();
|
||||||
|
args.insert("error".to_string(), e.to_string());
|
||||||
|
show_error!(
|
||||||
|
"{}",
|
||||||
|
get_message_with_args("sort-failed-to-delete-temporary-directory", args)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
std::process::exit(2)
|
std::process::exit(2)
|
||||||
})
|
})
|
||||||
.map_err(|e| USimpleError::new(2, format!("failed to set up signal handler: {e}")))
|
.map_err(|e| {
|
||||||
|
let mut args = HashMap::new();
|
||||||
|
args.insert("error".to_string(), e.to_string());
|
||||||
|
USimpleError::new(
|
||||||
|
2,
|
||||||
|
get_message_with_args("sort-failed-to-set-up-signal-handler", args),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_file(&mut self) -> UResult<(File, PathBuf)> {
|
pub fn next_file(&mut self) -> UResult<(File, PathBuf)> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue