mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
join: consider locale collation in field comparison (#9982)
Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
This commit is contained in:
co-authored by
Sylvestre Ledru
parent
555271d8a9
commit
98d3dbad4e
@@ -19,7 +19,7 @@ path = "src/join.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = { workspace = true }
|
||||
uucore = { workspace = true }
|
||||
uucore = { workspace = true, features = ["i18n-collator"] }
|
||||
memchr = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
fluent = { workspace = true }
|
||||
|
||||
+18
-2
@@ -19,6 +19,9 @@ use thiserror::Error;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{FromIo, UError, UResult, USimpleError, set_exit_code};
|
||||
use uucore::format_usage;
|
||||
use uucore::i18n::collator::{
|
||||
AlternateHandling, CollatorOptions, locale_cmp, should_use_locale_collation, try_init_collator,
|
||||
};
|
||||
use uucore::line_ending::LineEnding;
|
||||
use uucore::translate;
|
||||
|
||||
@@ -311,14 +314,16 @@ struct Input<Sep: Separator> {
|
||||
separator: Sep,
|
||||
ignore_case: bool,
|
||||
check_order: CheckOrder,
|
||||
use_locale: bool,
|
||||
}
|
||||
|
||||
impl<Sep: Separator> Input<Sep> {
|
||||
fn new(separator: Sep, ignore_case: bool, check_order: CheckOrder) -> Self {
|
||||
fn new(separator: Sep, ignore_case: bool, check_order: CheckOrder, use_locale: bool) -> Self {
|
||||
Self {
|
||||
separator,
|
||||
ignore_case,
|
||||
check_order,
|
||||
use_locale,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,6 +333,8 @@ impl<Sep: Separator> Input<Sep> {
|
||||
let field1 = CaseInsensitiveSlice { v: field1 };
|
||||
let field2 = CaseInsensitiveSlice { v: field2 };
|
||||
field1.cmp(&field2)
|
||||
} else if self.use_locale {
|
||||
locale_cmp(field1, field2)
|
||||
} else {
|
||||
field1.cmp(field2)
|
||||
}
|
||||
@@ -823,6 +830,10 @@ fn parse_settings(matches: &clap::ArgMatches) -> UResult<Settings> {
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;
|
||||
|
||||
let mut opts = CollatorOptions::default();
|
||||
opts.alternate_handling = Some(AlternateHandling::Shifted);
|
||||
let _ = try_init_collator(opts);
|
||||
|
||||
let settings = parse_settings(&matches)?;
|
||||
|
||||
let file1 = matches.get_one::<OsString>("file1").unwrap();
|
||||
@@ -989,7 +1000,12 @@ fn exec<Sep: Separator>(
|
||||
settings.print_unpaired2,
|
||||
)?;
|
||||
|
||||
let input = Input::new(sep.clone(), settings.ignore_case, settings.check_order);
|
||||
let input = Input::new(
|
||||
sep.clone(),
|
||||
settings.ignore_case,
|
||||
settings.check_order,
|
||||
should_use_locale_collation(),
|
||||
);
|
||||
|
||||
let format = if settings.autoformat {
|
||||
let mut format = vec![Spec::Key];
|
||||
|
||||
@@ -30,6 +30,11 @@ pub fn init_collator(opts: CollatorOptions) {
|
||||
.expect("Collator already initialized");
|
||||
}
|
||||
|
||||
/// Check if locale collation should be used.
|
||||
pub fn should_use_locale_collation() -> bool {
|
||||
get_collating_locale().0 != DEFAULT_LOCALE
|
||||
}
|
||||
|
||||
/// Initialize the collator for locale-aware string comparison if needed.
|
||||
///
|
||||
/// This function checks if the current locale requires locale-aware collation
|
||||
|
||||
@@ -580,3 +580,22 @@ fn join_emoji_delim_inner_key() {
|
||||
.succeeds()
|
||||
.stdout_only("b🗿a🗿u\n");
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn test_locale_collation() {
|
||||
let ts = TestScenario::new(util_name!());
|
||||
let at = &ts.fixtures;
|
||||
|
||||
at.write("f1.sorted", "abc:d 2\nab:d 1\n");
|
||||
at.write("f2.sorted", "abc:d y\nab:d x\n");
|
||||
|
||||
ts.ucmd()
|
||||
.env("LC_ALL", "en_US.UTF-8")
|
||||
.arg("--check-order")
|
||||
.arg("f1.sorted")
|
||||
.arg("f2.sorted")
|
||||
.succeeds()
|
||||
.stdout_contains("abc:d 2 y")
|
||||
.stdout_contains("ab:d 1 x");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user