@@ -9,7 +9,7 @@ use std::cmp::Ordering;
99use std:: ffi:: OsString ;
1010use std:: fs:: { File , metadata} ;
1111use std:: io:: { self , BufRead , BufReader , Read , StdinLock , stdin} ;
12- use std:: path:: Path ;
12+ use std:: path:: { Path , PathBuf } ;
1313use uucore:: error:: { FromIo , UResult , USimpleError } ;
1414use uucore:: format_usage;
1515use uucore:: fs:: paths_refer_to_same_file;
@@ -56,16 +56,29 @@ struct OrderChecker {
5656
5757enum Input {
5858 Stdin ( StdinLock < ' static > ) ,
59- FileIn ( BufReader < File > ) ,
59+ FileIn {
60+ path : PathBuf ,
61+ file : BufReader < File > ,
62+ } ,
6063}
6164
6265impl Input {
6366 fn stdin ( ) -> Self {
6467 Self :: Stdin ( stdin ( ) . lock ( ) )
6568 }
6669
67- fn from_file ( f : File ) -> Self {
68- Self :: FileIn ( BufReader :: new ( f) )
70+ fn from_file ( path : PathBuf , file : File ) -> Self {
71+ Self :: FileIn {
72+ path,
73+ file : BufReader :: new ( file) ,
74+ }
75+ }
76+
77+ fn path ( & self ) -> & Path {
78+ match self {
79+ Self :: Stdin ( _) => Path :: new ( "-" ) ,
80+ Self :: FileIn { path, .. } => path,
81+ }
6982 }
7083}
7184
@@ -79,19 +92,22 @@ impl LineReader {
7992 Self { line_ending, input }
8093 }
8194
82- fn read_line ( & mut self , buf : & mut Vec < u8 > ) -> io:: Result < usize > {
95+ fn read_line ( & mut self , buf : & mut Vec < u8 > ) -> UResult < usize > {
96+ buf. clear ( ) ;
97+
8398 let line_ending = self . line_ending . into ( ) ;
8499
85- let result = match & mut self . input {
100+ let n = match & mut self . input {
86101 Input :: Stdin ( r) => r. read_until ( line_ending, buf) ,
87- Input :: FileIn ( r) => r. read_until ( line_ending, buf) ,
88- } ;
102+ Input :: FileIn { file : r, .. } => r. read_until ( line_ending, buf) ,
103+ }
104+ . map_err_context ( || self . input . path ( ) . display ( ) . to_string ( ) ) ?;
89105
90- if !buf. ends_with ( & [ line_ending] ) {
106+ if n > 0 && !buf. ends_with ( & [ line_ending] ) {
91107 buf. push ( line_ending) ;
92108 }
93109
94- result
110+ Ok ( n )
95111 }
96112}
97113
@@ -185,10 +201,10 @@ fn comm(a: &mut LineReader, b: &mut LineReader, delim: &str, opts: &ArgMatches)
185201 let delim_col_2 = delim. repeat ( width_col_1) ;
186202 let delim_col_3 = delim. repeat ( width_col_1 + width_col_2) ;
187203
188- let ra = & mut Vec :: new ( ) ;
189- let mut na = a . read_line ( ra ) ;
190- let rb = & mut Vec :: new ( ) ;
191- let mut nb = b. read_line ( rb ) ;
204+ let line_a = & mut Vec :: new ( ) ;
205+ let line_b = & mut Vec :: new ( ) ;
206+ a . read_line ( line_a ) ? ;
207+ b. read_line ( line_b ) ? ;
192208
193209 let mut total_col_1 = 0 ;
194210 let mut total_col_2 = 0 ;
@@ -214,54 +230,46 @@ fn comm(a: &mut LineReader, b: &mut LineReader, delim: &str, opts: &ArgMatches)
214230 let mut checker2 = OrderChecker :: new ( FileNumber :: Two , check_order) ;
215231 let mut input_error = false ;
216232
217- while na. is_ok ( ) || nb. is_ok ( ) {
218- let ord = match ( na. is_ok ( ) , nb. is_ok ( ) ) {
219- ( false , true ) => Ordering :: Greater ,
220- ( true , false ) => Ordering :: Less ,
221- ( true , true ) => match ( & na, & nb) {
222- ( & Ok ( 0 ) , & Ok ( 0 ) ) => break ,
223- ( & Ok ( 0 ) , _) => Ordering :: Greater ,
224- ( _, & Ok ( 0 ) ) => Ordering :: Less ,
225- _ => ra. cmp ( & rb) ,
226- } ,
227- _ => unreachable ! ( ) ,
233+ loop {
234+ let ord = match ( line_a. is_empty ( ) , line_b. is_empty ( ) ) {
235+ ( true , true ) => break ,
236+ ( true , false ) => Ordering :: Greater ,
237+ ( false , true ) => Ordering :: Less ,
238+ ( false , false ) => line_a. cmp ( & line_b) ,
228239 } ;
229240
230241 match ord {
231242 Ordering :: Less => {
232- if should_check_order && !checker1. verify_order ( ra ) {
243+ if should_check_order && !checker1. verify_order ( line_a ) {
233244 break ;
234245 }
235246 if !opts. get_flag ( options:: COLUMN_1 ) {
236- print ! ( "{}" , String :: from_utf8_lossy( ra ) ) ;
247+ print ! ( "{}" , String :: from_utf8_lossy( line_a ) ) ;
237248 }
238- ra. clear ( ) ;
239- na = a. read_line ( ra) ;
249+ a. read_line ( line_a) ?;
240250 total_col_1 += 1 ;
241251 }
242252 Ordering :: Greater => {
243- if should_check_order && !checker2. verify_order ( rb ) {
253+ if should_check_order && !checker2. verify_order ( line_b ) {
244254 break ;
245255 }
246256 if !opts. get_flag ( options:: COLUMN_2 ) {
247- print ! ( "{delim_col_2}{}" , String :: from_utf8_lossy( rb ) ) ;
257+ print ! ( "{delim_col_2}{}" , String :: from_utf8_lossy( line_b ) ) ;
248258 }
249- rb. clear ( ) ;
250- nb = b. read_line ( rb) ;
259+ b. read_line ( line_b) ?;
251260 total_col_2 += 1 ;
252261 }
253262 Ordering :: Equal => {
254- if should_check_order && ( !checker1. verify_order ( ra) || !checker2. verify_order ( rb) )
263+ if should_check_order
264+ && ( !checker1. verify_order ( line_a) || !checker2. verify_order ( line_b) )
255265 {
256266 break ;
257267 }
258268 if !opts. get_flag ( options:: COLUMN_3 ) {
259- print ! ( "{delim_col_3}{}" , String :: from_utf8_lossy( ra ) ) ;
269+ print ! ( "{delim_col_3}{}" , String :: from_utf8_lossy( line_a ) ) ;
260270 }
261- ra. clear ( ) ;
262- rb. clear ( ) ;
263- na = a. read_line ( ra) ;
264- nb = b. read_line ( rb) ;
271+ a. read_line ( line_a) ?;
272+ b. read_line ( line_b) ?;
265273 total_col_3 += 1 ;
266274 }
267275 }
@@ -291,15 +299,16 @@ fn comm(a: &mut LineReader, b: &mut LineReader, delim: &str, opts: &ArgMatches)
291299 }
292300}
293301
294- fn open_file ( name : & OsString , line_ending : LineEnding ) -> io:: Result < LineReader > {
295- if name == "-" {
302+ fn open_file < P : AsRef < Path > > ( name : P , line_ending : LineEnding ) -> io:: Result < LineReader > {
303+ let name = name. as_ref ( ) ;
304+ if name. as_os_str ( ) == "-" {
296305 Ok ( LineReader :: new ( Input :: stdin ( ) , line_ending) )
297306 } else {
298- if metadata ( name) ?. is_dir ( ) {
299- return Err ( io:: Error :: other ( translate ! ( "comm-error-is-directory" ) ) ) ;
300- }
301307 let f = File :: open ( name) ?;
302- Ok ( LineReader :: new ( Input :: from_file ( f) , line_ending) )
308+ Ok ( LineReader :: new (
309+ Input :: from_file ( name. to_path_buf ( ) , f) ,
310+ line_ending,
311+ ) )
303312 }
304313}
305314
0 commit comments