@@ -47,6 +47,7 @@ use uucore::error::{FromIo, strip_errno};
4747use uucore:: error:: { UError , UResult , USimpleError , UUsageError } ;
4848use uucore:: extendedbigdecimal:: ExtendedBigDecimal ;
4949use uucore:: format_usage;
50+ use uucore:: i18n:: decimal:: locale_decimal_separator;
5051use uucore:: line_ending:: LineEnding ;
5152use uucore:: parser:: num_parser:: { ExtendedParser , ExtendedParserError } ;
5253use uucore:: parser:: parse_size:: { ParseSizeError , Parser } ;
@@ -106,6 +107,14 @@ mod options {
106107
107108const DECIMAL_PT : u8 = b'.' ;
108109
110+ fn locale_decimal_pt ( ) -> u8 {
111+ match locale_decimal_separator ( ) . as_bytes ( ) . first ( ) . copied ( ) {
112+ Some ( b'.' ) => b'.' ,
113+ Some ( b',' ) => b',' ,
114+ _ => DECIMAL_PT ,
115+ }
116+ }
117+
109118const NEGATIVE : & u8 = & b'-' ;
110119const POSITIVE : & u8 = & b'+' ;
111120
@@ -683,8 +692,8 @@ impl<'a> Line<'a> {
683692 }
684693 SortMode :: GeneralNumeric => {
685694 let initial_selection = & self . line [ selection. clone ( ) ] ;
686-
687- let leading = get_leading_gen ( initial_selection) ;
695+ let decimal_pt = locale_decimal_pt ( ) ;
696+ let leading = get_leading_gen ( initial_selection, decimal_pt ) ;
688697
689698 // Shorten selection to leading.
690699 selection. start += leading. start ;
@@ -1072,7 +1081,11 @@ impl FieldSelector {
10721081 Selection :: WithNumInfo ( range_str, info)
10731082 } else if self . settings . mode == SortMode :: GeneralNumeric {
10741083 // Parse this number as BigDecimal, as this is the requirement for general numeric sorting.
1075- Selection :: AsBigDecimal ( general_bd_parse ( & range_str[ get_leading_gen ( range_str) ] ) )
1084+ let decimal_pt = locale_decimal_pt ( ) ;
1085+ Selection :: AsBigDecimal ( general_bd_parse (
1086+ & range_str[ get_leading_gen ( range_str, decimal_pt) ] ,
1087+ decimal_pt,
1088+ ) )
10761089 } else {
10771090 // This is not a numeric sort, so we don't need a NumCache.
10781091 Selection :: Str ( range_str)
@@ -2491,7 +2504,7 @@ fn ascii_case_insensitive_cmp(a: &[u8], b: &[u8]) -> Ordering {
24912504// scientific notation, so we strip those lines only after the end of the following numeric string.
24922505// For example, 5e10KFD would be 5e10 or 5x10^10 and +10000HFKJFK would become 10000.
24932506#[ allow( clippy:: cognitive_complexity) ]
2494- fn get_leading_gen ( inp : & [ u8 ] ) -> Range < usize > {
2507+ fn get_leading_gen ( inp : & [ u8 ] , decimal_pt : u8 ) -> Range < usize > {
24952508 let trimmed = inp. trim_ascii_start ( ) ;
24962509 let leading_whitespace_len = inp. len ( ) - trimmed. len ( ) ;
24972510
@@ -2529,7 +2542,7 @@ fn get_leading_gen(inp: &[u8]) -> Range<usize> {
25292542 continue ;
25302543 }
25312544
2532- if c == DECIMAL_PT && !had_decimal_pt && !had_e_notation {
2545+ if c == decimal_pt && !had_decimal_pt && !had_e_notation {
25332546 had_decimal_pt = true ;
25342547 continue ;
25352548 }
@@ -2572,9 +2585,16 @@ pub enum GeneralBigDecimalParseResult {
25722585/// Parse the beginning string into a [`GeneralBigDecimalParseResult`].
25732586/// Using a [`GeneralBigDecimalParseResult`] instead of [`ExtendedBigDecimal`] is necessary to correctly order floats.
25742587#[ inline( always) ]
2575- fn general_bd_parse ( a : & [ u8 ] ) -> GeneralBigDecimalParseResult {
2588+ fn general_bd_parse ( a : & [ u8 ] , decimal_pt : u8 ) -> GeneralBigDecimalParseResult {
2589+ let parsed_bytes = ( decimal_pt != DECIMAL_PT ) . then ( || {
2590+ a. iter ( )
2591+ . map ( |& b| if b == decimal_pt { DECIMAL_PT } else { b } )
2592+ . collect :: < Vec < _ > > ( )
2593+ } ) ;
2594+ let input = parsed_bytes. as_deref ( ) . unwrap_or ( a) ;
2595+
25762596 // The string should be valid ASCII to be parsed.
2577- let Ok ( a) = std:: str:: from_utf8 ( a ) else {
2597+ let Ok ( a) = std:: str:: from_utf8 ( input ) else {
25782598 return GeneralBigDecimalParseResult :: Invalid ;
25792599 } ;
25802600
0 commit comments