@@ -9,9 +9,7 @@ use std::fs::File;
99use std:: io:: { BufRead , BufReader , Read , stdin} ;
1010use std:: path:: Path ;
1111use uucore:: error:: { FromIo , UResult , USimpleError , set_exit_code} ;
12- use uucore:: translate;
13-
14- use uucore:: { format_usage, show_error} ;
12+ use uucore:: { format_usage, show_error, translate} ;
1513
1614mod helper;
1715
@@ -78,7 +76,7 @@ enum NumberingStyle {
7876 All ,
7977 NonEmpty ,
8078 None ,
81- Regex ( Box < regex:: Regex > ) ,
79+ Regex ( Box < regex:: bytes :: Regex > ) ,
8280}
8381
8482impl TryFrom < & str > for NumberingStyle {
@@ -89,7 +87,7 @@ impl TryFrom<&str> for NumberingStyle {
8987 "a" => Ok ( Self :: All ) ,
9088 "t" => Ok ( Self :: NonEmpty ) ,
9189 "n" => Ok ( Self :: None ) ,
92- _ if s. starts_with ( 'p' ) => match regex:: Regex :: new ( & s[ 1 ..] ) {
90+ _ if s. starts_with ( 'p' ) => match regex:: bytes :: Regex :: new ( & s[ 1 ..] ) {
9391 Ok ( re) => Ok ( Self :: Regex ( Box :: new ( re) ) ) ,
9492 Err ( _) => Err ( translate ! ( "nl-error-invalid-regex" ) ) ,
9593 } ,
@@ -142,19 +140,30 @@ enum SectionDelimiter {
142140impl SectionDelimiter {
143141 /// A valid section delimiter contains the pattern one to three times,
144142 /// and nothing else.
145- fn parse ( s : & str , pattern : & str ) -> Option < Self > {
146- if s. is_empty ( ) || pattern. is_empty ( ) {
143+ fn parse ( bytes : & [ u8 ] , pattern : & str ) -> Option < Self > {
144+ let pattern = pattern. as_bytes ( ) ;
145+
146+ if bytes. is_empty ( ) || pattern. is_empty ( ) || bytes. len ( ) % pattern. len ( ) != 0 {
147147 return None ;
148148 }
149149
150- let pattern_count = s. matches ( pattern) . count ( ) ;
151- let is_length_ok = pattern_count * pattern. len ( ) == s. len ( ) ;
150+ let count = bytes. len ( ) / pattern. len ( ) ;
151+ if !( 1 ..=3 ) . contains ( & count) {
152+ return None ;
153+ }
152154
153- match ( pattern_count, is_length_ok) {
154- ( 3 , true ) => Some ( Self :: Header ) ,
155- ( 2 , true ) => Some ( Self :: Body ) ,
156- ( 1 , true ) => Some ( Self :: Footer ) ,
157- _ => None ,
155+ if bytes
156+ . chunks_exact ( pattern. len ( ) )
157+ . all ( |chunk| chunk == pattern)
158+ {
159+ match count {
160+ 1 => Some ( Self :: Footer ) ,
161+ 2 => Some ( Self :: Body ) ,
162+ 3 => Some ( Self :: Header ) ,
163+ _ => unreachable ! ( ) ,
164+ }
165+ } else {
166+ None
158167 }
159168 }
160169}
@@ -337,9 +346,21 @@ pub fn uu_app() -> Command {
337346/// `nl` implements the main functionality for an individual buffer.
338347fn nl < T : Read > ( reader : & mut BufReader < T > , stats : & mut Stats , settings : & Settings ) -> UResult < ( ) > {
339348 let mut current_numbering_style = & settings. body_numbering ;
349+ let mut line = Vec :: new ( ) ;
350+
351+ loop {
352+ line. clear ( ) ;
353+ // reads up to and including b'\n'; returns 0 on EOF
354+ let n = reader
355+ . read_until ( b'\n' , & mut line)
356+ . map_err_context ( || translate ! ( "nl-error-could-not-read-line" ) ) ?;
357+ if n == 0 {
358+ break ;
359+ }
340360
341- for line in reader. lines ( ) {
342- let line = line. map_err_context ( || translate ! ( "nl-error-could-not-read-line" ) ) ?;
361+ if line. last ( ) . copied ( ) == Some ( b'\n' ) {
362+ line. pop ( ) ;
363+ }
343364
344365 if line. is_empty ( ) {
345366 stats. consecutive_empty_lines += 1 ;
@@ -386,11 +407,12 @@ fn nl<T: Read>(reader: &mut BufReader<T>, stats: &mut Stats, settings: &Settings
386407 ) ) ;
387408 } ;
388409 println ! (
389- "{}{}{line }" ,
410+ "{}{}{}" ,
390411 settings
391412 . number_format
392413 . format( line_number, settings. number_width) ,
393414 settings. number_separator. to_string_lossy( ) ,
415+ String :: from_utf8_lossy( & line) ,
394416 ) ;
395417 // update line number for the potential next line
396418 match line_number. checked_add ( settings. line_increment ) {
@@ -399,7 +421,7 @@ fn nl<T: Read>(reader: &mut BufReader<T>, stats: &mut Stats, settings: &Settings
399421 }
400422 } else {
401423 let spaces = " " . repeat ( settings. number_width + 1 ) ;
402- println ! ( "{spaces}{line}" ) ;
424+ println ! ( "{spaces}{}" , String :: from_utf8_lossy ( & line ) ) ;
403425 }
404426 }
405427 }
0 commit comments