From 351d1fc068e8c4d4dd9c5a2a883d21e3981128c1 Mon Sep 17 00:00:00 2001 From: Wisha Wa Date: Mon, 12 Oct 2020 01:27:35 +0700 Subject: [PATCH 001/132] ptx: improve performance by removing N^2 routine. --- src/uu/ptx/src/ptx.rs | 246 +++++++++++++++++++++++++++--------------- 1 file changed, 157 insertions(+), 89 deletions(-) diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index 3621e1bdf..3bc2ee297 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -182,8 +182,16 @@ fn get_config(matches: &Matches) -> Config { config } -fn read_input(input_files: &[String], config: &Config) -> HashMap, usize)> { - let mut file_map: HashMap, usize)> = HashMap::new(); +struct FileContent { + lines: Vec, + chars_lines: Vec>, + offset: usize, +} + +type FileMap = HashMap; + +fn read_input(input_files: &[String], config: &Config) -> FileMap { + let mut file_map: FileMap = HashMap::new(); let mut files = Vec::new(); if input_files.is_empty() { files.push("-"); @@ -194,7 +202,7 @@ fn read_input(input_files: &[String], config: &Config) -> HashMap> = BufReader::new(if filename == "-" { Box::new(stdin()) @@ -203,25 +211,33 @@ fn read_input(input_files: &[String], config: &Config) -> HashMap = reader.lines().map(|x| crash_if_err!(1, x)).collect(); + let ws_reg = Regex::new(r"[\t\n\v\f\r]").unwrap(); + let chars_lines: Vec> = lines + .iter() + .map(|x| ws_reg.replace_all(x, " ").chars().collect()) + .collect(); let size = lines.len(); - file_map.insert(filename.to_owned(), (lines, lines_so_far)); - lines_so_far += size + file_map.insert( + filename.to_owned(), + FileContent { + lines, + chars_lines, + offset, + }, + ); + offset += size } file_map } -fn create_word_set( - config: &Config, - filter: &WordFilter, - file_map: &HashMap, usize)>, -) -> BTreeSet { +fn create_word_set(config: &Config, filter: &WordFilter, file_map: &FileMap) -> BTreeSet { let reg = Regex::new(&filter.word_regex).unwrap(); let ref_reg = Regex::new(&config.context_regex).unwrap(); let mut word_set: BTreeSet = BTreeSet::new(); for (file, lines) in file_map.iter() { let mut count: usize = 0; - let offs = lines.1; - for line in &lines.0 { + let offs = lines.offset; + for line in &lines.lines { // if -r, exclude reference from word set let (ref_beg, ref_end) = match ref_reg.find(line) { Some(x) => (x.start(), x.end()), @@ -316,57 +332,73 @@ fn trim_idx(s: &[char], beg: usize, end: usize) -> (usize, usize) { } fn get_output_chunks( - all_before: &str, + all_before: &[char], keyword: &str, - all_after: &str, + all_after: &[char], config: &Config, ) -> (String, String, String, String) { - assert_eq!(all_before.trim(), all_before); - assert_eq!(keyword.trim(), keyword); - assert_eq!(all_after.trim(), all_after); - let mut head = String::new(); - let mut before = String::new(); - let mut after = String::new(); - let mut tail = String::new(); - - let half_line_size = cmp::max( - (config.line_width / 2) as isize - (2 * config.trunc_str.len()) as isize, + let half_line_size = (config.line_width / 2) as usize; + let max_before_size = cmp::max(half_line_size as isize - config.gap_size as isize, 0) as usize; + let max_after_size = cmp::max( + half_line_size as isize + - (2 * config.trunc_str.len()) as isize + - keyword.len() as isize + - 1, 0, ) as usize; - let max_after_size = cmp::max(half_line_size as isize - keyword.len() as isize - 1, 0) as usize; - let max_before_size = half_line_size; - let all_before_vec: Vec = all_before.chars().collect(); - let all_after_vec: Vec = all_after.chars().collect(); + + let mut head = String::with_capacity(half_line_size); + let mut before = String::with_capacity(half_line_size); + let mut after = String::with_capacity(half_line_size); + let mut tail = String::with_capacity(half_line_size); // get before - let mut bb_tmp = cmp::max(all_before.len() as isize - max_before_size as isize, 0) as usize; - bb_tmp = trim_broken_word_left(&all_before_vec, bb_tmp, all_before.len()); - let (before_beg, before_end) = trim_idx(&all_before_vec, bb_tmp, all_before.len()); - before.push_str(&all_before[before_beg..before_end]); + let (_, be) = trim_idx(all_before, 0, all_before.len()); + let mut bb_tmp = cmp::max(be as isize - max_before_size as isize, 0) as usize; + bb_tmp = trim_broken_word_left(all_before, bb_tmp, be); + let (before_beg, before_end) = trim_idx(all_before, bb_tmp, be); + let before_str: String = all_before[before_beg..before_end].iter().collect(); + before.push_str(&before_str); assert!(max_before_size >= before.len()); // get after let mut ae_tmp = cmp::min(max_after_size, all_after.len()); - ae_tmp = trim_broken_word_right(&all_after_vec, 0, ae_tmp); - let (after_beg, after_end) = trim_idx(&all_after_vec, 0, ae_tmp); - after.push_str(&all_after[after_beg..after_end]); + ae_tmp = trim_broken_word_right(all_after, 0, ae_tmp); + let (_, after_end) = trim_idx(all_after, 0, ae_tmp); + let after_str: String = all_after[0..after_end].iter().collect(); + after.push_str(&after_str); assert!(max_after_size >= after.len()); // get tail - let max_tail_size = max_before_size - before.len(); - let (tb, _) = trim_idx(&all_after_vec, after_end, all_after.len()); - let mut te_tmp = cmp::min(tb + max_tail_size, all_after.len()); - te_tmp = trim_broken_word_right(&all_after_vec, tb, te_tmp); - let (tail_beg, tail_end) = trim_idx(&all_after_vec, tb, te_tmp); - tail.push_str(&all_after[tail_beg..tail_end]); + let max_tail_size = cmp::max( + max_before_size as isize - before.len() as isize - config.gap_size as isize, + 0, + ) as usize; + let (tb, _) = trim_idx(all_after, after_end, all_after.len()); + let mut te_tmp = cmp::min(all_after.len(), tb + max_tail_size) as usize; + te_tmp = trim_broken_word_right( + all_after, + tb, + cmp::max(te_tmp as isize - 1, tb as isize) as usize, + ); + let (tail_beg, tail_end) = trim_idx(all_after, tb, te_tmp); + let tail_str: String = all_after[tail_beg..tail_end].iter().collect(); + tail.push_str(&tail_str); // get head - let max_head_size = max_after_size - after.len(); - let (_, he) = trim_idx(&all_before_vec, 0, before_beg); - let mut hb_tmp = cmp::max(he as isize - max_head_size as isize, 0) as usize; - hb_tmp = trim_broken_word_left(&all_before_vec, hb_tmp, he); - let (head_beg, head_end) = trim_idx(&all_before_vec, hb_tmp, he); - head.push_str(&all_before[head_beg..head_end]); + let max_head_size = cmp::max( + max_after_size as isize - after.len() as isize - config.gap_size as isize, + 0, + ) as usize; + let (_, he) = trim_idx(all_before, 0, before_beg); + let hb_tmp = trim_broken_word_left( + all_before, + cmp::max(he as isize - max_head_size as isize, 0) as usize, + he, + ); + let (head_beg, head_end) = trim_idx(all_before, hb_tmp, he); + let head_str: String = all_before[head_beg..head_end].iter().collect(); + head.push_str(&head_str); // put right context truncation string if needed if after_end != all_after.len() && tail_beg == tail_end { @@ -382,11 +414,6 @@ fn get_output_chunks( head = format!("{}{}", config.trunc_str, head); } - // add space before "after" if needed - if !after.is_empty() { - after = format!(" {}", after); - } - (tail, before, after, head) } @@ -399,70 +426,94 @@ fn tex_mapper(x: char) -> String { } } -fn adjust_tex_str(context: &str) -> String { - let ws_reg = Regex::new(r"[\t\n\v\f\r ]").unwrap(); - let mut fix: String = ws_reg.replace_all(context, " ").trim().to_owned(); - let mapped_chunks: Vec = fix.chars().map(tex_mapper).collect(); - fix = mapped_chunks.join(""); - fix +fn format_tex_field(s: &str) -> String { + let mapped_chunks: Vec = s.chars().map(tex_mapper).collect(); + mapped_chunks.join("") } -fn format_tex_line(config: &Config, word_ref: &WordRef, line: &str, reference: &str) -> String { +fn format_tex_line( + config: &Config, + word_ref: &WordRef, + line: &str, + chars_line: &[char], + reference: &str, +) -> String { let mut output = String::new(); output.push_str(&format!("\\{} ", config.macro_name)); let all_before = if config.input_ref { let before = &line[0..word_ref.position]; - adjust_tex_str(before.trim().trim_start_matches(reference)) + let before_start_trimoff = + word_ref.position - before.trim_start_matches(reference).trim_start().len(); + let before_end_index = before.len(); + &chars_line[before_start_trimoff..cmp::max(before_end_index, before_start_trimoff)] } else { - adjust_tex_str(&line[0..word_ref.position]) + let before_chars_trim_idx = (0, word_ref.position); + &chars_line[before_chars_trim_idx.0..before_chars_trim_idx.1] }; - let keyword = adjust_tex_str(&line[word_ref.position..word_ref.position_end]); - let all_after = adjust_tex_str(&line[word_ref.position_end..line.len()]); + let keyword = &line[word_ref.position..word_ref.position_end]; + let after_chars_trim_idx = (word_ref.position_end, chars_line.len()); + let all_after = &chars_line[after_chars_trim_idx.0..after_chars_trim_idx.1]; let (tail, before, after, head) = get_output_chunks(&all_before, &keyword, &all_after, &config); output.push_str(&format!( "{5}{0}{6}{5}{1}{6}{5}{2}{6}{5}{3}{6}{5}{4}{6}", - tail, before, keyword, after, head, "{", "}" + format_tex_field(&tail), + format_tex_field(&before), + format_tex_field(keyword), + format_tex_field(&after), + format_tex_field(&head), + "{", + "}" )); if config.auto_ref || config.input_ref { - output.push_str(&format!("{}{}{}", "{", adjust_tex_str(&reference), "}")); + output.push_str(&format!("{}{}{}", "{", format_tex_field(&reference), "}")); } output } -fn adjust_roff_str(context: &str) -> String { - let ws_reg = Regex::new(r"[\t\n\v\f\r]").unwrap(); - ws_reg - .replace_all(context, " ") - .replace("\"", "\"\"") - .trim() - .to_owned() +fn format_roff_field(s: &str) -> String { + s.replace("\"", "\"\"") } -fn format_roff_line(config: &Config, word_ref: &WordRef, line: &str, reference: &str) -> String { +fn format_roff_line( + config: &Config, + word_ref: &WordRef, + line: &str, + chars_line: &[char], + reference: &str, +) -> String { let mut output = String::new(); output.push_str(&format!(".{}", config.macro_name)); let all_before = if config.input_ref { let before = &line[0..word_ref.position]; - adjust_roff_str(before.trim().trim_start_matches(reference)) + let before_start_trimoff = + word_ref.position - before.trim_start_matches(reference).trim_start().len(); + let before_end_index = before.len(); + &chars_line[before_start_trimoff..cmp::max(before_end_index, before_start_trimoff)] } else { - adjust_roff_str(&line[0..word_ref.position]) + let before_chars_trim_idx = (0, word_ref.position); + &chars_line[before_chars_trim_idx.0..before_chars_trim_idx.1] }; - let keyword = adjust_roff_str(&line[word_ref.position..word_ref.position_end]); - let all_after = adjust_roff_str(&line[word_ref.position_end..line.len()]); + let keyword = &line[word_ref.position..word_ref.position_end]; + let after_chars_trim_idx = (word_ref.position_end, chars_line.len()); + let all_after = &chars_line[after_chars_trim_idx.0..after_chars_trim_idx.1]; let (tail, before, after, head) = get_output_chunks(&all_before, &keyword, &all_after, &config); output.push_str(&format!( " \"{}\" \"{}\" \"{}{}\" \"{}\"", - tail, before, keyword, after, head + format_roff_field(&tail), + format_roff_field(&before), + format_roff_field(keyword), + format_roff_field(&after), + format_roff_field(&head) )); if config.auto_ref || config.input_ref { - output.push_str(&format!(" \"{}\"", adjust_roff_str(&reference))); + output.push_str(&format!(" \"{}\"", format_roff_field(&reference))); } output } fn write_traditional_output( config: &Config, - file_map: &HashMap, usize)>, + file_map: &FileMap, words: &BTreeSet, output_filename: &str, ) { @@ -472,19 +523,36 @@ fn write_traditional_output( let file = crash_if_err!(1, File::create(output_filename)); Box::new(file) }); + for word_ref in words.iter() { - let file_map_value: &(Vec, usize) = file_map + let file_map_value: &FileContent = file_map .get(&(word_ref.filename)) .expect("Missing file in file map"); - let (ref lines, _) = *(file_map_value); - let reference = get_reference(config, word_ref, &lines[word_ref.local_line_nr]); + let FileContent { + ref lines, + ref chars_lines, + offset: _, + } = *(file_map_value); + let reference = get_reference( + config, + word_ref, + &lines[word_ref.local_line_nr], + ); let output_line: String = match config.format { - OutFormat::Tex => { - format_tex_line(config, word_ref, &lines[word_ref.local_line_nr], &reference) - } - OutFormat::Roff => { - format_roff_line(config, word_ref, &lines[word_ref.local_line_nr], &reference) - } + OutFormat::Tex => format_tex_line( + config, + word_ref, + &lines[word_ref.local_line_nr], + &chars_lines[word_ref.local_line_nr], + &reference, + ), + OutFormat::Roff => format_roff_line( + config, + word_ref, + &lines[word_ref.local_line_nr], + &chars_lines[word_ref.local_line_nr], + &reference, + ), OutFormat::Dumb => crash!(1, "There is no dumb format with GNU extensions disabled"), }; crash_if_err!(1, writeln!(writer, "{}", output_line)); From b387565ba3d4a8761cd0462bb79a26b8c6b46ae5 Mon Sep 17 00:00:00 2001 From: Wisha Wa Date: Mon, 12 Oct 2020 01:59:06 +0700 Subject: [PATCH 002/132] ptx: remove unneeded regex and reduce repetitive regex compilations --- src/uu/ptx/src/ptx.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index 3bc2ee297..6981eeacc 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -211,11 +211,7 @@ fn read_input(input_files: &[String], config: &Config) -> FileMap { Box::new(file) }); let lines: Vec = reader.lines().map(|x| crash_if_err!(1, x)).collect(); - let ws_reg = Regex::new(r"[\t\n\v\f\r]").unwrap(); - let chars_lines: Vec> = lines - .iter() - .map(|x| ws_reg.replace_all(x, " ").chars().collect()) - .collect(); + let chars_lines: Vec> = lines.iter().map(|x| x.chars().collect()).collect(); let size = lines.len(); file_map.insert( filename.to_owned(), @@ -274,12 +270,11 @@ fn create_word_set(config: &Config, filter: &WordFilter, file_map: &FileMap) -> word_set } -fn get_reference(config: &Config, word_ref: &WordRef, line: &str) -> String { +fn get_reference(config: &Config, word_ref: &WordRef, line: &str, context_reg: &Regex) -> String { if config.auto_ref { format!("{}:{}", word_ref.filename, word_ref.local_line_nr + 1) } else if config.input_ref { - let reg = Regex::new(&config.context_regex).unwrap(); - let (beg, end) = match reg.find(line) { + let (beg, end) = match context_reg.find(line) { Some(x) => (x.start(), x.end()), None => (0, 0), }; @@ -524,6 +519,8 @@ fn write_traditional_output( Box::new(file) }); + let context_reg = Regex::new(&config.context_regex).unwrap(); + for word_ref in words.iter() { let file_map_value: &FileContent = file_map .get(&(word_ref.filename)) @@ -537,6 +534,7 @@ fn write_traditional_output( config, word_ref, &lines[word_ref.local_line_nr], + &context_reg, ); let output_line: String = match config.format { OutFormat::Tex => format_tex_line( From 58b9372dbe21efe87e637d8db9a8f52e20512872 Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Thu, 18 Mar 2021 14:46:56 +0100 Subject: [PATCH 003/132] rm: fix for -d to match GNU's output #1769 --- src/uu/rm/src/rm.rs | 26 +++++++++++++++++++------- tests/by-util/test_rm.rs | 17 +++++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 466a8d6c1..e858e3b0a 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -305,16 +305,28 @@ fn remove_dir(path: &Path, options: &Options) -> bool { true }; if response { - match fs::remove_dir(path) { - Ok(_) => { - if options.verbose { - println!("removed '{}'", path.display()); + if let Ok(mut read_dir) = fs::read_dir(path) { + if options.dir && read_dir.next().is_none() { + match fs::remove_dir(path) { + Ok(_) => { + if options.verbose { + println!("removed directory '{}'", path.display()); + } + } + Err(e) => { + show_error!("cannot remove '{}': {}", path.display(), e); + return true; + } } - } - Err(e) => { - show_error!("removing '{}': {}", path.display(), e); + } else { + // directory can be read but is not empty + show_error!("cannot remove '{}': Directory not empty", path.display()); return true; } + } else { + // GNU's rm shows this message if directory is empty but not readable + show_error!("cannot remove '{}': Directory not empty", path.display()); + return true; } } diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 27568957a..06d1d435d 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -115,6 +115,23 @@ fn test_rm_empty_directory() { assert!(!at.dir_exists(dir)); } +#[test] +fn test_rm_non_empty_directory() { + let (at, mut ucmd) = at_and_ucmd!(); + let dir = "test_rm_non_empty_dir"; + let file_a = &format!("{}/test_rm_non_empty_file_a", dir); + + at.mkdir(dir); + at.touch(file_a); + + let result = ucmd.arg("-d").arg(dir).fails(); + assert!(result + .stderr + .contains(&format!("cannot remove '{}': Directory not empty", dir))); + assert!(at.file_exists(file_a)); + assert!(at.dir_exists(dir)); +} + #[test] fn test_rm_recursive() { let (at, mut ucmd) = at_and_ucmd!(); From bdf603a65ef5d40741cdf18b765611d239822230 Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Tue, 23 Mar 2021 19:12:10 +0100 Subject: [PATCH 004/132] rm: make -d/-r obligatory for removing symlink_dir (windows) --- src/uu/rm/src/rm.rs | 31 ++++++++++++++++++++----------- tests/by-util/test_rm.rs | 3 +++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index e858e3b0a..6e26cb82a 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -306,21 +306,30 @@ fn remove_dir(path: &Path, options: &Options) -> bool { }; if response { if let Ok(mut read_dir) = fs::read_dir(path) { - if options.dir && read_dir.next().is_none() { - match fs::remove_dir(path) { - Ok(_) => { - if options.verbose { - println!("removed directory '{}'", path.display()); + if options.dir || options.recursive { + if read_dir.next().is_none() { + match fs::remove_dir(path) { + Ok(_) => { + if options.verbose { + println!("removed directory '{}'", path.display()); + } + } + Err(e) => { + show_error!("cannot remove '{}': {}", path.display(), e); + return true; } } - Err(e) => { - show_error!("cannot remove '{}': {}", path.display(), e); - return true; - } + } else { + // directory can be read but is not empty + show_error!("cannot remove '{}': Directory not empty", path.display()); + return true; } } else { - // directory can be read but is not empty - show_error!("cannot remove '{}': Directory not empty", path.display()); + // called to remove a symlink_dir (windows) without "-r"/"-R" or "-d" + show_error!( + "could not remove directory '{}' (did you mean to pass '-r' or '-R'?)", + path.display() + ); return true; } } else { diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 06d1d435d..9556bf8e7 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -194,7 +194,10 @@ fn test_rm_dir_symlink() { at.mkdir(dir); at.symlink_dir(dir, link); + #[cfg(not(windows))] ucmd.arg(link).succeeds(); + #[cfg(windows)] + ucmd.arg("-r").arg(link).succeeds(); } #[test] From 61eb4f250d761e893168a6345fbf1f4c0338280b Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Thu, 25 Mar 2021 23:04:02 +0100 Subject: [PATCH 005/132] rm: add more tests --- src/uu/rm/src/rm.rs | 9 ++--- tests/by-util/test_rm.rs | 77 ++++++++++++++++++++++++++++++---------- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 6e26cb82a..033a1a4aa 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -233,7 +233,7 @@ fn remove(files: Vec, options: Options) -> bool { // (e.g., permission), even rm -f should fail with // outputting the error, but there's no easy eay. if !options.force { - show_error!("no such file or directory '{}'", filename); + show_error!("cannot remove '{}': No such file or directory", filename); true } else { false @@ -289,7 +289,7 @@ fn handle_dir(path: &Path, options: &Options) -> bool { had_err = true; } else { show_error!( - "could not remove directory '{}' (did you mean to pass '-r' or '-R'?)", + "cannot remove '{}': Is a directory", // GNU's rm error message does not include help path.display() ); had_err = true; @@ -326,10 +326,7 @@ fn remove_dir(path: &Path, options: &Options) -> bool { } } else { // called to remove a symlink_dir (windows) without "-r"/"-R" or "-d" - show_error!( - "could not remove directory '{}' (did you mean to pass '-r' or '-R'?)", - path.display() - ); + show_error!("cannot remove '{}': Is a directory", path.display()); return true; } } else { diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 9556bf8e7..149d509c5 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -17,7 +17,12 @@ fn test_rm_failed() { let (_at, mut ucmd) = at_and_ucmd!(); let file = "test_rm_one_file"; - ucmd.arg(file).fails(); // Doesn't exist + let result = ucmd.arg(file).fails(); // Doesn't exist + + assert!(result.stderr.contains(&format!( + "cannot remove '{}': No such file or directory", + file + ))); } #[test] @@ -115,6 +120,22 @@ fn test_rm_empty_directory() { assert!(!at.dir_exists(dir)); } +#[test] +fn test_rm_empty_directory_verbose() { + let (at, mut ucmd) = at_and_ucmd!(); + let dir = "test_rm_empty_directory_verbose"; + + at.mkdir(dir); + + ucmd.arg("-d") + .arg("-v") + .arg(dir) + .succeeds() + .stdout_only(format!("removed directory '{}'\n", dir)); + + assert!(!at.dir_exists(dir)); +} + #[test] fn test_rm_non_empty_directory() { let (at, mut ucmd) = at_and_ucmd!(); @@ -151,22 +172,17 @@ fn test_rm_recursive() { } #[test] -fn test_rm_errors() { +fn test_rm_directory_without_flag() { let (at, mut ucmd) = at_and_ucmd!(); - let dir = "test_rm_errors_directory"; - let file_a = "test_rm_errors_directory/test_rm_errors_file_a"; - let file_b = "test_rm_errors_directory/test_rm_errors_file_b"; + let dir = "test_rm_directory_without_flag_dir"; at.mkdir(dir); - at.touch(file_a); - at.touch(file_b); - // $ rm test_rm_errors_directory - // rm: error: could not remove directory 'test_rm_errors_directory' (did you mean to pass '-r'?) - ucmd.arg(dir).fails().stderr_is( - "rm: error: could not remove directory 'test_rm_errors_directory' (did you mean \ - to pass '-r' or '-R'?)\n", - ); + let result = ucmd.arg(dir).fails(); + println!("{}", result.stderr); + assert!(result + .stderr + .contains(&format!("cannot remove '{}': Is a directory", dir))); } #[test] @@ -186,18 +202,41 @@ fn test_rm_verbose() { } #[test] -fn test_rm_dir_symlink() { +#[cfg(not(windows))] +// on unix symlink_dir is a file +fn test_rm_symlink_dir() { let (at, mut ucmd) = at_and_ucmd!(); - let dir = "test_rm_dir_symlink_dir"; - let link = "test_rm_dir_symlink_link"; + + let dir = "test_rm_symlink_dir_directory"; + let link = "test_rm_symlink_dir_link"; at.mkdir(dir); at.symlink_dir(dir, link); - #[cfg(not(windows))] ucmd.arg(link).succeeds(); - #[cfg(windows)] - ucmd.arg("-r").arg(link).succeeds(); +} + +#[test] +#[cfg(windows)] +// on windows removing symlink_dir requires "-r" or "-d" +fn test_rm_symlink_dir() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let dir = "test_rm_symlink_dir_directory"; + let link = "test_rm_symlink_dir_link"; + + at.mkdir(dir); + at.symlink_dir(dir, link); + + let result = scene.ucmd().arg(link).fails(); + assert!(result + .stderr + .contains(&format!("cannot remove '{}': Is a directory", link))); + + assert!(at.dir_exists(link)); + + scene.ucmd().arg("-r").arg(link).succeeds(); } #[test] From 83f8140aafe80a9683eb008362caedef87edd831 Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Fri, 26 Mar 2021 19:26:37 +0300 Subject: [PATCH 006/132] cat: move cat to clap (#1910) --- src/uu/cat/Cargo.toml | 1 + src/uu/cat/src/cat.rs | 142 ++++++++++++++++++++++++++++++++---------- 2 files changed, 109 insertions(+), 34 deletions(-) diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index 415477588..b6254cf6b 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -15,6 +15,7 @@ edition = "2018" path = "src/cat.rs" [dependencies] +clap = "2.33" quick-error = "1.2.3" uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index 0a35e243b..cf5a384a4 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -17,6 +17,7 @@ extern crate unix_socket; extern crate uucore; // last synced with: cat (GNU coreutils) 8.13 +use clap::{App, Arg}; use quick_error::ResultExt; use std::fs::{metadata, File}; use std::io::{self, stderr, stdin, stdout, BufWriter, Read, Write}; @@ -30,10 +31,11 @@ use std::os::unix::fs::FileTypeExt; #[cfg(unix)] use unix_socket::UnixStream; +static NAME: &str = "cat"; +static VERSION: &str = env!("CARGO_PKG_VERSION"); static SYNTAX: &str = "[OPTION]... [FILE]..."; static SUMMARY: &str = "Concatenate FILE(s), or standard input, to standard output With no FILE, or when FILE is -, read standard input."; -static LONG_HELP: &str = ""; #[derive(PartialEq)] enum NumberingMode { @@ -124,50 +126,122 @@ enum InputType { type CatResult = Result; +mod options { + pub static FILE: &str = "file"; + pub static SHOW_ALL: &str = "show-all"; + pub static NUMBER_NONBLANK: &str = "number-nonblank"; + pub static SHOW_NONPRINTING_ENDS: &str = "e"; + pub static SHOW_ENDS: &str = "show-ends"; + pub static NUMBER: &str = "number"; + pub static SQUEEZE_BLANK: &str = "squeeze-blank"; + pub static SHOW_NONPRINTING_TABS: &str = "t"; + pub static SHOW_TABS: &str = "show-tabs"; + pub static SHOW_NONPRINTING: &str = "show-nonprinting"; +} + pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); - let matches = app!(SYNTAX, SUMMARY, LONG_HELP) - .optflag("A", "show-all", "equivalent to -vET") - .optflag( - "b", - "number-nonblank", - "number nonempty output lines, overrides -n", + let matches = App::new(executable!()) + .name(NAME) + .version(VERSION) + .usage(SYNTAX) + .about(SUMMARY) + .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) + .arg( + Arg::with_name(options::SHOW_ALL) + .short("A") + .long(options::SHOW_ALL) + .help("equivalent to -vET"), ) - .optflag("e", "", "equivalent to -vE") - .optflag("E", "show-ends", "display $ at end of each line") - .optflag("n", "number", "number all output lines") - .optflag("s", "squeeze-blank", "suppress repeated empty output lines") - .optflag("t", "", "equivalent to -vT") - .optflag("T", "show-tabs", "display TAB characters as ^I") - .optflag( - "v", - "show-nonprinting", - "use ^ and M- notation, except for LF (\\n) and TAB (\\t)", + .arg( + Arg::with_name(options::NUMBER_NONBLANK) + .short("b") + .long(options::NUMBER_NONBLANK) + .help("number nonempty output lines, overrides -n") + .overrides_with(options::NUMBER), ) - .parse(args); + .arg( + Arg::with_name(options::SHOW_NONPRINTING_ENDS) + .short("e") + .help("equivalent to -vE"), + ) + .arg( + Arg::with_name(options::SHOW_ENDS) + .short("E") + .long(options::SHOW_ENDS) + .help("display $ at end of each line"), + ) + .arg( + Arg::with_name(options::NUMBER) + .short("n") + .long(options::NUMBER) + .help("number all output lines"), + ) + .arg( + Arg::with_name(options::SQUEEZE_BLANK) + .short("s") + .long(options::SQUEEZE_BLANK) + .help("suppress repeated empty output lines"), + ) + .arg( + Arg::with_name(options::SHOW_NONPRINTING_TABS) + .short("t") + .long(options::SHOW_NONPRINTING_TABS) + .help("equivalent to -vT"), + ) + .arg( + Arg::with_name(options::SHOW_TABS) + .short("T") + .long(options::SHOW_TABS) + .help("display TAB characters at ^I"), + ) + .arg( + Arg::with_name(options::SHOW_NONPRINTING) + .short("v") + .long(options::SHOW_NONPRINTING) + .help("use ^ and M- notation, except for LF (\\n) and TAB (\\t)"), + ) + .get_matches_from(args); - let number_mode = if matches.opt_present("b") { + let number_mode = if matches.is_present(options::NUMBER_NONBLANK) { NumberingMode::NonEmpty - } else if matches.opt_present("n") { + } else if matches.is_present(options::NUMBER) { NumberingMode::All } else { NumberingMode::None }; - let show_nonprint = matches.opts_present(&[ - "A".to_owned(), - "e".to_owned(), - "t".to_owned(), - "v".to_owned(), - ]); - let show_ends = matches.opts_present(&["E".to_owned(), "A".to_owned(), "e".to_owned()]); - let show_tabs = matches.opts_present(&["A".to_owned(), "T".to_owned(), "t".to_owned()]); - let squeeze_blank = matches.opt_present("s"); - let mut files = matches.free; - if files.is_empty() { - files.push("-".to_owned()); - } + let show_nonprint = vec![ + options::SHOW_ALL.to_owned(), + options::SHOW_NONPRINTING_ENDS.to_owned(), + options::SHOW_NONPRINTING_TABS.to_owned(), + options::SHOW_NONPRINTING.to_owned(), + ] + .iter() + .any(|v| matches.is_present(v)); + + let show_ends = vec![ + options::SHOW_ENDS.to_owned(), + options::SHOW_ALL.to_owned(), + options::SHOW_NONPRINTING_ENDS.to_owned(), + ] + .iter() + .any(|v| matches.is_present(v)); + + let show_tabs = vec![ + options::SHOW_ALL.to_owned(), + options::SHOW_TABS.to_owned(), + options::SHOW_NONPRINTING_TABS.to_owned(), + ] + .iter() + .any(|v| matches.is_present(v)); + + let squeeze_blank = matches.is_present(options::SQUEEZE_BLANK); + let files: Vec = match matches.values_of(options::FILE) { + Some(v) => v.clone().map(|v| v.to_owned()).collect(), + None => vec!["-".to_owned()], + }; let can_write_fast = !(show_tabs || show_nonprint @@ -361,7 +435,7 @@ fn write_file_lines(file: &str, options: &OutputOptions, state: &mut OutputState } writer.write_all(options.end_of_line.as_bytes())?; if handle.is_interactive { - writer.flush().context(&file[..])?; + writer.flush().context(file)?; } } state.at_line_start = true; From 955c547adffda3546ab6b9fb58d7d508f439eb3f Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Fri, 26 Mar 2021 19:12:01 +0100 Subject: [PATCH 007/132] ls: overrideable `-n` option (#1917) --- src/uu/ls/src/ls.rs | 87 +++++++++++++++++++--------------------- tests/by-util/test_ls.rs | 61 ++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 45 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 8714a0fa1..201ddc7a6 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -84,6 +84,7 @@ pub mod options { pub static COMMAS: &str = "m"; pub static LONG_NO_OWNER: &str = "g"; pub static LONG_NO_GROUP: &str = "o"; + pub static LONG_NUMERIC_UID_GID: &str = "numeric-uid-gid"; } pub mod files { pub static ALL: &str = "all"; @@ -114,7 +115,6 @@ pub mod options { pub static CLASSIFY: &str = "classify"; pub static INODE: &str = "inode"; pub static DEREFERENCE: &str = "dereference"; - pub static NUMERIC_UID_GID: &str = "numeric-uid-gid"; pub static REVERSE: &str = "reverse"; pub static RECURSIVE: &str = "recursive"; pub static COLOR: &str = "color"; @@ -167,7 +167,6 @@ struct Config { classify: bool, ignore_backups: bool, size_format: SizeFormat, - numeric_uid_gid: bool, directory: bool, time: Time, #[cfg(unix)] @@ -183,6 +182,8 @@ struct LongFormat { author: bool, group: bool, owner: bool, + #[cfg(unix)] + numeric_uid_gid: bool, } impl Config { @@ -210,7 +211,7 @@ impl Config { (Format::Columns, options::format::COLUMNS) }; - // The -o and -g options are tricky. They cannot override with each + // The -o, -n and -g options are tricky. They cannot override with each // other because it's possible to combine them. For example, the option // -og should hide both owner and group. Furthermore, they are not // reset if -l or --format=long is used. So these should just show the @@ -223,42 +224,26 @@ impl Config { // which always applies. // // The idea here is to not let these options override with the other - // options, but manually check the last index they occur. If this index - // is larger than the index for the other format options, we apply the - // long format. - match options.indices_of(opt).map(|x| x.max().unwrap()) { - None => { - if options.is_present(options::format::LONG_NO_GROUP) - || options.is_present(options::format::LONG_NO_OWNER) - { - format = Format::Long; - } else if options.is_present(options::format::ONELINE) { - format = Format::OneLine; - } - } - Some(mut idx) => { - if let Some(indices) = options.indices_of(options::format::LONG_NO_OWNER) { - let i = indices.max().unwrap(); - if i > idx { - format = Format::Long; - idx = i; - } - } - if let Some(indices) = options.indices_of(options::format::LONG_NO_GROUP) { - let i = indices.max().unwrap(); - if i > idx { - format = Format::Long; - idx = i; - } - } - if let Some(indices) = options.indices_of(options::format::ONELINE) { - let i = indices.max().unwrap(); - if i > idx && format != Format::Long { + // options, but manually whether they have an index that's greater than + // the other format options. If so, we set the appropriate format. + if format != Format::Long { + let idx = options.indices_of(opt).map(|x| x.max().unwrap()).unwrap_or(0); + if [options::format::LONG_NO_OWNER, options::format::LONG_NO_GROUP, options::format::LONG_NUMERIC_UID_GID] + .iter() + .flat_map(|opt| options.indices_of(opt)) + .flatten() + .any(|i| i >= idx) + { + format = Format::Long; + } else { + if let Some(mut indices) = options.indices_of(options::format::ONELINE) { + if indices.any(|i| i > idx) { format = Format::OneLine; } } } } + let files = if options.is_present(options::files::ALL) { Files::All @@ -328,10 +313,14 @@ impl Config { let group = !options.is_present(options::NO_GROUP) && !options.is_present(options::format::LONG_NO_GROUP); let owner = !options.is_present(options::format::LONG_NO_OWNER); + #[cfg(unix)] + let numeric_uid_gid = options.is_present(options::format::LONG_NUMERIC_UID_GID); LongFormat { author, group, owner, + #[cfg(unix)] + numeric_uid_gid, } }; @@ -355,7 +344,6 @@ impl Config { classify: options.is_present(options::CLASSIFY), ignore_backups: options.is_present(options::IGNORE_BACKUPS), size_format, - numeric_uid_gid: options.is_present(options::NUMERIC_UID_GID), directory: options.is_present(options::DIRECTORY), time, #[cfg(unix)] @@ -444,22 +432,36 @@ pub fn uumain(args: impl uucore::Args) -> i32 { options::format::COLUMNS, ]), ) - // The next three arguments do not override with the other format + // The next four arguments do not override with the other format // options, see the comment in Config::from for the reason. + // Ideally, they would use Arg::override_with, with their own name + // but that doesn't seem to work in all cases. Example: + // ls -1g1 + // even though `ls -11` and `ls -1 -g -1` work. .arg( Arg::with_name(options::format::ONELINE) .short(options::format::ONELINE) .help("List one file per line.") + .multiple(true) ) .arg( Arg::with_name(options::format::LONG_NO_GROUP) .short(options::format::LONG_NO_GROUP) .help("Long format without group information. Identical to --format=long with --no-group.") + .multiple(true) ) .arg( Arg::with_name(options::format::LONG_NO_OWNER) .short(options::format::LONG_NO_OWNER) .help("Long format without owner information.") + .multiple(true) + ) + .arg( + Arg::with_name(options::format::LONG_NUMERIC_UID_GID) + .short("n") + .long(options::format::LONG_NUMERIC_UID_GID) + .help("-l with numeric UIDs and GIDs.") + .multiple(true) ) // Time arguments @@ -657,12 +659,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { file the link references rather than the link itself.", ), ) - .arg( - Arg::with_name(options::NUMERIC_UID_GID) - .short("n") - .long(options::NUMERIC_UID_GID) - .help("-l with numeric UIDs and GIDs."), - ) + .arg( Arg::with_name(options::REVERSE) .short("r") @@ -852,7 +849,7 @@ fn pad_left(string: String, count: usize) -> String { } fn display_items(items: &[PathBuf], strip: Option<&Path>, config: &Config) { - if config.format == Format::Long || config.numeric_uid_gid { + if config.format == Format::Long { let (mut max_links, mut max_size) = (1, 1); for item in items { let (links, size) = display_dir_entry_size(item, config); @@ -994,7 +991,7 @@ use uucore::entries; #[cfg(unix)] fn display_uname(metadata: &Metadata, config: &Config) -> String { - if config.numeric_uid_gid { + if config.long.numeric_uid_gid { metadata.uid().to_string() } else { entries::uid2usr(metadata.uid()).unwrap_or_else(|_| metadata.uid().to_string()) @@ -1003,7 +1000,7 @@ fn display_uname(metadata: &Metadata, config: &Config) -> String { #[cfg(unix)] fn display_group(metadata: &Metadata, config: &Config) -> String { - if config.numeric_uid_gid { + if config.long.numeric_uid_gid { metadata.gid().to_string() } else { entries::gid2grp(metadata.gid()).unwrap_or_else(|_| metadata.gid().to_string()) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 091d47234..7d5a3da7b 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -297,15 +297,24 @@ fn test_ls_long_formats() { // Regex for three names, so all of author, group and owner let re_three = Regex::new(r"[xrw-]{9} \d ([-0-9_a-z]+ ){3}0").unwrap(); + #[cfg(unix)] + let re_three_num = Regex::new(r"[xrw-]{9} \d (\d+ ){3}0").unwrap(); + // Regex for two names, either: // - group and owner // - author and owner // - author and group let re_two = Regex::new(r"[xrw-]{9} \d ([-0-9_a-z]+ ){2}0").unwrap(); + #[cfg(unix)] + let re_two_num = Regex::new(r"[xrw-]{9} \d (\d+ ){2}0").unwrap(); + // Regex for one name: author, group or owner let re_one = Regex::new(r"[xrw-]{9} \d [-0-9_a-z]+ 0").unwrap(); + #[cfg(unix)] + let re_one_num = Regex::new(r"[xrw-]{9} \d \d+ 0").unwrap(); + // Regex for no names let re_zero = Regex::new(r"[xrw-]{9} \d 0").unwrap(); @@ -329,6 +338,19 @@ fn test_ls_long_formats() { println!("stdout = {:?}", result.stdout); assert!(re_three.is_match(&result.stdout)); + #[cfg(unix)] + { + let result = scene + .ucmd() + .arg("-n") + .arg("--author") + .arg("test-long-formats") + .succeeds(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(re_three_num.is_match(&result.stdout)); + } + for arg in &[ "-l", // only group and owner "-g --author", // only author and group @@ -344,6 +366,19 @@ fn test_ls_long_formats() { println!("stderr = {:?}", result.stderr); println!("stdout = {:?}", result.stdout); assert!(re_two.is_match(&result.stdout)); + + #[cfg(unix)] + { + let result = scene + .ucmd() + .arg("-n") + .args(&arg.split(" ").collect::>()) + .arg("test-long-formats") + .succeeds(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(re_two_num.is_match(&result.stdout)); + } } for arg in &[ @@ -364,6 +399,19 @@ fn test_ls_long_formats() { println!("stderr = {:?}", result.stderr); println!("stdout = {:?}", result.stdout); assert!(re_one.is_match(&result.stdout)); + + #[cfg(unix)] + { + let result = scene + .ucmd() + .arg("-n") + .args(&arg.split(" ").collect::>()) + .arg("test-long-formats") + .succeeds(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(re_one_num.is_match(&result.stdout)); + } } for arg in &[ @@ -387,6 +435,19 @@ fn test_ls_long_formats() { println!("stderr = {:?}", result.stderr); println!("stdout = {:?}", result.stdout); assert!(re_zero.is_match(&result.stdout)); + + #[cfg(unix)] + { + let result = scene + .ucmd() + .arg("-n") + .args(&arg.split(" ").collect::>()) + .arg("test-long-formats") + .succeeds(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(re_zero.is_match(&result.stdout)); + } } } From 3ca21940f8c8f75c3948ed07465a26cf0dc0f960 Mon Sep 17 00:00:00 2001 From: Rein F Date: Sat, 27 Mar 2021 08:55:31 +0100 Subject: [PATCH 008/132] nl: move from getopts to clap (#1921) --- src/uu/nl/Cargo.toml | 2 +- src/uu/nl/src/helper.rs | 26 +++--- src/uu/nl/src/nl.rs | 202 +++++++++++++++++++++------------------- 3 files changed, 119 insertions(+), 111 deletions(-) diff --git a/src/uu/nl/Cargo.toml b/src/uu/nl/Cargo.toml index d5cddbde2..41f7c60ab 100644 --- a/src/uu/nl/Cargo.toml +++ b/src/uu/nl/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/nl.rs" [dependencies] +clap = "2.33.3" aho-corasick = "0.7.3" -getopts = "0.2.18" libc = "0.2.42" memchr = "2.2.0" regex = "1.0.1" diff --git a/src/uu/nl/src/helper.rs b/src/uu/nl/src/helper.rs index 9b98129f1..94ff835d7 100644 --- a/src/uu/nl/src/helper.rs +++ b/src/uu/nl/src/helper.rs @@ -1,5 +1,7 @@ // spell-checker:ignore (ToDO) conv +use crate::options; + // parse_style parses a style string into a NumberingStyle. fn parse_style(chars: &[char]) -> Result { if chars.len() == 1 && chars[0] == 'a' { @@ -23,17 +25,17 @@ fn parse_style(chars: &[char]) -> Result { // parse_options loads the options into the settings, returning an array of // error messages. -pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) -> Vec { +pub fn parse_options(settings: &mut crate::Settings, opts: &clap::ArgMatches) -> Vec { // This vector holds error messages encountered. let mut errs: Vec = vec![]; - settings.renumber = !opts.opt_present("p"); - match opts.opt_str("s") { + settings.renumber = !opts.is_present(options::NO_RENUMBER); + match opts.value_of(options::NUMER_SEPARATOR) { None => {} Some(val) => { - settings.number_separator = val; + settings.number_separator = val.to_owned(); } } - match opts.opt_str("n") { + match opts.value_of(options::NUMBER_FORMAT) { None => {} Some(val) => match val.as_ref() { "ln" => { @@ -50,7 +52,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) -> } }, } - match opts.opt_str("b") { + match opts.value_of(options::BODY_NUMBERING) { None => {} Some(val) => { let chars: Vec = val.chars().collect(); @@ -64,7 +66,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) -> } } } - match opts.opt_str("f") { + match opts.value_of(options::FOOTER_NUMBERING) { None => {} Some(val) => { let chars: Vec = val.chars().collect(); @@ -78,7 +80,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) -> } } } - match opts.opt_str("h") { + match opts.value_of(options::HEADER_NUMBERING) { None => {} Some(val) => { let chars: Vec = val.chars().collect(); @@ -92,7 +94,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) -> } } } - match opts.opt_str("i") { + match opts.value_of(options::LINE_INCREMENT) { None => {} Some(val) => { let conv: Option = val.parse().ok(); @@ -104,7 +106,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) -> } } } - match opts.opt_str("w") { + match opts.value_of(options::NUMBER_WIDTH) { None => {} Some(val) => { let conv: Option = val.parse().ok(); @@ -116,7 +118,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) -> } } } - match opts.opt_str("v") { + match opts.value_of(options::STARTING_LINE_NUMER) { None => {} Some(val) => { let conv: Option = val.parse().ok(); @@ -128,7 +130,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) -> } } } - match opts.opt_str("l") { + match opts.value_of(options::JOIN_BLANK_LINES) { None => {} Some(val) => { let conv: Option = val.parse().ok(); diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index 47b6c3ae9..3b5b5a2e8 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -11,6 +11,7 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::iter::repeat; @@ -67,78 +68,106 @@ enum NumberFormat { RightZero, } +pub mod options { + pub const FILE: &str = "file"; + pub const BODY_NUMBERING: &str = "body-numbering"; + pub const SECTION_DELIMITER: &str = "section-delimiter"; + pub const FOOTER_NUMBERING: &str = "footer-numbering"; + pub const HEADER_NUMBERING: &str = "header-numbering"; + pub const LINE_INCREMENT: &str = "line-increment"; + pub const JOIN_BLANK_LINES: &str = "join-blank-lines"; + pub const NUMBER_FORMAT: &str = "number-format"; + pub const NO_RENUMBER: &str = "no-renumber"; + pub const NUMER_SEPARATOR: &str = "number-separator"; + pub const STARTING_LINE_NUMER: &str = "starting-line-number"; + pub const NUMBER_WIDTH: &str = "number-width"; +} + pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); - let mut opts = getopts::Options::new(); - - opts.optopt( - "b", - "body-numbering", - "use STYLE for numbering body lines", - "STYLE", - ); - opts.optopt( - "d", - "section-delimiter", - "use CC for separating logical pages", - "CC", - ); - opts.optopt( - "f", - "footer-numbering", - "use STYLE for numbering footer lines", - "STYLE", - ); - opts.optopt( - "h", - "header-numbering", - "use STYLE for numbering header lines", - "STYLE", - ); - opts.optopt( - "i", - "line-increment", - "line number increment at each line", - "", - ); - opts.optopt( - "l", - "join-blank-lines", - "group of NUMBER empty lines counted as one", - "NUMBER", - ); - opts.optopt( - "n", - "number-format", - "insert line numbers according to FORMAT", - "FORMAT", - ); - opts.optflag( - "p", - "no-renumber", - "do not reset line numbers at logical pages", - ); - opts.optopt( - "s", - "number-separator", - "add STRING after (possible) line number", - "STRING", - ); - opts.optopt( - "v", - "starting-line-number", - "first line number on each logical page", - "NUMBER", - ); - opts.optopt( - "w", - "number-width", - "use NUMBER columns for line numbers", - "NUMBER", - ); - opts.optflag("", "help", "display this help and exit"); - opts.optflag("V", "version", "version"); + let matches = App::new(executable!()) + .name(NAME) + .version(VERSION) + .usage(USAGE) + .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) + .arg( + Arg::with_name(options::BODY_NUMBERING) + .short("b") + .long(options::BODY_NUMBERING) + .help("use STYLE for numbering body lines") + .value_name("SYNTAX"), + ) + .arg( + Arg::with_name(options::SECTION_DELIMITER) + .short("d") + .long(options::SECTION_DELIMITER) + .help("use CC for separating logical pages") + .value_name("CC"), + ) + .arg( + Arg::with_name(options::FOOTER_NUMBERING) + .short("f") + .long(options::FOOTER_NUMBERING) + .help("use STYLE for numbering footer lines") + .value_name("STYLE"), + ) + .arg( + Arg::with_name(options::HEADER_NUMBERING) + .short("h") + .long(options::HEADER_NUMBERING) + .help("use STYLE for numbering header lines") + .value_name("STYLE"), + ) + .arg( + Arg::with_name(options::LINE_INCREMENT) + .short("i") + .long(options::LINE_INCREMENT) + .help("line number increment at each line") + .value_name("NUMBER"), + ) + .arg( + Arg::with_name(options::JOIN_BLANK_LINES) + .short("l") + .long(options::JOIN_BLANK_LINES) + .help("group of NUMBER empty lines counted as one") + .value_name("NUMBER"), + ) + .arg( + Arg::with_name(options::NUMBER_FORMAT) + .short("n") + .long(options::NUMBER_FORMAT) + .help("insert line numbers according to FORMAT") + .value_name("FORMAT"), + ) + .arg( + Arg::with_name(options::NO_RENUMBER) + .short("p") + .long(options::NO_RENUMBER) + .help("do not reset line numbers at logical pages"), + ) + .arg( + Arg::with_name(options::NUMER_SEPARATOR) + .short("s") + .long(options::NUMER_SEPARATOR) + .help("add STRING after (possible) line number") + .value_name("STRING"), + ) + .arg( + Arg::with_name(options::STARTING_LINE_NUMER) + .short("v") + .long(options::STARTING_LINE_NUMER) + .help("first line number on each logical page") + .value_name("NUMBER"), + ) + .arg( + Arg::with_name(options::NUMBER_WIDTH) + .short("w") + .long(options::NUMBER_WIDTH) + .help("use NUMBER columns for line numbers") + .value_name("NUMBER"), + ) + .get_matches_from(args); // A mutable settings object, initialized with the defaults. let mut settings = Settings { @@ -155,27 +184,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 { number_separator: String::from("\t"), }; - let given_options = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => { - show_error!("{}", f); - print_usage(&opts); - return 1; - } - }; - - if given_options.opt_present("help") { - print_usage(&opts); - return 0; - } - if given_options.opt_present("version") { - version(); - return 0; - } - // Update the settings from the command line options, and terminate the // program if some options could not successfully be parsed. - let parse_errors = helper::parse_options(&mut settings, &given_options); + let parse_errors = helper::parse_options(&mut settings, &matches); if !parse_errors.is_empty() { show_error!("Invalid arguments supplied."); for message in &parse_errors { @@ -184,8 +195,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 { return 1; } - let files = given_options.free; - let mut read_stdin = files.is_empty(); + let mut read_stdin = false; + let files: Vec = match matches.values_of(options::FILE) { + Some(v) => v.clone().map(|v| v.to_owned()).collect(), + None => vec!["-".to_owned()], + }; for file in &files { if file == "-" { @@ -370,11 +384,3 @@ fn pass_none(_: &str, _: ®ex::Regex) -> bool { fn pass_all(_: &str, _: ®ex::Regex) -> bool { true } - -fn print_usage(opts: &getopts::Options) { - println!("{}", opts.usage(USAGE)); -} - -fn version() { - println!("{} {}", NAME, VERSION); -} From 3ae714e88cdf2e2176ac5386e175794ab5bdf48a Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Sat, 27 Mar 2021 09:16:45 +0100 Subject: [PATCH 009/132] tests/tee: implemented tests for tee (#1804) These tests are ported from `https://github.com/coreutils/coreutils/tests/misc/tee.sh`. --- tests/by-util/test_tee.rs | 103 +++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index 651491045..5819b3044 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -1 +1,102 @@ -// ToDO: add tests +use crate::common::util::*; + +// tests for basic tee functionality. +// inspired by: +// https://github.com/coreutils/coreutils/tests/misc/tee.sh + +#[test] +fn test_tee_processing_multiple_operands() { + // POSIX says: "Processing of at least 13 file operands shall be supported." + + let content = "tee_sample_content"; + for &n in [1, 2, 12, 13].iter() { + let files = (1..=n).map(|x| x.to_string()).collect::>(); + let (at, mut ucmd) = at_and_ucmd!(); + + ucmd.args(&files) + .pipe_in(content) + .succeeds() + .stdout_is(content); + + for file in files.iter() { + assert!(at.file_exists(file)); + assert_eq!(at.read(file), content); + } + } +} + +#[test] +fn test_tee_treat_minus_as_filename() { + // Ensure tee treats '-' as the name of a file, as mandated by POSIX. + + let (at, mut ucmd) = at_and_ucmd!(); + let content = "tee_sample_content"; + let file = "-"; + + ucmd.arg("-").pipe_in(content).succeeds().stdout_is(content); + + assert!(at.file_exists(file)); + assert_eq!(at.read(file), content); +} + +#[test] +fn test_tee_append() { + let (at, mut ucmd) = at_and_ucmd!(); + let content = "tee_sample_content"; + let file = "tee_out"; + + at.touch(file); + at.write(file, content); + assert_eq!(at.read(file), content); + + ucmd.arg("-a") + .arg(file) + .pipe_in(content) + .succeeds() + .stdout_is(content); + assert!(at.file_exists(file)); + assert_eq!(at.read(file), content.repeat(2)); +} + +#[test] +#[cfg(target_os = "linux")] +fn test_tee_no_more_writeable_stdout() { + let (_at, mut ucmd) = at_and_ucmd!(); + let content = (1..=10) + .map(|x| format!("{}\n", x.to_string())) + .collect::(); + let file_out = "tee_file_out"; + + let _result = ucmd + .arg("/dev/full") + .arg(file_out) + .pipe_in(&content[..]) + .fails(); + + // TODO: comment in after https://github.com/uutils/coreutils/issues/1805 is fixed + // assert_eq!(at.read(file_out), content); + // assert!(result.stdout.contains(&content)); + // assert!(result.stderr.contains("No space left on device")); +} + +#[test] +#[cfg(target_os = "linux")] +fn test_tee_no_more_writeable_stdin() { + let (_at, mut ucmd) = at_and_ucmd!(); + let _content = (1..=10) + .map(|x| format!("{}\n", x.to_string())) + .collect::(); + let file_out_a = "tee_file_out_a"; + let file_out_b = "tee_file_out_b"; + + let _result = ucmd + .arg(file_out_a) + .arg(file_out_b) + .pipe_in("/dev/full") + .succeeds(); // TODO: expected to succeed currently; change to fails() when required + + // TODO: comment in after https://github.com/uutils/coreutils/issues/1805 is fixed + // assert_eq!(at.read(file_out_a), content); + // assert_eq!(at.read(file_out_b), content); + // assert!(result.stderr.contains("No space left on device")); +} From 35675fdfe7639acdb81c0bdc97a3f59780a52a04 Mon Sep 17 00:00:00 2001 From: Antonio Gurgel Date: Sat, 27 Mar 2021 01:18:47 -0700 Subject: [PATCH 010/132] install: implement `-C` / `--compare` (#1811) * install: implement `-C` / `--compare` GNU coreutils [1] checks the following: whether - either file is nonexistent, - there's a sticky bit or set[ug]id bit in play, - either file isn't a regular file, - the sizes of both files mismatch, - the destination file's owner differs from intended, or - the contents of both files mismatch. [1] https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/install.c?h=v8.32#n174 * Add test: non-regular files * Forgot a #[test] * Give up on non-regular file test * `cargo fmt` install.rs --- Cargo.lock | 20 ++++++++ Cargo.toml | 1 + src/uu/install/Cargo.toml | 1 + src/uu/install/src/install.rs | 95 +++++++++++++++++++++++++++++++++-- tests/by-util/test_install.rs | 85 +++++++++++++++++++++++++++++++ 5 files changed, 197 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4851a6e13..12cfe7ed6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,6 +187,7 @@ dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -517,6 +518,11 @@ name = "fake-simd" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "file_diff" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "filetime" version = "0.2.14" @@ -730,6 +736,17 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nix" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "nodrop" version = "0.1.14" @@ -1658,6 +1675,7 @@ name = "uu_install" version = "0.0.4" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "file_diff 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2501,6 +2519,7 @@ dependencies = [ "checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" "checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +"checksum file_diff 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" "checksum filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" "checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" "checksum fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" @@ -2532,6 +2551,7 @@ dependencies = [ "checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" "checksum memoffset 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" "checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" +"checksum nix 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" "checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" "checksum num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" "checksum num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" diff --git a/Cargo.toml b/Cargo.toml index 208fd5d9c..08e9a3bb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -334,6 +334,7 @@ conv = "0.3" filetime = "0.2" glob = "0.3.0" libc = "0.2" +nix = "0.20.0" rand = "0.7" regex = "1.0" sha1 = { version="0.6", features=["std"] } diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index 9841ac64a..5aec0b07c 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -20,6 +20,7 @@ path = "src/install.rs" [dependencies] clap = "2.33" filetime = "0.2" +file_diff = "1.0.0" libc = ">= 0.2" uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["mode", "perms", "entries"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 1ac9bc743..db54ee22d 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -13,10 +13,12 @@ mod mode; extern crate uucore; use clap::{App, Arg, ArgMatches}; +use file_diff::diff; use filetime::{set_file_times, FileTime}; use uucore::entries::{grp2gid, usr2uid}; use uucore::perms::{wrap_chgrp, wrap_chown, Verbosity}; +use libc::{getegid, geteuid}; use std::fs; use std::fs::File; use std::os::unix::fs::MetadataExt; @@ -34,6 +36,7 @@ pub struct Behavior { group: String, verbose: bool, preserve_timestamps: bool, + compare: bool, } #[derive(Clone, Eq, PartialEq)] @@ -112,11 +115,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .help("ignored") ) .arg( - // TODO implement flag Arg::with_name(OPT_COMPARE) .short("C") .long(OPT_COMPARE) - .help("(unimplemented) compare each pair of source and destination files, and in some cases, do not modify the destination at all") + .help("compare each pair of source and destination files, and in some cases, do not modify the destination at all") ) .arg( Arg::with_name(OPT_DIRECTORY) @@ -262,8 +264,6 @@ fn check_unimplemented<'a>(matches: &ArgMatches) -> Result<(), &'a str> { Err("--backup") } else if matches.is_present(OPT_BACKUP_2) { Err("-b") - } else if matches.is_present(OPT_COMPARE) { - Err("--compare, -C") } else if matches.is_present(OPT_CREATED) { Err("-D") } else if matches.is_present(OPT_STRIP) { @@ -338,6 +338,7 @@ fn behavior(matches: &ArgMatches) -> Result { group: matches.value_of(OPT_GROUP).unwrap_or("").to_string(), verbose: matches.is_present(OPT_VERBOSE), preserve_timestamps: matches.is_present(OPT_PRESERVE_TIMESTAMPS), + compare: matches.is_present(OPT_COMPARE), }) } @@ -500,7 +501,13 @@ fn copy(from: &PathBuf, to: &PathBuf, b: &Behavior) -> Result<(), ()> { ); return Err(()); } - } else if let Err(err) = fs::copy(from, to) { + } + + if b.compare && !need_copy(from, to, b) { + return Ok(()); + } + + if let Err(err) = fs::copy(from, to) { show_error!( "cannot install '{}' to '{}': {}", from.display(), @@ -583,3 +590,81 @@ fn copy(from: &PathBuf, to: &PathBuf, b: &Behavior) -> Result<(), ()> { Ok(()) } + +/// Return true if a file is necessary to copy. This is the case when: +/// - _from_ or _to_ is nonexistent; +/// - either file has a sticky bit or set[ug]id bit, or the user specified one; +/// - either file isn't a regular file; +/// - the sizes of _from_ and _to_ differ; +/// - _to_'s owner differs from intended; or +/// - the contents of _from_ and _to_ differ. +/// +/// # Parameters +/// +/// _from_ and _to_, if existent, must be non-directories. +/// +/// # Errors +/// +/// Crashes the program if a nonexistent owner or group is specified in _b_. +/// +fn need_copy(from: &PathBuf, to: &PathBuf, b: &Behavior) -> bool { + let from_meta = match fs::metadata(from) { + Ok(meta) => meta, + Err(_) => return true, + }; + let to_meta = match fs::metadata(to) { + Ok(meta) => meta, + Err(_) => return true, + }; + + // setuid || setgid || sticky + let extra_mode: u32 = 0o7000; + + if b.specified_mode.unwrap_or(0) & extra_mode != 0 + || from_meta.mode() & extra_mode != 0 + || to_meta.mode() & extra_mode != 0 + { + return true; + } + + if !from_meta.is_file() || !to_meta.is_file() { + return true; + } + + if from_meta.len() != to_meta.len() { + return true; + } + + // TODO: if -P (#1809) and from/to contexts mismatch, return true. + + if !b.owner.is_empty() { + let owner_id = match usr2uid(&b.owner) { + Ok(id) => id, + _ => crash!(1, "no such user: {}", b.owner), + }; + if owner_id != to_meta.uid() { + return true; + } + } else if !b.group.is_empty() { + let group_id = match grp2gid(&b.group) { + Ok(id) => id, + _ => crash!(1, "no such group: {}", b.group), + }; + if group_id != to_meta.gid() { + return true; + } + } else { + #[cfg(not(target_os = "windows"))] + unsafe { + if to_meta.uid() != geteuid() || to_meta.gid() != getegid() { + return true; + } + } + } + + if !diff(from.to_str().unwrap(), to.to_str().unwrap()) { + return true; + } + + false +} diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 89dfb0e56..dfd5c1c8d 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -1,4 +1,5 @@ use crate::common::util::*; +use filetime::FileTime; use rust_users::*; use std::os::unix::fs::PermissionsExt; @@ -407,3 +408,87 @@ fn test_install_failing_no_such_file() { assert!(r.code == Some(1)); assert!(r.stderr.contains("No such file or directory")); } + +#[test] +fn test_install_copy_then_compare_file() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + let file1 = "test_install_copy_then_compare_file_a1"; + let file2 = "test_install_copy_then_compare_file_a2"; + + at.touch(file1); + scene + .ucmd() + .arg("-C") + .arg(file1) + .arg(file2) + .succeeds() + .no_stderr(); + + let mut file2_meta = at.metadata(file2); + let before = FileTime::from_last_modification_time(&file2_meta); + + scene + .ucmd() + .arg("-C") + .arg(file1) + .arg(file2) + .succeeds() + .no_stderr(); + + file2_meta = at.metadata(file2); + let after = FileTime::from_last_modification_time(&file2_meta); + + assert!(before == after); +} + +#[test] +#[cfg(target_os = "linux")] +fn test_install_copy_then_compare_file_with_extra_mode() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + // XXX: can't tests introspect on their own names? + let file1 = "test_install_copy_then_compare_file_with_extra_mode_a1"; + let file2 = "test_install_copy_then_compare_file_with_extra_mode_a2"; + + at.touch(file1); + scene + .ucmd() + .arg("-C") + .arg(file1) + .arg(file2) + .succeeds() + .no_stderr(); + + let mut file2_meta = at.metadata(file2); + let before = FileTime::from_last_modification_time(&file2_meta); + + scene + .ucmd() + .arg("-C") + .arg(file1) + .arg(file2) + .arg("-m") + .arg("1644") + .succeeds() + .no_stderr(); + + file2_meta = at.metadata(file2); + let after_install_sticky = FileTime::from_last_modification_time(&file2_meta); + + assert!(before != after_install_sticky); + + // dest file still 1644, so need_copy ought to return `true` + scene + .ucmd() + .arg("-C") + .arg(file1) + .arg(file2) + .succeeds() + .no_stderr(); + + file2_meta = at.metadata(file2); + let after_install_sticky_again = FileTime::from_last_modification_time(&file2_meta); + + assert!(after_install_sticky != after_install_sticky_again); +} From e1439dd199dba0b0f600dfaa45218a4a5daa9b98 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 27 Mar 2021 10:06:22 +0100 Subject: [PATCH 011/132] refresh cargo.lock with recent updates (#1924) Updating memoffset v0.6.1 -> v0.6.2 Updating syn v1.0.64 -> v1.0.65 --- Cargo.lock | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12cfe7ed6..99fd7a3f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,7 +335,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -350,7 +350,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -442,7 +442,7 @@ dependencies = [ "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -718,7 +718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memoffset" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -742,7 +742,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1127,7 +1127,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1183,7 +1183,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syn" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1268,7 +1268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1370,6 +1370,7 @@ dependencies = [ name = "uu_cat" version = "0.0.4" dependencies = [ + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.7", @@ -1824,7 +1825,7 @@ name = "uu_nl" version = "0.0.4" dependencies = [ "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2332,7 +2333,7 @@ version = "0.0.5" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2379,7 +2380,7 @@ dependencies = [ "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2399,7 +2400,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2549,7 +2550,7 @@ dependencies = [ "checksum md5 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" -"checksum memoffset 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" +"checksum memoffset 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cc14fc54a812b4472b4113facc3e44d099fbc0ea2ce0551fa5c703f8edfbfd38" "checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" "checksum nix 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" "checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" @@ -2608,7 +2609,7 @@ dependencies = [ "checksum sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0" "checksum smallvec 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f" +"checksum syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum term_grid 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "230d3e804faaed5a39b08319efb797783df2fd9671b39b7596490cb486d702cf" "checksum term_size 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" From faef7e9214e865e369c780bd6182ca306560b1aa Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 27 Mar 2021 10:05:13 +0100 Subject: [PATCH 012/132] fix(install): Unbreak the CI by bringing the old behavior for install of /dev/null --- src/uu/install/src/install.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index db54ee22d..b4f98ec1a 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -488,6 +488,10 @@ fn copy_file_to_file(file: &PathBuf, target: &PathBuf, b: &Behavior) -> i32 { /// If the copy system call fails, we print a verbose error and return an empty error value. /// fn copy(from: &PathBuf, to: &PathBuf, b: &Behavior) -> Result<(), ()> { + if b.compare && !need_copy(from, to, b) { + return Ok(()); + } + if from.to_string_lossy() == "/dev/null" { /* workaround a limitation of fs::copy * https://github.com/rust-lang/rust/issues/79390 @@ -501,13 +505,7 @@ fn copy(from: &PathBuf, to: &PathBuf, b: &Behavior) -> Result<(), ()> { ); return Err(()); } - } - - if b.compare && !need_copy(from, to, b) { - return Ok(()); - } - - if let Err(err) = fs::copy(from, to) { + } else if let Err(err) = fs::copy(from, to) { show_error!( "cannot install '{}' to '{}': {}", from.display(), From 75700677ca440203be5a6cb348b508ff5b592369 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 27 Mar 2021 10:08:03 +0100 Subject: [PATCH 013/132] fix(install): improve the error output when the test is failing --- tests/by-util/test_install.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index dfd5c1c8d..3a8771f5d 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -352,11 +352,19 @@ fn test_install_copy_file() { #[test] #[cfg(target_os = "linux")] fn test_install_target_file_dev_null() { - let (at, mut ucmd) = at_and_ucmd!(); + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + let file1 = "/dev/null"; let file2 = "target_file"; - ucmd.arg(file1).arg(file2).succeeds().no_stderr(); + let result = scene.ucmd().arg(file1).arg(file2).run(); + + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + + assert!(result.success); + assert!(at.file_exists(file2)); } From 4845b3f5dcf1c532ff7774424170efa59091ebae Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 27 Mar 2021 10:29:46 +0100 Subject: [PATCH 014/132] Enable the stale bot to close issues/PR without any activity (#1926) --- .github/stale.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..47076f60f --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,18 @@ +# Number of days of inactivity before an issue/PR becomes stale +daysUntilStale: 365 +# Number of days of inactivity before a stale issue/PR is closed +daysUntilClose: 14 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security + - "Good first bug" +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false From e9ffaf87ea9a84e81d72deb9f86323615324fbec Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 27 Mar 2021 10:47:26 +0100 Subject: [PATCH 015/132] ignore test_install_copy_then_compare_file_with_extra_mode see https://github.com/uutils/coreutils/issues/1927 --- tests/by-util/test_install.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 3a8771f5d..411de61f3 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -452,6 +452,7 @@ fn test_install_copy_then_compare_file() { #[test] #[cfg(target_os = "linux")] +#[ignore] fn test_install_copy_then_compare_file_with_extra_mode() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; From 16878c2daa7c6c525f151f709333f48774c7f08e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 27 Mar 2021 10:54:18 +0100 Subject: [PATCH 016/132] Create CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 128 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..6c50b811d --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +sylvestre@debian.org. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. From ac7edcc4fad4a046bb3a8ae8371cebc5e58256e9 Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Sat, 27 Mar 2021 15:31:06 +0300 Subject: [PATCH 017/132] ptx: delete getopts dependency (#1942) * chore: delete getopts dependency * deps: update Cargo.lock --- Cargo.lock | 1 - src/uu/ptx/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99fd7a3f6..8a56ffbfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1927,7 +1927,6 @@ version = "0.0.4" dependencies = [ "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/uu/ptx/Cargo.toml b/src/uu/ptx/Cargo.toml index d1e0267b6..790b06305 100644 --- a/src/uu/ptx/Cargo.toml +++ b/src/uu/ptx/Cargo.toml @@ -17,7 +17,6 @@ path = "src/ptx.rs" [dependencies] clap = "2.33" aho-corasick = "0.7.3" -getopts = "0.2.18" libc = "0.2.42" memchr = "2.2.0" regex = "1.0.1" From 0bdd61af5e6572be3f77e09d42f0b3d5d9ee91d3 Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Sat, 27 Mar 2021 15:31:29 +0300 Subject: [PATCH 018/132] cksum: use clap for argument management (#1943) --- src/uu/cksum/Cargo.toml | 1 + src/uu/cksum/src/cksum.rs | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/uu/cksum/Cargo.toml b/src/uu/cksum/Cargo.toml index ef3ec8b46..b7ac630f0 100644 --- a/src/uu/cksum/Cargo.toml +++ b/src/uu/cksum/Cargo.toml @@ -15,6 +15,7 @@ edition = "2018" path = "src/cksum.rs" [dependencies] +clap = "2.33" libc = "0.2.42" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index e1c75fffc..bc71a2d97 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -10,6 +10,7 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::fs::File; use std::io::{self, stdin, BufReader, Read}; use std::path::Path; @@ -18,9 +19,10 @@ use std::path::Path; const CRC_TABLE_LEN: usize = 256; const CRC_TABLE: [u32; CRC_TABLE_LEN] = generate_crc_table(); +const VERSION: &str = env!("CARGO_PKG_VERSION"); +const NAME: &str = "cksum"; const SYNTAX: &str = "[OPTIONS] [FILE]..."; const SUMMARY: &str = "Print CRC and size for each file"; -const LONG_HELP: &str = ""; // this is basically a hack to get "loops" to work on Rust 1.33. Once we update to Rust 1.46 or // greater, we can just use while loops @@ -160,10 +162,25 @@ fn cksum(fname: &str) -> io::Result<(u32, usize)> { } } -pub fn uumain(args: impl uucore::Args) -> i32 { - let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str()); +mod options { + pub static FILE: &str = "file"; +} - let files = matches.free; +pub fn uumain(args: impl uucore::Args) -> i32 { + let args = args.collect_str(); + + let matches = App::new(executable!()) + .name(NAME) + .version(VERSION) + .about(SUMMARY) + .usage(SYNTAX) + .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) + .get_matches_from(args); + + let files: Vec = match matches.values_of(options::FILE) { + Some(v) => v.clone().map(|v| v.to_owned()).collect(), + None => vec![], + }; if files.is_empty() { match cksum("-") { From f66a188414886d28f9c5c583e6f048086766040d Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Sat, 27 Mar 2021 22:00:59 +0300 Subject: [PATCH 019/132] mkfifo: general refactor, move to clap, add tests (#1945) * mkfifo: general refactor, move to clap, add unimplemented flags * chore: update Cargo.lock * chore: delete unused variables, simplify multiple lines with crash * test: add tests * chore: revert the use of crash * test: use even more invalid mod mode --- Cargo.lock | 2 +- src/uu/mkfifo/Cargo.toml | 2 +- src/uu/mkfifo/src/mkfifo.rs | 94 ++++++++++++++++++------------------ tests/by-util/test_mkfifo.rs | 49 ++++++++++++++++++- 4 files changed, 97 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a56ffbfd..a5c551228 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1760,7 +1760,7 @@ dependencies = [ name = "uu_mkfifo" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.7", "uucore_procs 0.0.5", diff --git a/src/uu/mkfifo/Cargo.toml b/src/uu/mkfifo/Cargo.toml index 627d4a721..aa347a86e 100644 --- a/src/uu/mkfifo/Cargo.toml +++ b/src/uu/mkfifo/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/mkfifo.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" libc = "0.2.42" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/mkfifo/src/mkfifo.rs b/src/uu/mkfifo/src/mkfifo.rs index 41582b14a..14701af4d 100644 --- a/src/uu/mkfifo/src/mkfifo.rs +++ b/src/uu/mkfifo/src/mkfifo.rs @@ -8,56 +8,55 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use libc::mkfifo; use std::ffi::CString; -use std::io::Error; static NAME: &str = "mkfifo"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static USAGE: &str = "mkfifo [OPTION]... NAME..."; +static SUMMARY: &str = "Create a FIFO with the given name."; + +mod options { + pub static MODE: &str = "mode"; + pub static SE_LINUX_SECURITY_CONTEXT: &str = "Z"; + pub static CONTEXT: &str = "context"; + pub static FIFO: &str = "fifo"; +} pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); - let mut opts = getopts::Options::new(); + let matches = App::new(executable!()) + .name(NAME) + .version(VERSION) + .usage(USAGE) + .about(SUMMARY) + .arg( + Arg::with_name(options::MODE) + .short("m") + .long(options::MODE) + .help("file permissions for the fifo") + .default_value("0666") + .value_name("0666"), + ) + .arg( + Arg::with_name(options::SE_LINUX_SECURITY_CONTEXT) + .short(options::SE_LINUX_SECURITY_CONTEXT) + .help("set the SELinux security context to default type") + ) + .arg(Arg::with_name(options::CONTEXT).long(options::CONTEXT).value_name("CTX").help("like -Z, or if CTX is specified then set the SELinux\nor SMACK security context to CTX")) + .arg(Arg::with_name(options::FIFO).hidden(true).multiple(true)) + .get_matches_from(args); - opts.optopt( - "m", - "mode", - "file permissions for the fifo", - "(default 0666)", - ); - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("V", "version", "output version information and exit"); - - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(err) => panic!("{}", err), - }; - - if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - return 0; + if matches.is_present(options::CONTEXT) { + crash!(1, "--context is not implemented"); + } + if matches.is_present(options::SE_LINUX_SECURITY_CONTEXT) { + crash!(1, "-Z is not implemented"); } - if matches.opt_present("help") || matches.free.is_empty() { - let msg = format!( - "{0} {1} - -Usage: - {0} [OPTIONS] NAME... - -Create a FIFO with the given name.", - NAME, VERSION - ); - - print!("{}", opts.usage(&msg)); - if matches.free.is_empty() { - return 1; - } - return 0; - } - - let mode = match matches.opt_str("m") { + let mode = match matches.value_of(options::MODE) { Some(m) => match usize::from_str_radix(&m, 8) { Ok(m) => m, Err(e) => { @@ -68,21 +67,22 @@ Create a FIFO with the given name.", None => 0o666, }; - let mut exit_status = 0; - for f in &matches.free { + let fifos: Vec = match matches.values_of(options::FIFO) { + Some(v) => v.clone().map(|s| s.to_owned()).collect(), + None => crash!(1, "missing operand"), + }; + + let mut exit_code = 0; + for f in fifos { let err = unsafe { let name = CString::new(f.as_bytes()).unwrap(); mkfifo(name.as_ptr(), mode as libc::mode_t) }; if err == -1 { - show_error!( - "creating '{}': {}", - f, - Error::last_os_error().raw_os_error().unwrap() - ); - exit_status = 1; + show_error!("cannot create fifo '{}': File exists", f); + exit_code = 1; } } - exit_status + exit_code } diff --git a/tests/by-util/test_mkfifo.rs b/tests/by-util/test_mkfifo.rs index 651491045..f60c0a4b8 100644 --- a/tests/by-util/test_mkfifo.rs +++ b/tests/by-util/test_mkfifo.rs @@ -1 +1,48 @@ -// ToDO: add tests +use crate::common::util::*; + +#[test] +fn test_create_fifo_missing_operand() { + new_ucmd!() + .fails() + .stderr_is("mkfifo: error: missing operand"); +} + +#[test] +fn test_create_one_fifo() { + new_ucmd!().arg("abc").succeeds(); +} + +#[test] +fn test_create_one_fifo_with_invalid_mode() { + new_ucmd!() + .arg("abcd") + .arg("-m") + .arg("invalid") + .fails() + .stderr + .contains("invalid mode"); +} + +#[test] +fn test_create_multiple_fifos() { + new_ucmd!() + .arg("abcde") + .arg("def") + .arg("sed") + .arg("dum") + .succeeds(); +} + +#[test] +fn test_create_one_fifo_with_mode() { + new_ucmd!().arg("abcde").arg("-m600").succeeds(); +} + +#[test] +fn test_create_one_fifo_already_exists() { + new_ucmd!() + .arg("abcdef") + .arg("abcdef") + .fails() + .stderr_is("mkfifo: error: cannot create fifo 'abcdef': File exists"); +} From 500771c78d4b6b62bc7203d1624174cd28bd994b Mon Sep 17 00:00:00 2001 From: Ivan Date: Sat, 27 Mar 2021 22:02:49 +0300 Subject: [PATCH 020/132] tee: should match GNU's output if used with /dev/full (#1944) + aligned 'tee' output with GNU tee when one of the files is '/dev/full' + don't stop tee when one of the outputs fails; just continue and return error status from tee in the end Co-authored-by: Ivan Rymarchyk --- src/uu/tee/Cargo.toml | 1 + src/uu/tee/src/tee.rs | 93 +++++++++++++++++++++++++-------------- tests/by-util/test_tee.rs | 19 ++++---- 3 files changed, 73 insertions(+), 40 deletions(-) diff --git a/src/uu/tee/Cargo.toml b/src/uu/tee/Cargo.toml index 99a6ec23e..51bba2e45 100644 --- a/src/uu/tee/Cargo.toml +++ b/src/uu/tee/Cargo.toml @@ -17,6 +17,7 @@ path = "src/tee.rs" [dependencies] clap = "2.33.3" libc = "0.2.42" +retain_mut = "0.1.2" uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["libc"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/tee/src/tee.rs b/src/uu/tee/src/tee.rs index c54fa0d16..4b0f19038 100644 --- a/src/uu/tee/src/tee.rs +++ b/src/uu/tee/src/tee.rs @@ -12,6 +12,7 @@ use clap::{App, Arg}; use std::fs::OpenOptions; use std::io::{copy, sink, stdin, stdout, Error, ErrorKind, Read, Result, Write}; use std::path::{Path, PathBuf}; +use retain_mut::RetainMut; #[cfg(unix)] use uucore::libc; @@ -93,18 +94,33 @@ fn tee(options: Options) -> Result<()> { if options.ignore_interrupts { ignore_interrupts()? } - let mut writers: Vec> = options + let mut writers: Vec = options .files .clone() .into_iter() - .map(|file| open(file, options.append)) + .map(|file| + NamedWriter { + name: file.clone(), + inner: open(file, options.append), + } + ) .collect(); - writers.push(Box::new(stdout())); - let output = &mut MultiWriter { writers }; + + + writers.insert(0, NamedWriter { + name: "'standard output'".to_owned(), + inner: Box::new(stdout()), + }); + + let mut output = MultiWriter::new(writers); let input = &mut NamedReader { inner: Box::new(stdin()) as Box, }; - if copy(input, output).is_err() || output.flush().is_err() { + + // TODO: replaced generic 'copy' call to be able to stop copying + // if all outputs are closed (due to errors) + if copy(input, &mut output).is_err() || output.flush().is_err() || + output.error_occured() { Err(Error::new(ErrorKind::Other, "")) } else { Ok(()) @@ -112,7 +128,7 @@ fn tee(options: Options) -> Result<()> { } fn open(name: String, append: bool) -> Box { - let path = PathBuf::from(name); + let path = PathBuf::from(name.clone()); let inner: Box = { let mut options = OpenOptions::new(); let mode = if append { @@ -125,55 +141,68 @@ fn open(name: String, append: bool) -> Box { Err(_) => Box::new(sink()), } }; - Box::new(NamedWriter { inner, path }) as Box + Box::new(NamedWriter { inner, name }) as Box } struct MultiWriter { - writers: Vec>, + writers: Vec, + initial_len: usize, +} + +impl MultiWriter { + fn new (writers: Vec) -> Self { + Self { + initial_len: writers.len(), + writers, + } + } + fn error_occured(&self) -> bool { + self.writers.len() != self.initial_len + } } impl Write for MultiWriter { fn write(&mut self, buf: &[u8]) -> Result { - for writer in &mut self.writers { - writer.write_all(buf)?; - } + self.writers.retain_mut(|writer| { + let result = writer.write_all(buf); + match result { + Err(f) => { + show_info!("{}: {}", writer.name, f.to_string()); + false + } + _ => true + } + }); Ok(buf.len()) } fn flush(&mut self) -> Result<()> { - for writer in &mut self.writers { - writer.flush()?; - } + self.writers.retain_mut(|writer| { + let result = writer.flush(); + match result { + Err(f) => { + show_info!("{}: {}", writer.name, f.to_string()); + false + } + _ => true + } + }); Ok(()) } } struct NamedWriter { inner: Box, - path: PathBuf, + pub name: String, } impl Write for NamedWriter { fn write(&mut self, buf: &[u8]) -> Result { - match self.inner.write(buf) { - Err(f) => { - self.inner = Box::new(sink()) as Box; - show_warning!("{}: {}", self.path.display(), f.to_string()); - Err(f) - } - okay => okay, - } + self.inner.write(buf) } fn flush(&mut self) -> Result<()> { - match self.inner.flush() { - Err(f) => { - self.inner = Box::new(sink()) as Box; - show_warning!("{}: {}", self.path.display(), f.to_string()); - Err(f) - } - okay => okay, - } + self.inner.flush() } } @@ -185,7 +214,7 @@ impl Read for NamedReader { fn read(&mut self, buf: &mut [u8]) -> Result { match self.inner.read(buf) { Err(f) => { - show_warning!("{}: {}", Path::new("stdin").display(), f.to_string()); + show_info!("{}: {}", Path::new("stdin").display(), f.to_string()); Err(f) } okay => okay, diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index 5819b3044..f01677ae7 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -60,28 +60,31 @@ fn test_tee_append() { #[test] #[cfg(target_os = "linux")] -fn test_tee_no_more_writeable_stdout() { - let (_at, mut ucmd) = at_and_ucmd!(); +fn test_tee_no_more_writeable_1() { + // equals to 'tee /dev/full out2 (); let file_out = "tee_file_out"; - let _result = ucmd + let result = ucmd .arg("/dev/full") .arg(file_out) .pipe_in(&content[..]) .fails(); - // TODO: comment in after https://github.com/uutils/coreutils/issues/1805 is fixed - // assert_eq!(at.read(file_out), content); - // assert!(result.stdout.contains(&content)); - // assert!(result.stderr.contains("No space left on device")); + assert_eq!(at.read(file_out), content); + assert!(result.stdout.contains(&content)); + assert!(result.stderr.contains("No space left on device")); } #[test] #[cfg(target_os = "linux")] -fn test_tee_no_more_writeable_stdin() { +fn test_tee_no_more_writeable_2() { + // should be equals to 'tee out1 out2 >/dev/full Date: Sat, 27 Mar 2021 20:03:47 +0100 Subject: [PATCH 021/132] refresh cargo.lock with recent updates --- Cargo.lock | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index a5c551228..9911ba928 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1062,6 +1062,11 @@ dependencies = [ "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "retain_mut" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rust-ini" version = "0.13.0" @@ -1420,6 +1425,7 @@ dependencies = [ name = "uu_cksum" version = "0.0.4" dependencies = [ + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.7", "uucore_procs 0.0.5", @@ -2132,6 +2138,7 @@ version = "0.0.4" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "retain_mut 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.7", "uucore_procs 0.0.5", ] @@ -2592,6 +2599,7 @@ dependencies = [ "checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" "checksum regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)" = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" "checksum remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +"checksum retain_mut 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53552c6c49e1e13f1a203ef0080ab3bbef0beb570a528993e83df057a9d9bba1" "checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" From 4f6041e39d46cd8c8dcd58fc5e2e490b60bd78e4 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 27 Mar 2021 22:26:08 +0100 Subject: [PATCH 022/132] Only close if stale for one year --- .github/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/stale.yml b/.github/stale.yml index 47076f60f..e0988d0bd 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,7 +1,7 @@ # Number of days of inactivity before an issue/PR becomes stale daysUntilStale: 365 # Number of days of inactivity before a stale issue/PR is closed -daysUntilClose: 14 +daysUntilClose: 365 # Issues with these labels will never be considered stale exemptLabels: - pinned From bcb1828ad608e26072277d5d2738c8eb91d64966 Mon Sep 17 00:00:00 2001 From: k0ur0x Date: Sun, 28 Mar 2021 05:51:43 +0430 Subject: [PATCH 023/132] comm: move from getopts to clap --- src/uu/comm/Cargo.toml | 2 +- src/uu/comm/src/comm.rs | 86 ++++++++++++++++++++++++++++------------- 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/src/uu/comm/Cargo.toml b/src/uu/comm/Cargo.toml index ddfbb6a47..a0dc4e06f 100644 --- a/src/uu/comm/Cargo.toml +++ b/src/uu/comm/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/comm.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" libc = "0.2.42" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/comm/src/comm.rs b/src/uu/comm/src/comm.rs index 3fb1ef395..34b4330c9 100644 --- a/src/uu/comm/src/comm.rs +++ b/src/uu/comm/src/comm.rs @@ -15,21 +15,34 @@ use std::fs::File; use std::io::{self, stdin, BufRead, BufReader, Stdin}; use std::path::Path; -static SYNTAX: &str = "[OPTIONS] FILE1 FILE2"; -static SUMMARY: &str = "Compare sorted files line by line"; +use clap::{App, Arg, ArgMatches}; + +static VERSION: &str = env!("CARGO_PKG_VERSION"); +static ABOUT: &str = "compare two sorted files line by line"; static LONG_HELP: &str = ""; -fn mkdelim(col: usize, opts: &getopts::Matches) -> String { - let mut s = String::new(); - let delim = match opts.opt_str("output-delimiter") { - Some(d) => d, - None => "\t".to_owned(), - }; +mod options { + pub const COLUMN_1: &str = "1"; + pub const COLUMN_2: &str = "2"; + pub const COLUMN_3: &str = "3"; + pub const DELIMITER: &str = "output-delimiter"; + pub const DELIMITER_DEFAULT: &str = "\t"; + pub const FILE_1: &str = "FILE1"; + pub const FILE_2: &str = "FILE2"; +} - if col > 1 && !opts.opt_present("1") { +fn get_usage() -> String { + format!("{} [OPTION]... FILE1 FILE2", executable!()) +} + +fn mkdelim(col: usize, opts: &ArgMatches) -> String { + let mut s = String::new(); + let delim = opts.value_of(options::DELIMITER).unwrap(); + + if col > 1 && !opts.is_present(options::COLUMN_1) { s.push_str(delim.as_ref()); } - if col > 2 && !opts.opt_present("2") { + if col > 2 && !opts.is_present(options::COLUMN_2) { s.push_str(delim.as_ref()); } @@ -57,7 +70,7 @@ impl LineReader { } } -fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) { +fn comm(a: &mut LineReader, b: &mut LineReader, opts: &ArgMatches) { let delim: Vec = (0..4).map(|col| mkdelim(col, opts)).collect(); let ra = &mut String::new(); @@ -80,7 +93,7 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) { match ord { Ordering::Less => { - if !opts.opt_present("1") { + if !opts.is_present(options::COLUMN_1) { ensure_nl(ra); print!("{}{}", delim[1], ra); } @@ -88,7 +101,7 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) { na = a.read_line(ra); } Ordering::Greater => { - if !opts.opt_present("2") { + if !opts.is_present(options::COLUMN_2) { ensure_nl(rb); print!("{}{}", delim[2], rb); } @@ -96,7 +109,7 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) { nb = b.read_line(rb); } Ordering::Equal => { - if !opts.opt_present("3") { + if !opts.is_present(options::COLUMN_3) { ensure_nl(ra); print!("{}{}", delim[3], ra); } @@ -120,21 +133,42 @@ fn open_file(name: &str) -> io::Result { } pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); + let usage = get_usage(); - let matches = app!(SYNTAX, SUMMARY, LONG_HELP) - .optflag("1", "", "suppress column 1 (lines uniq to FILE1)") - .optflag("2", "", "suppress column 2 (lines uniq to FILE2)") - .optflag( - "3", - "", - "suppress column 3 (lines that appear in both files)", + let matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .after_help(LONG_HELP) + .arg( + Arg::with_name(options::COLUMN_1) + .short(options::COLUMN_1) + .help("suppress column 1 (lines unique to FILE1)"), ) - .optopt("", "output-delimiter", "separate columns with STR", "STR") - .parse(args); + .arg( + Arg::with_name(options::COLUMN_2) + .short(options::COLUMN_2) + .help("suppress column 2 (lines unique to FILE2)"), + ) + .arg( + Arg::with_name(options::COLUMN_3) + .short(options::COLUMN_3) + .help("suppress column 3 (lines that appear in both files)"), + ) + .arg( + Arg::with_name(options::DELIMITER) + .long(options::DELIMITER) + .help("separate columns with STR") + .value_name("STR") + .default_value(options::DELIMITER_DEFAULT) + .hide_default_value(true), + ) + .arg(Arg::with_name(options::FILE_1).required(true)) + .arg(Arg::with_name(options::FILE_2).required(true)) + .get_matches_from(args); - let mut f1 = open_file(matches.free[0].as_ref()).unwrap(); - let mut f2 = open_file(matches.free[1].as_ref()).unwrap(); + let mut f1 = open_file(matches.value_of(options::FILE_1).unwrap()).unwrap(); + let mut f2 = open_file(matches.value_of(options::FILE_2).unwrap()).unwrap(); comm(&mut f1, &mut f2, &matches); From 01eb913c05969182c4aadb51fd98f96355f61575 Mon Sep 17 00:00:00 2001 From: Antonio Gurgel Date: Sat, 27 Mar 2021 19:37:58 -0700 Subject: [PATCH 024/132] test_install: Add sleeps To ensure timestamps don't match. Fixes #1927. --- tests/by-util/test_install.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 411de61f3..957bb54d5 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -2,6 +2,7 @@ use crate::common::util::*; use filetime::FileTime; use rust_users::*; use std::os::unix::fs::PermissionsExt; +use std::thread::sleep; #[test] fn test_install_help() { @@ -471,6 +472,7 @@ fn test_install_copy_then_compare_file_with_extra_mode() { let mut file2_meta = at.metadata(file2); let before = FileTime::from_last_modification_time(&file2_meta); + sleep(std::time::Duration::from_millis(1000)); scene .ucmd() @@ -487,6 +489,8 @@ fn test_install_copy_then_compare_file_with_extra_mode() { assert!(before != after_install_sticky); + sleep(std::time::Duration::from_millis(1000)); + // dest file still 1644, so need_copy ought to return `true` scene .ucmd() From ebb4568d5270582edc6da5d91976be2b90604088 Mon Sep 17 00:00:00 2001 From: Antonio Gurgel Date: Sat, 27 Mar 2021 22:46:57 -0700 Subject: [PATCH 025/132] Forgot to unignore the test --- tests/by-util/test_install.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 957bb54d5..d12dc0b8d 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -453,7 +453,6 @@ fn test_install_copy_then_compare_file() { #[test] #[cfg(target_os = "linux")] -#[ignore] fn test_install_copy_then_compare_file_with_extra_mode() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; From a655117a5fe3bfe09ed02eae852a519714d603c9 Mon Sep 17 00:00:00 2001 From: Antonio Gurgel Date: Sun, 28 Mar 2021 00:42:25 -0700 Subject: [PATCH 026/132] `std::thread::sleep` needs target_os Co-authored-by: Sylvestre Ledru --- tests/by-util/test_install.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index d12dc0b8d..af48a0e66 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -2,6 +2,7 @@ use crate::common::util::*; use filetime::FileTime; use rust_users::*; use std::os::unix::fs::PermissionsExt; +#[cfg(target_os = "linux")] use std::thread::sleep; #[test] From 1bfea356a65bae95c4ac5b0cc42439195895e113 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 28 Mar 2021 10:36:44 +0200 Subject: [PATCH 027/132] refresh cargo.lock with recent updates --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9911ba928..5b5869e02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1435,7 +1435,7 @@ dependencies = [ name = "uu_comm" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.7", "uucore_procs 0.0.5", From dd0addb9c12e23a43818a1bfe14559921da59a20 Mon Sep 17 00:00:00 2001 From: Sivachandran Paramasivam Date: Sun, 28 Mar 2021 16:30:49 +0530 Subject: [PATCH 028/132] pathchk: improve unit test code coverage with more tests --- tests/by-util/test_pathchk.rs | 147 +++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 3 deletions(-) diff --git a/tests/by-util/test_pathchk.rs b/tests/by-util/test_pathchk.rs index e24a464e0..d01beccc2 100644 --- a/tests/by-util/test_pathchk.rs +++ b/tests/by-util/test_pathchk.rs @@ -5,11 +5,152 @@ fn test_default_mode() { // test the default mode // accept some reasonable default - new_ucmd!().args(&["abc/def"]).succeeds().no_stdout(); + new_ucmd!().args(&["dir/file"]).succeeds().no_stdout(); - // fail on long inputs + // accept non-portable chars + new_ucmd!().args(&["dir#/$file"]).succeeds().no_stdout(); + + // accept empty path + new_ucmd!().args(&[""]).succeeds().no_stdout(); + + // fail on long path new_ucmd!() - .args(&["test".repeat(20000)]) + .args(&["dir".repeat(libc::PATH_MAX as usize + 1)]) + .fails() + .no_stdout(); + + // fail on long filename + new_ucmd!() + .args(&[format!( + "dir/{}", + "file".repeat(libc::FILENAME_MAX as usize + 1) + )]) .fails() .no_stdout(); } + +#[test] +fn test_posix_mode() { + // test the posix mode + + // accept some reasonable default + new_ucmd!().args(&["-p", "dir/file"]).succeeds().no_stdout(); + + // fail on long path + new_ucmd!() + .args(&[ + "-p", + &"dir".repeat(libc::PATH_MAX as usize + 1).as_str(), + ]) + .fails() + .no_stdout(); + + // fail on long filename + new_ucmd!() + .args(&[ + "-p", + &format!("dir/{}", "file".repeat(libc::FILENAME_MAX as usize + 1)).as_str(), + ]) + .fails() + .no_stdout(); + + // fail on non-portable chars + new_ucmd!().args(&["-p", "dir#/$file"]).fails().no_stdout(); +} + +#[test] +fn test_posix_special() { + // test the posix special mode + + // accept some reasonable default + new_ucmd!().args(&["-P", "dir/file"]).succeeds().no_stdout(); + + // accept non-portable chars + new_ucmd!() + .args(&["-P", "dir#/$file"]) + .succeeds() + .no_stdout(); + + // accept non-leading hyphen + new_ucmd!() + .args(&["-P", "dir/file-name"]) + .succeeds() + .no_stdout(); + + // fail on long path + new_ucmd!() + .args(&[ + "-P", + &"dir".repeat(libc::PATH_MAX as usize + 1).as_str(), + ]) + .fails() + .no_stdout(); + + // fail on long filename + new_ucmd!() + .args(&[ + "-P", + &format!("dir/{}", "file".repeat(libc::FILENAME_MAX as usize + 1)).as_str(), + ]) + .fails() + .no_stdout(); + + // fail on leading hyphen char + new_ucmd!().args(&["-P", "dir/-file"]).fails().no_stdout(); + + // fail on empty path + new_ucmd!().args(&["-P", ""]).fails().no_stdout(); +} + +#[test] +fn test_posix_all() { + // test the posix special mode + + // accept some reasonable default + new_ucmd!().args(&["-p", "-P", "dir/file"]).succeeds().no_stdout(); + + // accept non-leading hyphen + new_ucmd!() + .args(&["-p", "-P", "dir/file-name"]) + .succeeds() + .no_stdout(); + + // fail on long path + new_ucmd!() + .args(&[ + "-p", + "-P", + &"dir".repeat(libc::PATH_MAX as usize + 1).as_str(), + ]) + .fails() + .no_stdout(); + + // fail on long filename + new_ucmd!() + .args(&[ + "-p", + "-P", + &format!("dir/{}", "file".repeat(libc::FILENAME_MAX as usize + 1)).as_str(), + ]) + .fails() + .no_stdout(); + + // fail on non-portable chars + new_ucmd!().args(&["-p", "-P", "dir#/$file"]).fails().no_stdout(); + + // fail on leading hyphen char + new_ucmd!().args(&["-p", "-P", "dir/-file"]).fails().no_stdout(); + + // fail on empty path + new_ucmd!().args(&["-p", "-P", ""]).fails().no_stdout(); +} + +#[test] +fn test_args_parsing() { + // fail on no args + let empty_args: [String; 0] = []; + new_ucmd!() + .args(&empty_args) + .fails() + .no_stdout(); +} \ No newline at end of file From 43c6a52b63623d6c75d924ee85617c8556f86f5b Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Sun, 28 Mar 2021 13:11:39 +0200 Subject: [PATCH 029/132] chmod: move from getopts to clap --- src/uu/chmod/Cargo.toml | 1 + src/uu/chmod/src/chmod.rs | 235 ++++++++++++++++++++++++-------------- 2 files changed, 148 insertions(+), 88 deletions(-) diff --git a/src/uu/chmod/Cargo.toml b/src/uu/chmod/Cargo.toml index 41b73d8a6..d4917b525 100644 --- a/src/uu/chmod/Cargo.toml +++ b/src/uu/chmod/Cargo.toml @@ -15,6 +15,7 @@ edition = "2018" path = "src/chmod.rs" [dependencies] +clap = "2.33.3" libc = "0.2.42" uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs", "mode"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index 61c56dd77..119447b14 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -10,6 +10,7 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::fs; use std::os::unix::fs::{MetadataExt, PermissionsExt}; use std::path::Path; @@ -18,115 +19,173 @@ use uucore::fs::display_permissions_unix; use uucore::mode; use walkdir::WalkDir; -const NAME: &str = "chmod"; -static SUMMARY: &str = "Change the mode of each FILE to MODE. +static VERSION: &str = env!("CARGO_PKG_VERSION"); +static ABOUT: &str = "Change the mode of each FILE to MODE. With --reference, change the mode of each FILE to that of RFILE."; -static LONG_HELP: &str = " - Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'. -"; + +mod options { + pub const CHANGES: &str = "changes"; + pub const QUIET: &str = "quiet"; // visible_alias("silent") + pub const VERBOSE: &str = "verbose"; + pub const NO_PRESERVE_ROOT: &str = "no-preserve-root"; + pub const PRESERVE_ROOT: &str = "preserve-root"; + pub const REFERENCE: &str = "RFILE"; + pub const RECURSIVE: &str = "recursive"; + pub const MODE: &str = "MODE"; + pub const FILE: &str = "FILE"; +} + +fn get_usage() -> String { + format!( + "{0} [OPTION]... MODE[,MODE]... FILE... +or: {0} [OPTION]... OCTAL-MODE FILE... +or: {0} [OPTION]... --reference=RFILE FILE...", + executable!() + ) +} + +fn get_long_usage() -> String { + String::from("Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.") +} pub fn uumain(args: impl uucore::Args) -> i32 { let mut args = args.collect_str(); - let syntax = format!( - "[OPTION]... MODE[,MODE]... FILE... - {0} [OPTION]... OCTAL-MODE FILE... - {0} [OPTION]... --reference=RFILE FILE...", - NAME - ); - let mut opts = app!(&syntax, SUMMARY, LONG_HELP); - opts.optflag( - "c", - "changes", - "like verbose but report only when a change is made", - ) - // TODO: support --silent (can be done using clap) - .optflag("f", "quiet", "suppress most error messages") - .optflag( - "v", - "verbose", - "output a diagnostic for every file processed", - ) - .optflag( - "", - "no-preserve-root", - "do not treat '/' specially (the default)", - ) - .optflag("", "preserve-root", "fail to operate recursively on '/'") - .optopt( - "", - "reference", - "use RFILE's mode instead of MODE values", - "RFILE", - ) - .optflag("R", "recursive", "change files and directories recursively"); + // Before we can parse 'args' with clap (and previously getopts), + // a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE"). + let mode_had_minus_prefix = strip_minus_from_mode(&mut args); - // sanitize input for - at beginning (e.g. chmod -x test_file). Remove - // the option and save it for later, after parsing is finished. - let negative_option = sanitize_input(&mut args); + let usage = get_usage(); + let after_help = get_long_usage(); - let mut matches = opts.parse(args); - if matches.free.is_empty() { - show_error!("missing an argument"); - show_error!("for help, try '{} --help'", NAME); - return 1; - } else { - let changes = matches.opt_present("changes"); - let quiet = matches.opt_present("quiet"); - let verbose = matches.opt_present("verbose"); - let preserve_root = matches.opt_present("preserve-root"); - let recursive = matches.opt_present("recursive"); - let fmode = matches - .opt_str("reference") + let matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .after_help(&after_help[..]) + .arg( + Arg::with_name(options::CHANGES) + .long(options::CHANGES) + .short("c") + .help("like verbose but report only when a change is made"), + ) + .arg( + Arg::with_name(options::QUIET) + .long(options::QUIET) + .visible_alias("silent") + .short("f") + .help("suppress most error messages"), + ) + .arg( + Arg::with_name(options::VERBOSE) + .long(options::VERBOSE) + .short("v") + .help("output a diagnostic for every file processed"), + ) + .arg( + Arg::with_name(options::NO_PRESERVE_ROOT) + .long(options::NO_PRESERVE_ROOT) + .help("do not treat '/' specially (the default)"), + ) + .arg( + Arg::with_name(options::PRESERVE_ROOT) + .long(options::PRESERVE_ROOT) + .help("fail to operate recursively on '/'"), + ) + .arg( + Arg::with_name(options::RECURSIVE) + .long(options::RECURSIVE) + .short("R") + .help("change files and directories recursively"), + ) + .arg( + Arg::with_name(options::REFERENCE) + .long("reference") + .takes_value(true) + .help("use RFILE's mode instead of MODE values"), + ) + .arg( + Arg::with_name(options::MODE) + .required_unless(options::REFERENCE) + .takes_value(true), + // It would be nice if clap could parse with delimeter, e.g. "g-x,u+x", + // however .multiple(true) cannot be used here because FILE already needs that. + // Only one positional argument with .multiple(true) set is allowed per command + ) + .arg( + Arg::with_name(options::FILE) + .required_unless(options::MODE) + .multiple(true), + ) + .get_matches_from(args); + + let changes = matches.is_present(options::CHANGES); + let quiet = matches.is_present(options::QUIET); + let verbose = matches.is_present(options::VERBOSE); + let preserve_root = matches.is_present(options::PRESERVE_ROOT); + let recursive = matches.is_present(options::RECURSIVE); + let fmode = + matches + .value_of(options::REFERENCE) .and_then(|ref fref| match fs::metadata(fref) { Ok(meta) => Some(meta.mode()), Err(err) => crash!(1, "cannot stat attributes of '{}': {}", fref, err), }); - let cmode = if fmode.is_none() { - // If there was a negative option, now it's a good time to - // use it. - if negative_option.is_some() { - negative_option - } else { - Some(matches.free.remove(0)) - } - } else { - None - }; - let chmoder = Chmoder { - changes, - quiet, - verbose, - preserve_root, - recursive, - fmode, - cmode, - }; - match chmoder.chmod(matches.free) { - Ok(()) => {} - Err(e) => return e, - } + let modes = matches.value_of(options::MODE).unwrap(); // should always be Some because required + let mut cmode = if mode_had_minus_prefix { + // clap parsing is finished, now put prefix back + Some(format!("-{}", modes)) + } else { + Some(modes.to_string()) + }; + let mut files: Vec = matches + .values_of(options::FILE) + .map(|v| v.map(ToString::to_string).collect()) + .unwrap_or_default(); + if fmode.is_some() { + // "--reference" and MODE are mutually exclusive + // if "--reference" was used MODE needs to be interpreted as another FILE + // it wasn't possible to implement this behavior directly with clap + files.push(cmode.unwrap()); + cmode = None; + } + + let chmoder = Chmoder { + changes, + quiet, + verbose, + preserve_root, + recursive, + fmode, + cmode, + }; + match chmoder.chmod(files) { + Ok(()) => {} + Err(e) => return e, } 0 } -fn sanitize_input(args: &mut Vec) -> Option { +// Iterate 'args' and delete the first occurrence +// of a prefix '-' if it's associated with MODE +// e.g. "chmod -v -xw -R FILE" -> "chmod -v xw -R FILE" +fn strip_minus_from_mode(args: &mut Vec) -> bool { for i in 0..args.len() { - let first = args[i].chars().next().unwrap(); - if first != '-' { - continue; - } - if let Some(second) = args[i].chars().nth(1) { - match second { - 'r' | 'w' | 'x' | 'X' | 's' | 't' | 'u' | 'g' | 'o' | '0'..='7' => { - return Some(args.remove(i)); + if args[i].starts_with("-") { + if let Some(second) = args[i].chars().nth(1) { + match second { + 'r' | 'w' | 'x' | 'X' | 's' | 't' | 'u' | 'g' | 'o' | '0'..='7' => { + // TODO: use strip_prefix() once minimum rust version reaches 1.45.0 + args[i] = args[i][1..args[i].len()].to_string(); + return true; + } + _ => {} } - _ => {} } } } - None + false } struct Chmoder { From 6d4f70ccb24294f7f6d1e4165809efae41919e13 Mon Sep 17 00:00:00 2001 From: Craig Pastro Date: Sun, 28 Mar 2021 22:08:37 +0900 Subject: [PATCH 030/132] shuf: move from getopts to clap (#1950) --- Cargo.lock | 1960 ++++++++++++++++++------------------ src/uu/shuf/Cargo.toml | 2 +- src/uu/shuf/src/shuf.rs | 279 ++--- tests/by-util/test_shuf.rs | 56 +- 4 files changed, 1186 insertions(+), 1111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b5869e02..343ad1e30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,2651 +4,2649 @@ name = "advapi32-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "aho-corasick" version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" dependencies = [ - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.4", ] [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9", ] [[package]] name = "arrayvec" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" dependencies = [ - "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", + "winapi 0.3.9", ] [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bit-set" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" dependencies = [ - "bit-vec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bit-vec", ] [[package]] name = "bit-vec" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "blake2-rfc" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" dependencies = [ - "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec", + "constant_time_eq", ] [[package]] name = "block-buffer" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" dependencies = [ - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools", + "generic-array", ] [[package]] name = "bstr" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "memchr 2.3.4", + "regex-automata", + "serde", ] [[package]] name = "bumpalo" version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" [[package]] name = "byte-tools" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cast" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version", ] [[package]] name = "cc" version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" dependencies = [ - "num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits", + "time", ] [[package]] name = "clap" version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", ] [[package]] name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", ] [[package]] name = "constant_time_eq" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "conv" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" dependencies = [ - "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "custom_derive", ] [[package]] name = "coreutils" version = "0.0.4" dependencies = [ - "conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "unindent 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uu_arch 0.0.4", - "uu_base32 0.0.4", - "uu_base64 0.0.4", - "uu_basename 0.0.4", - "uu_cat 0.0.4", - "uu_chgrp 0.0.4", - "uu_chmod 0.0.4", - "uu_chown 0.0.4", - "uu_chroot 0.0.4", - "uu_cksum 0.0.4", - "uu_comm 0.0.4", - "uu_cp 0.0.4", - "uu_csplit 0.0.4", - "uu_cut 0.0.4", - "uu_date 0.0.4", - "uu_df 0.0.4", - "uu_dircolors 0.0.4", - "uu_dirname 0.0.4", - "uu_du 0.0.4", - "uu_echo 0.0.4", - "uu_env 0.0.4", - "uu_expand 0.0.4", - "uu_expr 0.0.4", - "uu_factor 0.0.4", - "uu_false 0.0.4", - "uu_fmt 0.0.4", - "uu_fold 0.0.4", - "uu_groups 0.0.4", - "uu_hashsum 0.0.4", - "uu_head 0.0.4", - "uu_hostid 0.0.4", - "uu_hostname 0.0.4", - "uu_id 0.0.4", - "uu_install 0.0.4", - "uu_join 0.0.4", - "uu_kill 0.0.4", - "uu_link 0.0.4", - "uu_ln 0.0.4", - "uu_logname 0.0.4", - "uu_ls 0.0.4", - "uu_mkdir 0.0.4", - "uu_mkfifo 0.0.4", - "uu_mknod 0.0.4", - "uu_mktemp 0.0.4", - "uu_more 0.0.4", - "uu_mv 0.0.4", - "uu_nice 0.0.4", - "uu_nl 0.0.4", - "uu_nohup 0.0.4", - "uu_nproc 0.0.4", - "uu_numfmt 0.0.4", - "uu_od 0.0.4", - "uu_paste 0.0.4", - "uu_pathchk 0.0.4", - "uu_pinky 0.0.4", - "uu_printenv 0.0.4", - "uu_printf 0.0.4", - "uu_ptx 0.0.4", - "uu_pwd 0.0.4", - "uu_readlink 0.0.4", - "uu_realpath 0.0.4", - "uu_relpath 0.0.4", - "uu_rm 0.0.4", - "uu_rmdir 0.0.4", - "uu_seq 0.0.4", - "uu_shred 0.0.4", - "uu_shuf 0.0.4", - "uu_sleep 0.0.4", - "uu_sort 0.0.4", - "uu_split 0.0.4", - "uu_stat 0.0.4", - "uu_stdbuf 0.0.4", - "uu_sum 0.0.4", - "uu_sync 0.0.4", - "uu_tac 0.0.4", - "uu_tail 0.0.4", - "uu_tee 0.0.4", - "uu_test 0.0.4", - "uu_timeout 0.0.4", - "uu_touch 0.0.4", - "uu_tr 0.0.4", - "uu_true 0.0.4", - "uu_truncate 0.0.4", - "uu_tsort 0.0.4", - "uu_tty 0.0.4", - "uu_uname 0.0.4", - "uu_unexpand 0.0.4", - "uu_uniq 0.0.4", - "uu_unlink 0.0.4", - "uu_uptime 0.0.4", - "uu_users 0.0.4", - "uu_wc 0.0.4", - "uu_who 0.0.4", - "uu_whoami 0.0.4", - "uu_yes 0.0.4", - "uucore 0.0.7", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "conv", + "filetime", + "glob 0.3.0", + "lazy_static", + "libc", + "nix 0.20.0", + "rand 0.7.3", + "regex", + "sha1", + "tempfile", + "textwrap", + "time", + "unindent", + "unix_socket", + "users", + "uu_arch", + "uu_base32", + "uu_base64", + "uu_basename", + "uu_cat", + "uu_chgrp", + "uu_chmod", + "uu_chown", + "uu_chroot", + "uu_cksum", + "uu_comm", + "uu_cp", + "uu_csplit", + "uu_cut", + "uu_date", + "uu_df", + "uu_dircolors", + "uu_dirname", + "uu_du", + "uu_echo", + "uu_env", + "uu_expand", + "uu_expr", + "uu_factor", + "uu_false", + "uu_fmt", + "uu_fold", + "uu_groups", + "uu_hashsum", + "uu_head", + "uu_hostid", + "uu_hostname", + "uu_id", + "uu_install", + "uu_join", + "uu_kill", + "uu_link", + "uu_ln", + "uu_logname", + "uu_ls", + "uu_mkdir", + "uu_mkfifo", + "uu_mknod", + "uu_mktemp", + "uu_more", + "uu_mv", + "uu_nice", + "uu_nl", + "uu_nohup", + "uu_nproc", + "uu_numfmt", + "uu_od", + "uu_paste", + "uu_pathchk", + "uu_pinky", + "uu_printenv", + "uu_printf", + "uu_ptx", + "uu_pwd", + "uu_readlink", + "uu_realpath", + "uu_relpath", + "uu_rm", + "uu_rmdir", + "uu_seq", + "uu_shred", + "uu_shuf", + "uu_sleep", + "uu_sort", + "uu_split", + "uu_stat", + "uu_stdbuf", + "uu_sum", + "uu_sync", + "uu_tac", + "uu_tail", + "uu_tee", + "uu_test", + "uu_timeout", + "uu_touch", + "uu_tr", + "uu_true", + "uu_truncate", + "uu_tsort", + "uu_tty", + "uu_uname", + "uu_unexpand", + "uu_uniq", + "uu_unlink", + "uu_uptime", + "uu_users", + "uu_wc", + "uu_who", + "uu_whoami", + "uu_yes", + "uucore", + "walkdir", ] [[package]] name = "cpp" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4875a08600be48dcc9cb6ee07f104a3e0752e95184dede6a30044d6480bf50e8" dependencies = [ - "cpp_macros 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_macros", ] [[package]] name = "cpp_build" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c47531e7e09532ad4827098729794f5e1a5b1c2ccbb5e295498d2e7ab451c445" dependencies = [ - "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_common 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_synmap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "cpp_common 0.4.0", + "cpp_syn", + "cpp_synmap", + "cpp_synom", + "lazy_static", ] [[package]] name = "cpp_common" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e39149a7943affa02f5b6e347ca2840a129cc78d5883ee229f0f1c4027d628" dependencies = [ - "cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_syn", + "cpp_synom", + "lazy_static", + "quote 0.3.15", ] [[package]] name = "cpp_common" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df78ad28e5fe814285016779fb3d3b874520c799a847e6190bf2b834cc4ff283" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "proc-macro2", + "syn", ] [[package]] name = "cpp_macros" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f93a21e618c10abc84ebb63ffa5952e1f7a4568b8141d542d5ef860e4a8fc25" dependencies = [ - "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_common 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "if_rust_version 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "byteorder", + "cpp_common 0.5.6", + "if_rust_version", + "lazy_static", + "proc-macro2", + "quote 1.0.9", + "syn", ] [[package]] name = "cpp_syn" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8cd649bf5b3804d92fe12a60c7698f5a538a6033ed8a668bf5241d4d4f1644e" dependencies = [ - "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_synom", + "quote 0.3.15", + "unicode-xid 0.0.4", ] [[package]] name = "cpp_synmap" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897e4f9cdbe2874edd3ffe53718ee5d8b89e2a970057b2c93d3214104f2e90b6" dependencies = [ - "cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_syn", + "cpp_synom", + "memchr 1.0.2", ] [[package]] name = "cpp_synom" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc8da5694233b646150c785118f77835ad0a49680c7f312a10ef30957c67b6d" dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4", ] [[package]] name = "criterion" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion-plot 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "csv 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "oorandom 11.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "plotters 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", - "tinytemplate 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools 0.10.0", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", ] [[package]] name = "criterion-plot" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" dependencies = [ - "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cast", + "itertools 0.9.0", ] [[package]] name = "crossbeam-channel" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "crossbeam-utils", ] [[package]] name = "crossbeam-deque" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-epoch 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", ] [[package]] name = "crossbeam-utils" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "cfg-if 1.0.0", + "lazy_static", ] [[package]] name = "csv" version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" dependencies = [ - "bstr 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", ] [[package]] name = "csv-core" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" dependencies = [ - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.4", ] [[package]] name = "custom_derive" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" [[package]] name = "data-encoding" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" [[package]] name = "digest" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" dependencies = [ - "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", ] [[package]] name = "dunce" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2641c4a7c0c4101df53ea572bffdc561c146f6c2eb09e4df02bc4811e3feeb4" [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ - "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log", + "regex", ] [[package]] name = "fake-simd" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "file_diff" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" [[package]] name = "filetime" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.5", + "winapi 0.3.9", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fs_extra" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "generic-array" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2297fb0e3ea512e380da24b52dca3924028f59df5e3a17a18f81d8349ca7ebe" dependencies = [ - "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop", + "typenum", ] [[package]] name = "getopts" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" dependencies = [ - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "getrandom" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "libc", + "wasi", ] [[package]] name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "half" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" [[package]] name = "hermit-abi" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "hex" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" [[package]] name = "hostname" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "match_cfg 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "match_cfg", + "winapi 0.3.9", ] [[package]] name = "if_rust_version" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46dbcb333e86939721589d25a3557e180b52778cb33c7fdfe9e0158ff790d5ec" [[package]] name = "ioctl-sys" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2c4b26352496eaaa8ca7cfa9bd99e93419d3f7983dc6e99c2a35fe9e33504a" [[package]] name = "itertools" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" dependencies = [ - "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] name = "itertools" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" dependencies = [ - "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] name = "itertools" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" dependencies = [ - "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] name = "itoa" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "js-sys" version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821" dependencies = [ - "wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen", ] [[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" [[package]] name = "log" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", ] [[package]] name = "match_cfg" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "maybe-uninit" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "md5" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48" [[package]] name = "memchr" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "memchr" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "memoffset" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] name = "nix" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cc", + "cfg-if 0.1.10", + "libc", + "void", ] [[package]] name = "nix" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", ] [[package]] name = "nodrop" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "num-integer" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "num-traits", ] [[package]] name = "num-traits" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] name = "num_cpus" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ - "hermit-abi 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", ] [[package]] name = "number_prefix" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "numtoa" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" [[package]] name = "onig" version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8518fcb2b1b8c2f45f0ad499df4fda6087fc3475ca69a185c173b8315d2fb383" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "lazy_static", + "libc", + "onig_sys", ] [[package]] name = "onig_sys" version = "69.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388410bf5fa341f10e58e6db3975f4bea1ac30247dd79d37a9e5ced3cb4cc3b0" dependencies = [ - "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "pkg-config", ] [[package]] name = "oorandom" version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "paste" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" dependencies = [ - "paste-impl 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)", + "paste-impl", + "proc-macro-hack", ] [[package]] name = "paste-impl" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" dependencies = [ - "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack", ] [[package]] name = "pkg-config" version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] name = "platform-info" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ea9cd21d89bffb387b6c7363d23bead0807be9de676c671b474dd29e7436d3" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi 0.3.9", ] [[package]] name = "plotters" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" dependencies = [ - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "plotters-svg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", ] [[package]] name = "plotters-backend" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" [[package]] name = "plotters-svg" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" dependencies = [ - "plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plotters-backend", ] [[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "proc-macro-hack" version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ - "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.1", ] [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quickcheck" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" dependencies = [ - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger", + "log", + "rand 0.7.3", + "rand_core 0.5.1", ] [[package]] name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" [[package]] name = "quote" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] name = "rand" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "winapi 0.3.9", ] [[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "libc", + "rand_chacha", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", ] [[package]] name = "rand_chacha" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ - "ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" dependencies = [ - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2", ] [[package]] name = "rand_core" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1", ] [[package]] name = "rand_pcg" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1", ] [[package]] name = "rayon" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", ] [[package]] name = "rayon-core" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" dependencies = [ - "crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", ] [[package]] name = "redox_syscall" version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", ] [[package]] name = "redox_termios" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" dependencies = [ - "redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.2.5", ] [[package]] name = "regex" version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" dependencies = [ - "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr 2.3.4", + "regex-syntax", ] [[package]] name = "regex-automata" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" dependencies = [ - "byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", ] [[package]] name = "regex-syntax" version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" [[package]] name = "remove_dir_all" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9", ] [[package]] name = "retain_mut" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53552c6c49e1e13f1a203ef0080ab3bbef0beb570a528993e83df057a9d9bba1" [[package]] name = "rust-ini" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" [[package]] name = "rustc_version" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver", ] [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util", ] [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver-parser", ] [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" [[package]] name = "serde_cbor" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" dependencies = [ - "half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "half", + "serde", ] [[package]] name = "serde_derive" version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "syn", ] [[package]] name = "serde_json" version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" dependencies = [ - "itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa", + "ryu", + "serde", ] [[package]] name = "sha1" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" [[package]] name = "sha2" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" dependencies = [ - "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer", + "byte-tools", + "digest", + "fake-simd", + "generic-array", ] [[package]] name = "sha3" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0" dependencies = [ - "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer", + "byte-tools", + "digest", + "generic-array", ] [[package]] name = "smallvec" version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" dependencies = [ - "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit", ] [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "unicode-xid 0.2.1", ] [[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10", + "libc", + "rand 0.7.3", + "redox_syscall 0.1.57", + "remove_dir_all", + "winapi 0.3.9", ] [[package]] name = "term_grid" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230d3e804faaed5a39b08319efb797783df2fd9671b39b7596490cb486d702cf" dependencies = [ - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "term_size" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi 0.3.9", ] [[package]] name = "termion" version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "numtoa", + "redox_syscall 0.2.5", + "redox_termios", ] [[package]] name = "termsize" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e86d824a8e90f342ad3ef4bd51ef7119a9b681b0cc9f8ee7b2852f02ccd2517" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "kernel32-sys", + "libc", + "termion", + "winapi 0.2.8", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "term_size 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "term_size", + "unicode-width", ] [[package]] name = "thiserror" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" dependencies = [ - "thiserror-impl 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "syn", ] [[package]] name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "redox_syscall 0.1.57", + "winapi 0.3.9", ] [[package]] name = "tinytemplate" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", + "serde_json", ] [[package]] name = "typenum" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" [[package]] name = "unicode-width" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "unindent" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" [[package]] name = "unix_socket" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10", + "libc", ] [[package]] name = "users" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "log", ] [[package]] name = "uu_arch" version = "0.0.4" dependencies = [ - "platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "platform-info", + "uucore", + "uucore_procs", ] [[package]] name = "uu_base32" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_base64" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_basename" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_cat" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "quick-error", + "unix_socket", + "uucore", + "uucore_procs", ] [[package]] name = "uu_chgrp" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore", + "uucore_procs", + "walkdir", ] [[package]] name = "uu_chmod" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "uucore", + "uucore_procs", + "walkdir", ] [[package]] name = "uu_chown" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "glob 0.3.0", + "uucore", + "uucore_procs", + "walkdir", ] [[package]] name = "uu_chroot" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_cksum" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_comm" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_cp" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "ioctl-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "filetime", + "ioctl-sys", + "libc", + "quick-error", + "uucore", + "uucore_procs", + "walkdir", + "winapi 0.3.9", + "xattr", ] [[package]] name = "uu_csplit" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "glob 0.2.11", + "regex", + "thiserror", + "uucore", + "uucore_procs", ] [[package]] name = "uu_cut" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_date" version = "0.0.4" dependencies = [ - "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "clap", + "libc", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_df" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "libc", + "number_prefix", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_dircolors" version = "0.0.4" dependencies = [ - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "glob 0.3.0", + "uucore", + "uucore_procs", ] [[package]] name = "uu_dirname" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_du" version = "0.0.4" dependencies = [ - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_echo" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_env" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "rust-ini", + "uucore", + "uucore_procs", ] [[package]] name = "uu_expand" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "unicode-width", + "uucore", + "uucore_procs", ] [[package]] name = "uu_expr" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "onig 4.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "onig", + "uucore", + "uucore_procs", ] [[package]] name = "uu_factor" version = "0.0.4" dependencies = [ - "criterion 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "criterion", + "num-traits", + "paste", + "quickcheck", + "rand 0.7.3", + "rand_chacha", + "smallvec", + "uucore", + "uucore_procs", ] [[package]] name = "uu_false" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_fmt" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "unicode-width", + "uucore", + "uucore_procs", ] [[package]] name = "uu_fold" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_groups" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_hashsum" version = "0.0.4" dependencies = [ - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "md5 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "blake2-rfc", + "clap", + "digest", + "hex", + "libc", + "md5", + "regex", + "regex-syntax", + "sha1", + "sha2", + "sha3", + "uucore", + "uucore_procs", ] [[package]] name = "uu_head" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_hostid" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_hostname" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hostname 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "hostname", + "libc", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_id" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_install" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "file_diff 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "file_diff", + "filetime", + "libc", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_join" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_kill" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_link" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_ln" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_logname" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_ls" version = "0.0.4" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "term_grid 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "termsize 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "atty", + "clap", + "lazy_static", + "number_prefix", + "term_grid", + "termsize", + "time", + "unicode-width", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mkdir" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mkfifo" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mknod" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mktemp" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "rand 0.5.6", + "tempfile", + "uucore", + "uucore_procs", ] [[package]] name = "uu_more" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "nix 0.13.1", + "redox_syscall 0.1.57", + "redox_termios", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mv" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "fs_extra", + "uucore", + "uucore_procs", ] [[package]] name = "uu_nice" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "nix 0.13.1", + "uucore", + "uucore_procs", ] [[package]] name = "uu_nl" version = "0.0.4" dependencies = [ - "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "aho-corasick", + "clap", + "libc", + "memchr 2.3.4", + "regex", + "regex-syntax", + "uucore", + "uucore_procs", ] [[package]] name = "uu_nohup" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_nproc" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "num_cpus", + "uucore", + "uucore_procs", ] [[package]] name = "uu_numfmt" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_od" version = "0.0.4" dependencies = [ - "byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "byteorder", + "clap", + "half", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_paste" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_pathchk" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_pinky" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_printenv" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_printf" version = "0.0.4" dependencies = [ - "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "itertools 0.8.2", + "uucore", + "uucore_procs", ] [[package]] name = "uu_ptx" version = "0.0.4" dependencies = [ - "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "aho-corasick", + "clap", + "libc", + "memchr 2.3.4", + "regex", + "regex-syntax", + "uucore", + "uucore_procs", ] [[package]] name = "uu_pwd" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_readlink" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_realpath" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_relpath" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "uucore", + "uucore_procs", ] [[package]] name = "uu_rm" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "remove_dir_all", + "uucore", + "uucore_procs", + "walkdir", ] [[package]] name = "uu_rmdir" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_seq" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_shred" version = "0.0.4" dependencies = [ - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "filetime", + "getopts", + "libc", + "rand 0.5.6", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_shuf" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "rand 0.5.6", + "uucore", + "uucore_procs", ] [[package]] name = "uu_sleep" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_sort" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "itertools 0.8.2", + "semver", + "uucore", + "uucore_procs", ] [[package]] name = "uu_split" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_stat" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_stdbuf" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uu_stdbuf_libstdbuf 0.0.4", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "tempfile", + "uu_stdbuf_libstdbuf", + "uucore", + "uucore_procs", ] [[package]] name = "uu_stdbuf_libstdbuf" version = "0.0.4" dependencies = [ - "cpp 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_build 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "cpp", + "cpp_build", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_sum" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "uucore", + "uucore_procs", ] [[package]] name = "uu_sync" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "libc", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_tac" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "uucore", + "uucore_procs", ] [[package]] name = "uu_tail" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "libc", + "redox_syscall 0.1.57", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_tee" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "retain_mut 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "retain_mut", + "uucore", + "uucore_procs", ] [[package]] name = "uu_test" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "redox_syscall 0.1.57", + "uucore", + "uucore_procs", ] [[package]] name = "uu_timeout" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_touch" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "filetime", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_tr" version = "0.0.4" dependencies = [ - "bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "bit-set", + "fnv", + "getopts", + "uucore", + "uucore_procs", ] [[package]] name = "uu_true" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_truncate" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_tsort" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_tty" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_uname" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "platform-info", + "uucore", + "uucore_procs", ] [[package]] name = "uu_unexpand" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "unicode-width", + "uucore", + "uucore_procs", ] [[package]] name = "uu_uniq" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_unlink" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_uptime" version = "0.0.4" dependencies = [ - "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "chrono", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_users" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_wc" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_who" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_whoami" version = "0.0.4" dependencies = [ - "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "advapi32-sys", + "clap", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_yes" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uucore" version = "0.0.7" dependencies = [ - "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dunce 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "wild 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "data-encoding", + "dunce", + "getopts", + "lazy_static", + "libc", + "nix 0.13.1", + "platform-info", + "termion", + "thiserror", + "time", + "wild", ] [[package]] name = "uucore_procs" version = "0.0.5" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "syn", ] [[package]] name = "vec_map" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "walkdir" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ - "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file", + "winapi 0.3.9", + "winapi-util", ] [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3" dependencies = [ - "bumpalo 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote 1.0.9", + "syn", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b" dependencies = [ - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.9", + "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa" [[package]] name = "web-sys" version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310" dependencies = [ - "js-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys", + "wasm-bindgen", ] [[package]] name = "wild" version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020" dependencies = [ - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0", ] [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "xattr" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] - -[metadata] -"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" -"checksum aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -"checksum autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -"checksum bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" -"checksum bit-vec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" -"checksum bstr 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" -"checksum bumpalo 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" -"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" -"checksum byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" -"checksum cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -"checksum chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" -"checksum clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)" = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" -"checksum cpp 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4875a08600be48dcc9cb6ee07f104a3e0752e95184dede6a30044d6480bf50e8" -"checksum cpp_build 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c47531e7e09532ad4827098729794f5e1a5b1c2ccbb5e295498d2e7ab451c445" -"checksum cpp_common 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79e39149a7943affa02f5b6e347ca2840a129cc78d5883ee229f0f1c4027d628" -"checksum cpp_common 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "df78ad28e5fe814285016779fb3d3b874520c799a847e6190bf2b834cc4ff283" -"checksum cpp_macros 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f93a21e618c10abc84ebb63ffa5952e1f7a4568b8141d542d5ef860e4a8fc25" -"checksum cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8cd649bf5b3804d92fe12a60c7698f5a538a6033ed8a668bf5241d4d4f1644e" -"checksum cpp_synmap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "897e4f9cdbe2874edd3ffe53718ee5d8b89e2a970057b2c93d3214104f2e90b6" -"checksum cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc8da5694233b646150c785118f77835ad0a49680c7f312a10ef30957c67b6d" -"checksum criterion 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" -"checksum criterion-plot 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" -"checksum crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" -"checksum crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" -"checksum crossbeam-epoch 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" -"checksum crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" -"checksum csv 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -"checksum csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" -"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" -"checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" -"checksum dunce 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b2641c4a7c0c4101df53ea572bffdc561c146f6c2eb09e4df02bc4811e3feeb4" -"checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum file_diff 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" -"checksum filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" -"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -"checksum fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2297fb0e3ea512e380da24b52dca3924028f59df5e3a17a18f81d8349ca7ebe" -"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" -"checksum getrandom 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -"checksum half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" -"checksum hermit-abi 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" -"checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" -"checksum hostname 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -"checksum if_rust_version 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46dbcb333e86939721589d25a3557e180b52778cb33c7fdfe9e0158ff790d5ec" -"checksum ioctl-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e2c4b26352496eaaa8ca7cfa9bd99e93419d3f7983dc6e99c2a35fe9e33504a" -"checksum itertools 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" -"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" -"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -"checksum itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" -"checksum js-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)" = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" -"checksum log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -"checksum match_cfg 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" -"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -"checksum md5 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48" -"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" -"checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" -"checksum memoffset 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cc14fc54a812b4472b4113facc3e44d099fbc0ea2ce0551fa5c703f8edfbfd38" -"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" -"checksum nix 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" -"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -"checksum num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -"checksum num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -"checksum number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" -"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" -"checksum onig 4.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8518fcb2b1b8c2f45f0ad499df4fda6087fc3475ca69a185c173b8315d2fb383" -"checksum onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388410bf5fa341f10e58e6db3975f4bea1ac30247dd79d37a9e5ced3cb4cc3b0" -"checksum oorandom 11.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -"checksum paste 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" -"checksum paste-impl 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" -"checksum pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" -"checksum platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ea9cd21d89bffb387b6c7363d23bead0807be9de676c671b474dd29e7436d3" -"checksum plotters 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" -"checksum plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" -"checksum plotters-svg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" -"checksum ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" -"checksum proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" -"checksum proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" -"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -"checksum quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" -"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -"checksum rayon 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" -"checksum rayon-core 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" -"checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" -"checksum redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" -"checksum redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" -"checksum regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" -"checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" -"checksum regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)" = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" -"checksum remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -"checksum retain_mut 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53552c6c49e1e13f1a203ef0080ab3bbef0beb570a528993e83df057a9d9bba1" -"checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)" = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" -"checksum serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" -"checksum serde_derive 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)" = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" -"checksum serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)" = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" -"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" -"checksum sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0" -"checksum smallvec 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum syn 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" -"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" -"checksum term_grid 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "230d3e804faaed5a39b08319efb797783df2fd9671b39b7596490cb486d702cf" -"checksum term_size 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" -"checksum termion 1.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" -"checksum termsize 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "5e86d824a8e90f342ad3ef4bd51ef7119a9b681b0cc9f8ee7b2852f02ccd2517" -"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" -"checksum thiserror-impl 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tinytemplate 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -"checksum typenum 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" -"checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" -"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -"checksum unindent 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" -"checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" -"checksum users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486" -"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -"checksum wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe" -"checksum wasm-bindgen-backend 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3" -"checksum wasm-bindgen-macro 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b" -"checksum wasm-bindgen-macro-support 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d" -"checksum wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa" -"checksum web-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310" -"checksum wild 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" diff --git a/src/uu/shuf/Cargo.toml b/src/uu/shuf/Cargo.toml index b78d4fc04..5e7c6c71a 100644 --- a/src/uu/shuf/Cargo.toml +++ b/src/uu/shuf/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/shuf.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" rand = "0.5" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/shuf/src/shuf.rs b/src/uu/shuf/src/shuf.rs index 278e872fb..f7af05214 100644 --- a/src/uu/shuf/src/shuf.rs +++ b/src/uu/shuf/src/shuf.rs @@ -10,132 +10,162 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use rand::Rng; use std::fs::File; use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write}; -use std::usize::MAX as MAX_USIZE; - -enum Mode { - Default, - Echo, - InputRange((usize, usize)), -} static NAME: &str = "shuf"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static USAGE: &str = r#"shuf [OPTION]... [FILE] + or: shuf -e [OPTION]... [ARG]... + or: shuf -i LO-HI [OPTION]... +Write a random permutation of the input lines to standard output. + +With no FILE, or when FILE is -, read standard input. +"#; +static TEMPLATE: &str = "Usage: {usage}\nMandatory arguments to long options are mandatory for short options too.\n{unified}"; + +struct Options { + head_count: usize, + output: Option, + random_source: Option, + repeat: bool, + sep: u8, +} + +enum Mode { + Default(String), + Echo(Vec), + InputRange((usize, usize)), +} + +mod options { + pub static ECHO: &str = "echo"; + pub static INPUT_RANGE: &str = "input-range"; + pub static HEAD_COUNT: &str = "head-count"; + pub static OUTPUT: &str = "output"; + pub static RANDOM_SOURCE: &str = "random-source"; + pub static REPEAT: &str = "repeat"; + pub static ZERO_TERMINATED: &str = "zero-terminated"; + pub static FILE: &str = "file"; +} pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); + let matches = App::new(executable!()) + .name(NAME) + .version(VERSION) + .template(TEMPLATE) + .usage(USAGE) + .arg( + Arg::with_name(options::ECHO) + .short("e") + .long(options::ECHO) + .takes_value(true) + .value_name("ARG") + .help("treat each ARG as an input line") + .multiple(true) + .use_delimiter(false) + .min_values(0) + .conflicts_with(options::INPUT_RANGE), + ) + .arg( + Arg::with_name(options::INPUT_RANGE) + .short("i") + .long(options::INPUT_RANGE) + .takes_value(true) + .value_name("LO-HI") + .help("treat each number LO through HI as an input line") + .conflicts_with(options::FILE), + ) + .arg( + Arg::with_name(options::HEAD_COUNT) + .short("n") + .long(options::HEAD_COUNT) + .takes_value(true) + .value_name("COUNT") + .help("output at most COUNT lines"), + ) + .arg( + Arg::with_name(options::OUTPUT) + .short("o") + .long(options::OUTPUT) + .takes_value(true) + .value_name("FILE") + .help("write result to FILE instead of standard output"), + ) + .arg( + Arg::with_name(options::RANDOM_SOURCE) + .long(options::RANDOM_SOURCE) + .takes_value(true) + .value_name("FILE") + .help("get random bytes from FILE"), + ) + .arg( + Arg::with_name(options::REPEAT) + .short("r") + .long(options::REPEAT) + .help("output lines can be repeated"), + ) + .arg( + Arg::with_name(options::ZERO_TERMINATED) + .short("z") + .long(options::ZERO_TERMINATED) + .help("line delimiter is NUL, not newline"), + ) + .arg(Arg::with_name(options::FILE).takes_value(true)) + .get_matches_from(args); - let mut opts = getopts::Options::new(); - opts.optflag("e", "echo", "treat each ARG as an input line"); - opts.optopt( - "i", - "input-range", - "treat each number LO through HI as an input line", - "LO-HI", - ); - opts.optopt("n", "head-count", "output at most COUNT lines", "COUNT"); - opts.optopt( - "o", - "output", - "write result to FILE instead of standard output", - "FILE", - ); - opts.optopt("", "random-source", "get random bytes from FILE", "FILE"); - opts.optflag("r", "repeat", "output lines can be repeated"); - opts.optflag("z", "zero-terminated", "end lines with 0 byte, not newline"); - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("V", "version", "output version information and exit"); - let mut matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => crash!(1, "{}", f), - }; - if matches.opt_present("help") { - let msg = format!( - "{0} {1} - -Usage: - {0} [OPTION]... [FILE] - {0} -e [OPTION]... [ARG]... - {0} -i LO-HI [OPTION]... - -Write a random permutation of the input lines to standard output. -With no FILE, or when FILE is -, read standard input.", - NAME, VERSION - ); - print!("{}", opts.usage(&msg)); - } else if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); + let mode = if let Some(args) = matches.values_of(options::ECHO) { + Mode::Echo(args.map(String::from).collect()) + } else if let Some(range) = matches.value_of(options::INPUT_RANGE) { + match parse_range(range) { + Ok(m) => Mode::InputRange(m), + Err(msg) => { + crash!(1, "{}", msg); + } + } } else { - let echo = matches.opt_present("echo"); - let mode = match matches.opt_str("input-range") { - Some(range) => { - if echo { - show_error!("cannot specify more than one mode"); - return 1; - } - match parse_range(range) { - Ok(m) => Mode::InputRange(m), - Err(msg) => { - crash!(1, "{}", msg); - } - } - } - None => { - if echo { - Mode::Echo - } else { - if matches.free.is_empty() { - matches.free.push("-".to_owned()); - } else if matches.free.len() > 1 { - show_error!("extra operand '{}'", &matches.free[1][..]); - } - Mode::Default - } - } - }; - let repeat = matches.opt_present("repeat"); - let sep = if matches.opt_present("zero-terminated") { - 0x00_u8 - } else { - 0x0a_u8 - }; - let count = match matches.opt_str("head-count") { - Some(cnt) => match cnt.parse::() { + Mode::Default(matches.value_of(options::FILE).unwrap_or("-").to_string()) + }; + + let options = Options { + head_count: match matches.value_of(options::HEAD_COUNT) { + Some(count) => match count.parse::() { Ok(val) => val, - Err(e) => { - show_error!("'{}' is not a valid count: {}", cnt, e); + Err(_) => { + show_error!("invalid line count: '{}'", count); return 1; } }, - None => MAX_USIZE, - }; - let output = matches.opt_str("output"); - let random = matches.opt_str("random-source"); + None => std::usize::MAX, + }, + output: matches.value_of(options::OUTPUT).map(String::from), + random_source: matches.value_of(options::RANDOM_SOURCE).map(String::from), + repeat: matches.is_present(options::REPEAT), + sep: if matches.is_present(options::ZERO_TERMINATED) { + 0x00_u8 + } else { + 0x0a_u8 + }, + }; - match mode { - Mode::Echo => { - // XXX: this doesn't correctly handle non-UTF-8 cmdline args - let mut evec = matches - .free - .iter() - .map(String::as_bytes) - .collect::>(); - find_seps(&mut evec, sep); - shuf_bytes(&mut evec, repeat, count, sep, output, random); - } - Mode::InputRange((b, e)) => { - let rvec = (b..e).map(|x| format!("{}", x)).collect::>(); - let mut rvec = rvec.iter().map(String::as_bytes).collect::>(); - shuf_bytes(&mut rvec, repeat, count, sep, output, random); - } - Mode::Default => { - let fdata = read_input_file(&matches.free[0][..]); - let mut fdata = vec![&fdata[..]]; - find_seps(&mut fdata, sep); - shuf_bytes(&mut fdata, repeat, count, sep, output, random); - } + match mode { + Mode::Echo(args) => { + let mut evec = args.iter().map(String::as_bytes).collect::>(); + find_seps(&mut evec, options.sep); + shuf_bytes(&mut evec, options); + } + Mode::InputRange((b, e)) => { + let rvec = (b..e).map(|x| format!("{}", x)).collect::>(); + let mut rvec = rvec.iter().map(String::as_bytes).collect::>(); + shuf_bytes(&mut rvec, options); + } + Mode::Default(filename) => { + let fdata = read_input_file(&filename); + let mut fdata = vec![&fdata[..]]; + find_seps(&mut fdata, options.sep); + shuf_bytes(&mut fdata, options); } } @@ -193,15 +223,8 @@ fn find_seps(data: &mut Vec<&[u8]>, sep: u8) { } } -fn shuf_bytes( - input: &mut Vec<&[u8]>, - repeat: bool, - count: usize, - sep: u8, - output: Option, - random: Option, -) { - let mut output = BufWriter::new(match output { +fn shuf_bytes(input: &mut Vec<&[u8]>, opts: Options) { + let mut output = BufWriter::new(match opts.output { None => Box::new(stdout()) as Box, Some(s) => match File::create(&s[..]) { Ok(f) => Box::new(f) as Box, @@ -209,7 +232,7 @@ fn shuf_bytes( }, }); - let mut rng = match random { + let mut rng = match opts.random_source { Some(r) => WrappedRng::RngFile(rand::read::ReadRng::new(match File::open(&r[..]) { Ok(f) => f, Err(e) => crash!(1, "failed to open random source '{}': {}", &r[..], e), @@ -225,7 +248,7 @@ fn shuf_bytes( len_mod <<= 1; } - let mut count = count; + let mut count = opts.head_count; while count > 0 && !input.is_empty() { let mut r = input.len(); while r >= input.len() { @@ -237,11 +260,11 @@ fn shuf_bytes( .write_all(input[r]) .unwrap_or_else(|e| crash!(1, "write failed: {}", e)); output - .write_all(&[sep]) + .write_all(&[opts.sep]) .unwrap_or_else(|e| crash!(1, "write failed: {}", e)); // if we do not allow repeats, remove the chosen value from the input vector - if !repeat { + if !opts.repeat { // shrink the mask if we will drop below a power of 2 if input.len() % 2 == 0 && len_mod > 2 { len_mod >>= 1; @@ -253,18 +276,18 @@ fn shuf_bytes( } } -fn parse_range(input_range: String) -> Result<(usize, usize), String> { +fn parse_range(input_range: &str) -> Result<(usize, usize), String> { let split: Vec<&str> = input_range.split('-').collect(); if split.len() != 2 { - Err("invalid range format".to_owned()) + Err(format!("invalid input range: '{}'", input_range)) } else { let begin = match split[0].parse::() { Ok(m) => m, - Err(e) => return Err(format!("{} is not a valid number: {}", split[0], e)), + Err(_) => return Err(format!("invalid input range: '{}'", split[0])), }; let end = match split[1].parse::() { Ok(m) => m, - Err(e) => return Err(format!("{} is not a valid number: {}", split[1], e)), + Err(_) => return Err(format!("invalid input range: '{}'", split[1])), }; Ok((begin, end + 1)) } diff --git a/tests/by-util/test_shuf.rs b/tests/by-util/test_shuf.rs index 651491045..3913621ef 100644 --- a/tests/by-util/test_shuf.rs +++ b/tests/by-util/test_shuf.rs @@ -1 +1,55 @@ -// ToDO: add tests +// ToDO: add more tests + +use crate::common::util::*; + +#[test] +fn test_shuf_echo_and_input_range_not_allowed() { + let result = new_ucmd!().args(&["-e", "0", "-i", "0-2"]).run(); + + assert!(!result.success); + assert!(result + .stderr + .contains("The argument '--input-range ' cannot be used with '--echo ...'")); +} + +#[test] +fn test_shuf_input_range_and_file_not_allowed() { + let result = new_ucmd!().args(&["-i", "0-9", "file"]).run(); + + assert!(!result.success); + assert!(result + .stderr + .contains("The argument '' cannot be used with '--input-range '")); +} + +#[test] +fn test_shuf_invalid_input_range_one() { + let result = new_ucmd!().args(&["-i", "0"]).run(); + + assert!(!result.success); + assert!(result.stderr.contains("invalid input range")); +} + +#[test] +fn test_shuf_invalid_input_range_two() { + let result = new_ucmd!().args(&["-i", "a-9"]).run(); + + assert!(!result.success); + assert!(result.stderr.contains("invalid input range: 'a'")); +} + +#[test] +fn test_shuf_invalid_input_range_three() { + let result = new_ucmd!().args(&["-i", "0-b"]).run(); + + assert!(!result.success); + assert!(result.stderr.contains("invalid input range: 'b'")); +} + +#[test] +fn test_shuf_invalid_input_line_count() { + let result = new_ucmd!().args(&["-n", "a"]).run(); + + assert!(!result.success); + assert!(result.stderr.contains("invalid line count: 'a'")); +} From 88d0bb01c01f238a611f24687d089f272ad44f12 Mon Sep 17 00:00:00 2001 From: jaggededgedjustice Date: Sun, 28 Mar 2021 16:52:01 +0100 Subject: [PATCH 031/132] Add shuf tests (#1958) * Add tests for shuf * Fixup GNU tests for shuf --- .github/workflows/GNU.yml | 4 +- tests/by-util/test_shuf.rs | 165 ++++++++++++++++++++++++++++- tests/fixtures/shuf/file_input.txt | 10 ++ 3 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/shuf/file_input.txt diff --git a/.github/workflows/GNU.yml b/.github/workflows/GNU.yml index 9eb5da2b9..35efccbe5 100644 --- a/.github/workflows/GNU.yml +++ b/.github/workflows/GNU.yml @@ -84,8 +84,8 @@ jobs: sed -i 's|stat|/usr/bin/stat|' tests/chgrp/basic.sh tests/cp/existing-perm-dir.sh tests/touch/60-seconds.sh tests/misc/sort-compress-proc.sh sed -i 's|ls -|/usr/bin/ls -|' tests/chgrp/posix-H.sh tests/chown/deref.sh tests/cp/same-file.sh tests/misc/mknod.sh tests/mv/part-symlink.sh tests/du/8gb.sh sed -i 's|mkdir |/usr/bin/mkdir |' tests/cp/existing-perm-dir.sh tests/rm/empty-inacc.sh - sed -i 's|timeout \([[:digit:]]\)| /usr/bin/timeout \1|' tests/tail-2/inotify-rotate.sh tests/tail-2/inotify-dir-recreate.sh tests/tail-2/inotify-rotate-resources.sh tests/cp/parent-perm-race.sh tests/ls/infloop.sh tests/misc/sort-exit-early.sh tests/misc/sort-NaN-infloop.sh tests/misc/uniq-perf.sh tests/tail-2/inotify-only-regular.sh tests/tail-2/pipe-f2.sh tests/tail-2/retry.sh tests/tail-2/symlink.sh tests/tail-2/wait.sh tests/tail-2/pid.sh tests/dd/stats.sh tests/tail-2/follow-name.sh # Don't break the function called 'grep_timeout' - sed -i 's|chmod |/usr/bin/chmod |' tests/du/inacc-dir.sh tests/mkdir/p-3.sh tests/tail-2/tail-n0f.sh tests/cp/fail-perm.sh tests/du/inaccessible-cwd.sh tests/mv/i-2.sh tests/chgrp/basic.sh + sed -i 's|timeout \([[:digit:]]\)| /usr/bin/timeout \1|' tests/tail-2/inotify-rotate.sh tests/tail-2/inotify-dir-recreate.sh tests/tail-2/inotify-rotate-resources.sh tests/cp/parent-perm-race.sh tests/ls/infloop.sh tests/misc/sort-exit-early.sh tests/misc/sort-NaN-infloop.sh tests/misc/uniq-perf.sh tests/tail-2/inotify-only-regular.sh tests/tail-2/pipe-f2.sh tests/tail-2/retry.sh tests/tail-2/symlink.sh tests/tail-2/wait.sh tests/tail-2/pid.sh tests/dd/stats.sh tests/tail-2/follow-name.sh tests/misc/shuf.sh # Don't break the function called 'grep_timeout' + sed -i 's|chmod |/usr/bin/chmod |' tests/du/inacc-dir.sh tests/mkdir/p-3.sh tests/tail-2/tail-n0f.sh tests/cp/fail-perm.sh tests/du/inaccessible-cwd.sh tests/mv/i-2.sh tests/chgrp/basic.sh tests/misc/shuf.sh sed -i 's|sort |/usr/bin/sort |' tests/ls/hyperlink.sh tests/misc/test-N.sh sed -i 's|split |/usr/bin/split |' tests/misc/factor-parallel.sh sed -i 's|truncate |/usr/bin/truncate |' tests/split/fail.sh diff --git a/tests/by-util/test_shuf.rs b/tests/by-util/test_shuf.rs index 3913621ef..065cef804 100644 --- a/tests/by-util/test_shuf.rs +++ b/tests/by-util/test_shuf.rs @@ -1,7 +1,168 @@ -// ToDO: add more tests - use crate::common::util::*; +#[test] +fn test_output_is_random_permutation() { + let input_seq = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let input = input_seq + .iter() + .map(|x| x.to_string()) + .collect::>() + .join("\n"); + + let result = new_ucmd!() + .pipe_in(input.as_bytes()) + .succeeds() + .no_stderr() + .stdout + .clone(); + + let mut result_seq: Vec = result + .split("\n") + .filter(|x| !x.is_empty()) + .map(|x| x.parse().unwrap()) + .collect(); + result_seq.sort(); + assert_ne!(result, input, "Output is not randomised"); + assert_eq!(result_seq, input_seq, "Output is not a permutation"); +} + +#[test] +fn test_zero_termination() { + let input_seq = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let result = new_ucmd!() + .arg("-z") + .arg("-i1-10") + .succeeds() + .no_stderr() + .stdout + .clone(); + + let mut result_seq: Vec = result + .split("\0") + .filter(|x| !x.is_empty()) + .map(|x| x.parse().unwrap()) + .collect(); + result_seq.sort(); + assert_eq!(result_seq, input_seq, "Output is not a permutation"); +} + +#[test] +fn test_echo() { + let input_seq = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let result = new_ucmd!() + .arg("-e") + .args( + &input_seq + .iter() + .map(|x| x.to_string()) + .collect::>(), + ) + .succeeds() + .no_stderr() + .stdout + .clone(); + + let mut result_seq: Vec = result + .split("\n") + .filter(|x| !x.is_empty()) + .map(|x| x.parse().unwrap()) + .collect(); + result_seq.sort(); + assert_eq!(result_seq, input_seq, "Output is not a permutation"); +} + +#[test] +fn test_head_count() { + let repeat_limit = 5; + let input_seq = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let input = input_seq + .iter() + .map(|x| x.to_string()) + .collect::>() + .join("\n"); + + let result = new_ucmd!() + .args(&["-n", &repeat_limit.to_string()]) + .pipe_in(input.as_bytes()) + .succeeds() + .no_stderr() + .stdout + .clone(); + + let mut result_seq: Vec = result + .split("\n") + .filter(|x| !x.is_empty()) + .map(|x| x.parse().unwrap()) + .collect(); + result_seq.sort(); + assert_eq!(result_seq.len(), repeat_limit, "Output is not limited"); + assert!( + result_seq.iter().all(|x| input_seq.contains(x)), + format!("Output includes element not from input: {}", result) + ) +} + +#[test] +fn test_repeat() { + let repeat_limit = 15000; + let input_seq = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let input = input_seq + .iter() + .map(|x| x.to_string()) + .collect::>() + .join("\n"); + + let result = new_ucmd!() + .arg("-r") + .args(&["-n", &repeat_limit.to_string()]) + .pipe_in(input.as_bytes()) + .succeeds() + .no_stderr() + .stdout + .clone(); + + let result_seq: Vec = result + .split("\n") + .filter(|x| !x.is_empty()) + .map(|x| x.parse().unwrap()) + .collect(); + assert_eq!( + result_seq.len(), + repeat_limit, + "Output is not repeating forever" + ); + assert!( + result_seq.iter().all(|x| input_seq.contains(x)), + format!( + "Output includes element not from input: {:?}", + result_seq + .iter() + .filter(|x| !input_seq.contains(x)) + .collect::>() + ) + ) +} + +#[test] +fn test_file_input() { + let expected_seq = vec![11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; + + let result = new_ucmd!() + .arg("file_input.txt") + .succeeds() + .no_stderr() + .stdout + .clone(); + + let mut result_seq: Vec = result + .split("\n") + .filter(|x| !x.is_empty()) + .map(|x| x.parse().unwrap()) + .collect(); + result_seq.sort(); + assert_eq!(result_seq, expected_seq, "Output is not a permutation"); +} + #[test] fn test_shuf_echo_and_input_range_not_allowed() { let result = new_ucmd!().args(&["-e", "0", "-i", "0-2"]).run(); diff --git a/tests/fixtures/shuf/file_input.txt b/tests/fixtures/shuf/file_input.txt new file mode 100644 index 000000000..fc316949e --- /dev/null +++ b/tests/fixtures/shuf/file_input.txt @@ -0,0 +1,10 @@ +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 From a9a3794d5a366f185d65e8c4908b4db180cdec20 Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Sun, 28 Mar 2021 20:56:37 +0200 Subject: [PATCH 032/132] chmod: add tests --- src/uu/chmod/src/chmod.rs | 2 +- tests/by-util/test_chmod.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index 119447b14..819c674a0 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -170,7 +170,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { // Iterate 'args' and delete the first occurrence // of a prefix '-' if it's associated with MODE // e.g. "chmod -v -xw -R FILE" -> "chmod -v xw -R FILE" -fn strip_minus_from_mode(args: &mut Vec) -> bool { +pub fn strip_minus_from_mode(args: &mut Vec) -> bool { for i in 0..args.len() { if args[i].starts_with("-") { if let Some(second) = args[i].chars().nth(1) { diff --git a/tests/by-util/test_chmod.rs b/tests/by-util/test_chmod.rs index e7bc72677..3a53202fc 100644 --- a/tests/by-util/test_chmod.rs +++ b/tests/by-util/test_chmod.rs @@ -4,6 +4,8 @@ use std::os::unix::fs::{OpenOptionsExt, PermissionsExt}; use std::sync::Mutex; extern crate libc; +use self::chmod::strip_minus_from_mode; +extern crate chmod; use self::libc::umask; static TEST_FILE: &'static str = "file"; @@ -374,3 +376,32 @@ fn test_chmod_symlink_non_existing_recursive() { .stderr .contains("neither symbolic link 'tmp/test-long.link' nor referent has been changed")); } + +#[test] +fn test_chmod_strip_minus_from_mode() { + let tests = vec![ + // ( before, after ) + ("chmod -v -xw -R FILE", "chmod -v xw -R FILE"), + ("chmod g=rwx FILE -c", "chmod g=rwx FILE -c"), + ( + "chmod -c -R -w,o+w FILE --preserve-root", + "chmod -c -R w,o+w FILE --preserve-root", + ), + ("chmod -c -R +w FILE ", "chmod -c -R +w FILE "), + ("chmod a=r,=xX FILE", "chmod a=r,=xX FILE"), + ( + "chmod -v --reference RFILE -R FILE", + "chmod -v --reference RFILE -R FILE", + ), + ("chmod -Rvc -w-x FILE", "chmod -Rvc w-x FILE"), + ("chmod 755 -v FILE", "chmod 755 -v FILE"), + ("chmod -v +0004 FILE -R", "chmod -v +0004 FILE -R"), + ("chmod -v -0007 FILE -R", "chmod -v 0007 FILE -R"), + ]; + + for test in tests { + let mut args: Vec = test.0.split(" ").map(|v| v.to_string()).collect(); + let _mode_had_minus_prefix = strip_minus_from_mode(&mut args); + assert_eq!(test.1, args.join(" ")); + } +} From 3714e2201b388b8d07e81ded15031433dab7a2db Mon Sep 17 00:00:00 2001 From: Dominik Bittner Date: Mon, 29 Mar 2021 13:00:47 +0200 Subject: [PATCH 033/132] tty: Move from getopts to clap (#1956) + tty: Add some tests --- src/uu/tty/Cargo.toml | 2 +- src/uu/tty/src/tty.rs | 90 ++++++++++++++++++--------------------- tests/by-util/test_tty.rs | 58 ++++++++++++++++++++++++- 3 files changed, 100 insertions(+), 50 deletions(-) diff --git a/src/uu/tty/Cargo.toml b/src/uu/tty/Cargo.toml index 9912a3b9a..7e4ffbd79 100644 --- a/src/uu/tty/Cargo.toml +++ b/src/uu/tty/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/tty.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" libc = "0.2.42" uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/tty/src/tty.rs b/src/uu/tty/src/tty.rs index 110f76d30..18d69db46 100644 --- a/src/uu/tty/src/tty.rs +++ b/src/uu/tty/src/tty.rs @@ -12,68 +12,62 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::ffi::CStr; use uucore::fs::is_stdin_interactive; -extern "C" { - fn ttyname(filedesc: libc::c_int) -> *const libc::c_char; +static VERSION: &str = env!("CARGO_PKG_VERSION"); +static ABOUT: &str = "Print the file name of the terminal connected to standard input."; + +mod options { + pub const SILENT: &str = "silent"; } -static NAME: &str = "tty"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); +fn get_usage() -> String { + format!("{0} [OPTION]...", executable!()) +} pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); + let usage = get_usage(); - let mut opts = getopts::Options::new(); + let matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .arg( + Arg::with_name(options::SILENT) + .long(options::SILENT) + .visible_alias("quiet") + .short("s") + .help("print nothing, only return an exit status") + .required(false), + ) + .get_matches_from(args); - opts.optflag("s", "silent", "print nothing, only return an exit status"); - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("V", "version", "output version information and exit"); + let silent = matches.is_present(options::SILENT); - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => crash!(2, "{}", f), + // Call libc function ttyname + let tty = unsafe { + let ptr = libc::ttyname(libc::STDIN_FILENO); + if !ptr.is_null() { + String::from_utf8_lossy(CStr::from_ptr(ptr).to_bytes()).to_string() + } else { + "".to_owned() + } }; - if matches.opt_present("help") { - println!("{} {}", NAME, VERSION); - println!(); - println!("Usage:"); - println!(" {} [OPTION]...", NAME); - println!(); - print!( - "{}", - opts.usage("Print the file name of the terminal connected to standard input.") - ); - } else if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - } else { - let silent = matches.opt_present("s"); - - let tty = unsafe { - let ptr = ttyname(libc::STDIN_FILENO); - if !ptr.is_null() { - String::from_utf8_lossy(CStr::from_ptr(ptr).to_bytes()).to_string() - } else { - "".to_owned() - } - }; - - if !silent { - if !tty.chars().all(|c| c.is_whitespace()) { - println!("{}", tty); - } else { - println!("not a tty"); - } - } - - return if is_stdin_interactive() { - libc::EXIT_SUCCESS + if !silent { + if !tty.chars().all(|c| c.is_whitespace()) { + println!("{}", tty); } else { - libc::EXIT_FAILURE - }; + println!("not a tty"); + } } - 0 + return if is_stdin_interactive() { + libc::EXIT_SUCCESS + } else { + libc::EXIT_FAILURE + }; } diff --git a/tests/by-util/test_tty.rs b/tests/by-util/test_tty.rs index 651491045..6bca54e03 100644 --- a/tests/by-util/test_tty.rs +++ b/tests/by-util/test_tty.rs @@ -1 +1,57 @@ -// ToDO: add tests +use crate::common::util::*; + +#[test] +#[cfg(not(windows))] +fn test_dev_null() { + new_ucmd!() + .pipe_in(" Date: Mon, 29 Mar 2021 21:33:24 +1030 Subject: [PATCH 034/132] tr: move from getopts to claps #1929 (#1954) --- Cargo.lock | 6 +-- src/uu/tr/Cargo.toml | 2 +- src/uu/tr/src/tr.rs | 101 +++++++++++++++++++++++++------------------ 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 343ad1e30..8d42c573e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1325,9 +1325,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.65" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" +checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" dependencies = [ "proc-macro2", "quote 1.0.9", @@ -2334,8 +2334,8 @@ name = "uu_tr" version = "0.0.4" dependencies = [ "bit-set", + "clap", "fnv", - "getopts", "uucore", "uucore_procs", ] diff --git a/src/uu/tr/Cargo.toml b/src/uu/tr/Cargo.toml index 918698e24..3683211f6 100644 --- a/src/uu/tr/Cargo.toml +++ b/src/uu/tr/Cargo.toml @@ -17,7 +17,7 @@ path = "src/tr.rs" [dependencies] bit-set = "0.5.0" fnv = "1.0.5" -getopts = "0.2.18" +clap = "2.33" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index d60d2559a..ff1bb49d5 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -16,16 +16,27 @@ extern crate uucore; mod expand; use bit_set::BitSet; +use clap::{App, Arg}; use fnv::FnvHashMap; -use getopts::Options; use std::io::{stdin, stdout, BufRead, BufWriter, Write}; use crate::expand::ExpandSet; static NAME: &str = "tr"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static ABOUT: &str = "translate or delete characters"; +static LONG_HELP: &str = "Translate, squeeze, and/or delete characters from standard input, +writing to standard output."; const BUFFER_LEN: usize = 1024; +mod options { + pub const COMPLEMENT: &str = "complement"; + pub const DELETE: &str = "delete"; + pub const SQUEEZE: &str = "squeeze-repeats"; + pub const TRUNCATE: &str = "truncate"; + pub const SETS: &str = "sets"; +} + trait SymbolTranslator { fn translate(&self, c: char, prev_c: char) -> Option; } @@ -170,56 +181,60 @@ fn translate_input( } } -fn usage(opts: &Options) { - println!("{} {}", NAME, VERSION); - println!(); - println!("Usage:"); - println!(" {} [OPTIONS] SET1 [SET2]", NAME); - println!(); - println!("{}", opts.usage("Translate or delete characters.")); +fn get_usage() -> String { + format!("{} [OPTION]... SET1 [SET2]", executable!()) } pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); + let usage = get_usage(); - let mut opts = Options::new(); + let matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .after_help(LONG_HELP) + .arg( + Arg::with_name(options::COMPLEMENT) + .short("C") + .short("c") + .long(options::COMPLEMENT) + .help("use the complement of SET1"), + ) + .arg( + Arg::with_name(options::DELETE) + .short("d") + .long(options::DELETE) + .help("delete characters in SET1, do not translate"), + ) + .arg( + Arg::with_name(options::SQUEEZE) + .long(options::SQUEEZE) + .short("s") + .help( + "replace each sequence of a repeated character that is + listed in the last specified SET, with a single occurrence + of that character", + ), + ) + .arg( + Arg::with_name(options::TRUNCATE) + .long(options::TRUNCATE) + .short("t") + .help("first truncate SET1 to length of SET2"), + ) + .arg(Arg::with_name(options::SETS).multiple(true)) + .get_matches_from(args); - opts.optflag("c", "complement", "use the complement of SET1"); - opts.optflag("C", "", "same as -c"); - opts.optflag("d", "delete", "delete characters in SET1"); - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("s", "squeeze", "replace each sequence of a repeated character that is listed in the last specified SET, with a single occurrence of that character"); - opts.optflag( - "t", - "truncate-set1", - "first truncate SET1 to length of SET2", - ); - opts.optflag("V", "version", "output version information and exit"); + let dflag = matches.is_present(options::DELETE); + let cflag = matches.is_present(options::COMPLEMENT); + let sflag = matches.is_present(options::SQUEEZE); + let tflag = matches.is_present(options::TRUNCATE); - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(err) => { - show_error!("{}", err); - return 1; - } + let sets: Vec = match matches.values_of(options::SETS) { + Some(v) => v.map(|v| v.to_string()).collect(), + None => vec![], }; - if matches.opt_present("help") { - usage(&opts); - return 0; - } - - if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - return 0; - } - - let dflag = matches.opt_present("d"); - let cflag = matches.opts_present(&["c".to_owned(), "C".to_owned()]); - let sflag = matches.opt_present("s"); - let tflag = matches.opt_present("t"); - let sets = matches.free; - if sets.is_empty() { show_error!( "missing operand\nTry `{} --help` for more information.", From 8cc7a90d7ceb580b695ac5c2de264467456bbd69 Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Mon, 29 Mar 2021 14:03:56 +0300 Subject: [PATCH 035/132] sum: fix crash on invalid inputs, move to clap, add tests (#1952) --- Cargo.lock | 6 +-- src/uu/sum/Cargo.toml | 2 +- src/uu/sum/src/sum.rs | 93 ++++++++++++++++++++++----------------- tests/by-util/test_sum.rs | 20 +++++++++ 4 files changed, 77 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d42c573e..c950fb58e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2250,9 +2250,9 @@ dependencies = [ name = "uu_sum" version = "0.0.4" dependencies = [ - "getopts", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] diff --git a/src/uu/sum/Cargo.toml b/src/uu/sum/Cargo.toml index a880ba1f7..1e8590616 100644 --- a/src/uu/sum/Cargo.toml +++ b/src/uu/sum/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/sum.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/sum/src/sum.rs b/src/uu/sum/src/sum.rs index 5c1652196..ed5655a3d 100644 --- a/src/uu/sum/src/sum.rs +++ b/src/uu/sum/src/sum.rs @@ -10,12 +10,16 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::fs::File; use std::io::{stdin, Read, Result}; use std::path::Path; static NAME: &str = "sum"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static USAGE: &str = + "[OPTION]... [FILE]...\nWith no FILE, or when FILE is -, read standard input."; +static SUMMARY: &str = "Checksum and count the blocks in a file."; fn bsd_sum(mut reader: Box) -> (usize, u16) { let mut buf = [0; 1024]; @@ -64,55 +68,59 @@ fn open(name: &str) -> Result> { match name { "-" => Ok(Box::new(stdin()) as Box), _ => { - let f = File::open(&Path::new(name))?; + let path = &Path::new(name); + if path.is_dir() { + return Err(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + "Is a directory", + )); + }; + if !path.metadata().is_ok() { + return Err(std::io::Error::new( + std::io::ErrorKind::NotFound, + "No such file or directory", + )); + }; + let f = File::open(path)?; Ok(Box::new(f) as Box) } } } +mod options { + pub static FILE: &str = "file"; + pub static BSD_COMPATIBLE: &str = "r"; + pub static SYSTEM_V_COMPATIBLE: &str = "sysv"; +} + pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); - let mut opts = getopts::Options::new(); + let matches = App::new(executable!()) + .name(NAME) + .version(VERSION) + .usage(USAGE) + .about(SUMMARY) + .arg(Arg::with_name(options::FILE).multiple(true).hidden(true)) + .arg( + Arg::with_name(options::BSD_COMPATIBLE) + .short(options::BSD_COMPATIBLE) + .help("use the BSD compatible algorithm (default)"), + ) + .arg( + Arg::with_name(options::SYSTEM_V_COMPATIBLE) + .short("s") + .long(options::SYSTEM_V_COMPATIBLE) + .help("use the BSD compatible algorithm (default)"), + ) + .get_matches_from(args); - opts.optflag("r", "", "use the BSD compatible algorithm (default)"); - opts.optflag("s", "sysv", "use System V compatible algorithm"); - opts.optflag("h", "help", "show this help message"); - opts.optflag("v", "version", "print the version and exit"); - - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => crash!(1, "Invalid options\n{}", f), + let files: Vec = match matches.values_of(options::FILE) { + Some(v) => v.clone().map(|v| v.to_owned()).collect(), + None => vec!["-".to_owned()], }; - if matches.opt_present("help") { - let msg = format!( - "{0} {1} - -Usage: - {0} [OPTION]... [FILE]... - -Checksum and count the blocks in a file.", - NAME, VERSION - ); - println!( - "{}\nWith no FILE, or when FILE is -, read standard input.", - opts.usage(&msg) - ); - return 0; - } - if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - return 0; - } - - let sysv = matches.opt_present("sysv"); - - let files = if matches.free.is_empty() { - vec!["-".to_owned()] - } else { - matches.free - }; + let sysv = matches.is_present(options::SYSTEM_V_COMPATIBLE); let print_names = if sysv { files.len() > 1 || files[0] != "-" @@ -120,10 +128,15 @@ Checksum and count the blocks in a file.", files.len() > 1 }; + let mut exit_code = 0; for file in &files { let reader = match open(file) { Ok(f) => f, - _ => crash!(1, "unable to open file"), + Err(error) => { + show_error!("'{}' {}", file, error); + exit_code = 2; + continue; + } }; let (blocks, sum) = if sysv { sysv_sum(reader) @@ -138,5 +151,5 @@ Checksum and count the blocks in a file.", } } - 0 + exit_code } diff --git a/tests/by-util/test_sum.rs b/tests/by-util/test_sum.rs index 83cf689ac..d12455749 100644 --- a/tests/by-util/test_sum.rs +++ b/tests/by-util/test_sum.rs @@ -52,3 +52,23 @@ fn test_sysv_stdin() { .succeeds() .stdout_only_fixture("sysv_stdin.expected"); } + +#[test] +fn test_invalid_file() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.mkdir("a"); + + ucmd.arg("a") + .fails() + .stderr_is("sum: error: 'a' Is a directory"); +} + +#[test] +fn test_invalid_metadata() { + let (_, mut ucmd) = at_and_ucmd!(); + + ucmd.arg("b") + .fails() + .stderr_is("sum: error: 'b' No such file or directory"); +} From da5f2f3a6c774fd495ec003065321a4c31843db2 Mon Sep 17 00:00:00 2001 From: electricboogie <32370782+electricboogie@users.noreply.github.com> Date: Mon, 29 Mar 2021 06:05:52 -0500 Subject: [PATCH 036/132] sort: Add a GNU-style Random Sorter (#1922) --- Cargo.lock | 19 ++++ src/uu/sort/Cargo.toml | 2 + src/uu/sort/src/sort.rs | 222 +++++++++++++++++++++++++++++++------ tests/by-util/test_sort.rs | 62 +++++++++-- 4 files changed, 261 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c950fb58e..07a99069c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,6 +1317,12 @@ dependencies = [ "maybe-uninit", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.8.0" @@ -1443,6 +1449,17 @@ dependencies = [ "serde_json", ] +[[package]] +name = "twox-hash" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" +dependencies = [ + "cfg-if 0.1.10", + "rand 0.7.3", + "static_assertions", +] + [[package]] name = "typenum" version = "1.13.0" @@ -2200,7 +2217,9 @@ version = "0.0.4" dependencies = [ "clap", "itertools 0.8.2", + "rand 0.7.3", "semver", + "twox-hash", "uucore", "uucore_procs", ] diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index 5158f6e52..e50caf53b 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -15,7 +15,9 @@ edition = "2018" path = "src/sort.rs" [dependencies] +rand = "0.7" clap = "2.33" +twox-hash = "1.6.0" itertools = "0.8.0" semver = "0.9.0" uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 8e79ff947..f8789835a 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -1,6 +1,7 @@ // * This file is part of the uutils coreutils package. // * // * (c) Michael Yin +// * (c) Robert Swinford // * // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. @@ -12,13 +13,17 @@ extern crate uucore; use clap::{App, Arg}; use itertools::Itertools; +use rand::distributions::Alphanumeric; +use rand::{thread_rng, Rng}; use semver::Version; use std::cmp::Ordering; use std::collections::BinaryHeap; use std::fs::File; +use std::hash::{Hash, Hasher}; use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Lines, Read, Write}; use std::mem::replace; use std::path::Path; +use twox_hash::XxHash64; use uucore::fs::is_stdin_interactive; // for Iterator::dedup() static NAME: &str = "sort"; @@ -34,16 +39,18 @@ static OPT_DICTIONARY_ORDER: &str = "dictionary-order"; static OPT_MERGE: &str = "merge"; static OPT_CHECK: &str = "check"; static OPT_IGNORE_CASE: &str = "ignore-case"; +static OPT_IGNORE_BLANKS: &str = "ignore-blanks"; static OPT_OUTPUT: &str = "output"; static OPT_REVERSE: &str = "reverse"; static OPT_STABLE: &str = "stable"; static OPT_UNIQUE: &str = "unique"; +static OPT_RANDOM: &str = "random-sort"; static ARG_FILES: &str = "files"; static DECIMAL_PT: char = '.'; static THOUSANDS_SEP: char = ','; - +#[derive(Eq, Ord, PartialEq, PartialOrd)] enum SortMode { Numeric, HumanNumeric, @@ -60,8 +67,10 @@ struct Settings { stable: bool, unique: bool, check: bool, + random: bool, compare_fns: Vec Ordering>, transform_fns: Vec String>, + salt: String, } impl Default for Settings { @@ -74,8 +83,10 @@ impl Default for Settings { stable: false, unique: false, check: false, + random: false, compare_fns: Vec::new(), transform_fns: Vec::new(), + salt: String::new(), } } } @@ -155,17 +166,14 @@ impl<'a> Iterator for FileMerger<'a> { } } } + fn get_usage() -> String { format!( "{0} {1} - Usage: {0} [OPTION]... [FILE]... - Write the sorted concatenation of all FILE(s) to standard output. - Mandatory arguments for long options are mandatory for short options too. - With no FILE, or when FILE is -, read standard input.", NAME, VERSION ) @@ -228,6 +236,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_IGNORE_CASE) .help("fold lower case to upper case characters"), ) + .arg( + Arg::with_name(OPT_IGNORE_BLANKS) + .short("b") + .long(OPT_IGNORE_BLANKS) + .help("ignore leading blanks when finding sort keys in each line"), + ) .arg( Arg::with_name(OPT_OUTPUT) .short("o") @@ -236,6 +250,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .takes_value(true) .value_name("FILENAME"), ) + .arg( + Arg::with_name(OPT_RANDOM) + .short("R") + .long(OPT_RANDOM) + .help("shuffle in random order"), + ) .arg( Arg::with_name(OPT_REVERSE) .short("r") @@ -285,11 +305,20 @@ pub fn uumain(args: impl uucore::Args) -> i32 { settings.transform_fns.push(|s| s.to_uppercase()); } + if matches.is_present(OPT_IGNORE_BLANKS) { + settings.transform_fns.push(|s| s.trim_start().to_string()); + } + settings.outfile = matches.value_of(OPT_OUTPUT).map(String::from); settings.reverse = matches.is_present(OPT_REVERSE); settings.stable = matches.is_present(OPT_STABLE); settings.unique = matches.is_present(OPT_UNIQUE); + if matches.is_present(OPT_RANDOM) { + settings.random = matches.is_present(OPT_RANDOM); + settings.salt = get_rand_string(); + } + //let mut files = matches.free; if files.is_empty() { /* if no file, default to stdin */ @@ -313,10 +342,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } } - exec(files, &settings) + exec(files, &mut settings) } -fn exec(files: Vec, settings: &Settings) -> i32 { +fn exec(files: Vec, settings: &mut Settings) -> i32 { let mut lines = Vec::new(); let mut file_merger = FileMerger::new(&settings); @@ -351,6 +380,13 @@ fn exec(files: Vec, settings: &Settings) -> i32 { } else { print_sorted(file_merger, &settings.outfile) } + } else if settings.unique && settings.mode == SortMode::Numeric { + print_sorted( + lines + .iter() + .dedup_by(|a, b| num_sort_dedup(a) == num_sort_dedup(b)), + &settings.outfile, + ) } else if settings.unique { print_sorted(lines.iter().dedup(), &settings.outfile) } else { @@ -419,7 +455,11 @@ fn compare_by(a: &str, b: &str, settings: &Settings) -> Ordering { }; for compare_fn in &settings.compare_fns { - let cmp = compare_fn(a, b); + let cmp: Ordering = if settings.random { + random_shuffle(a, b, settings.salt.clone()) + } else { + compare_fn(a, b) + }; if cmp != Ordering::Equal { if settings.reverse { return cmp.reverse(); @@ -431,36 +471,60 @@ fn compare_by(a: &str, b: &str, settings: &Settings) -> Ordering { Ordering::Equal } -/// Parse the beginning string into an f64, returning -inf instead of NaN on errors. -fn permissive_f64_parse(a: &str) -> f64 { - // Maybe should be split on non-digit, but then 10e100 won't parse properly. - // On the flip side, this will give NEG_INFINITY for "1,234", which might be OK - // because there's no way to handle both CSV and thousands separators without a new flag. - // GNU sort treats "1,234" as "1" in numeric, so maybe it's fine. - // GNU sort treats "NaN" as non-number in numeric, so it needs special care. - match a.split_whitespace().next() { - None => std::f64::NEG_INFINITY, - Some(sa) => match sa.parse::() { - Ok(a) if a.is_nan() => std::f64::NEG_INFINITY, - Ok(a) => a, - Err(_) => std::f64::NEG_INFINITY, - }, - } -} - fn default_compare(a: &str, b: &str) -> Ordering { a.cmp(b) } -/// Compares two floating point numbers, with errors being assumed to be -inf. -/// Stops coercing at the first whitespace char, so 1e2 will parse as 100 but -/// 1,000 will parse as -inf. +fn get_leading_number(a: &str) -> &str { + let mut s = ""; + for c in a.chars() { + if !c.is_numeric() && !c.eq(&'-') && !c.eq(&' ') && !c.eq(&'.') && !c.eq(&',') { + s = a.trim().split(c).next().unwrap(); + break; + } + s = a.trim(); + } + return s; +} + +// Matches GNU behavior, see: +// https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html +// Specifically *not* the same as sort -n | uniq +fn num_sort_dedup(a: &str) -> &str { + // Empty lines are dumped + if a.is_empty() { + return "0" + // And lines that don't begin numerically are dumped + } else if !a.trim().chars().nth(0).unwrap_or('\0').is_numeric() { + return "0" + } else { + // Prepare lines for comparison of only the numerical leading numbers + return get_leading_number(a) + }; +} + +/// Parse the beginning string into an f64, returning -inf instead of NaN on errors. +fn permissive_f64_parse(a: &str) -> f64 { + // GNU sort treats "NaN" as non-number in numeric, so it needs special care. + match a.parse::() { + Ok(a) if a.is_nan() => std::f64::NEG_INFINITY, + Ok(a) => a, + Err(_) => std::f64::NEG_INFINITY, + } +} + +/// Compares two floats, with errors and non-numerics assumed to be -inf. +/// Stops coercing at the first non-numeric char. fn numeric_compare(a: &str, b: &str) -> Ordering { #![allow(clippy::comparison_chain)] - let fa = permissive_f64_parse(a); - let fb = permissive_f64_parse(b); - // f64::cmp isn't implemented because NaN messes with it - // but we sidestep that with permissive_f64_parse so just fake it + + let sa = get_leading_number(a); + let sb = get_leading_number(b); + + let fa = permissive_f64_parse(sa); + let fb = permissive_f64_parse(sb); + + // f64::cmp isn't implemented (due to NaN issues); implement directly instead if fa > fb { Ordering::Greater } else if fa < fb { @@ -471,10 +535,10 @@ fn numeric_compare(a: &str, b: &str) -> Ordering { } fn human_numeric_convert(a: &str) -> f64 { - let int_str: String = a.chars().take_while(|c| c.is_numeric()).collect(); - let suffix = a.chars().find(|c| !c.is_numeric()); - let int_part = int_str.parse::().unwrap_or(-1f64) as f64; - let suffix: f64 = match suffix.unwrap_or('\0') { + let int_str = get_leading_number(a); + let (_, s) = a.split_at(int_str.len()); + let int_part = permissive_f64_parse(int_str); + let suffix: f64 = match s.parse().unwrap_or('\0') { 'K' => 1000f64, 'M' => 1E6, 'G' => 1E9, @@ -501,6 +565,30 @@ fn human_numeric_size_compare(a: &str, b: &str) -> Ordering { } } +fn random_shuffle(a: &str, b: &str, salt: String) -> Ordering { + #![allow(clippy::comparison_chain)] + let salt_slice = salt.as_str(); + + let da = hash(&[a, salt_slice].concat()); + let db = hash(&[b, salt_slice].concat()); + + da.cmp(&db) +} + +fn get_rand_string() -> String { + thread_rng() + .sample_iter(&Alphanumeric) + .take(16) + .map(char::from) + .collect::() +} + +fn hash(t: &T) -> u64 { + let mut s: XxHash64 = Default::default(); + t.hash(&mut s); + s.finish() +} + #[derive(Eq, Ord, PartialEq, PartialOrd)] enum Month { Unknown, @@ -606,3 +694,65 @@ fn open(path: &str) -> Option<(Box, bool)> { } } } + +#[cfg(test)] +mod tests { + + use super::*; + + #[test] + fn test_default_compare() { + let a = "your own"; + let b = "your place"; + + assert_eq!(Ordering::Less, default_compare(a, b)); + } + + #[test] + fn test_numeric_compare1() { + let a = "149:7"; + let b = "150:5"; + + assert_eq!(Ordering::Less, numeric_compare(a, b)); + } + + #[test] + fn test_numeric_compare2() { + let a = "-1.02"; + let b = "1"; + + assert_eq!(Ordering::Less, numeric_compare(a, b)); + } + + #[test] + fn test_human_numeric_compare() { + let a = "300K"; + let b = "1M"; + + assert_eq!(Ordering::Less, human_numeric_size_compare(a, b)); + } + + #[test] + fn test_month_compare() { + let a = "JaN"; + let b = "OCt"; + + assert_eq!(Ordering::Less, month_compare(a, b)); + } + #[test] + fn test_version_compare() { + let a = "1.2.3-alpha2"; + let b = "1.4.0"; + + assert_eq!(Ordering::Less, version_compare(a, b)); + } + + #[test] + fn test_random_compare() { + let a = "9"; + let b = "9"; + let c = get_rand_string(); + + assert_eq!(Ordering::Equal, random_shuffle(a, b, c)); + } +} diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index 9ff1b3522..2bac71def 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -2,22 +2,43 @@ use crate::common::util::*; #[test] fn test_numeric_floats_and_ints() { - test_helper("numeric_floats_and_ints", "-n"); + for numeric_sort_param in vec!["-n", "--numeric-sort"] { + let input = "1.444\n8.013\n1\n-8\n1.04\n-1"; + new_ucmd!() + .arg(numeric_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("-8\n-1\n1\n1.04\n1.444\n8.013\n"); + } } #[test] fn test_numeric_floats() { - test_helper("numeric_floats", "-n"); + for numeric_sort_param in vec!["-n", "--numeric-sort"] { + let input = "1.444\n8.013\n1.58590\n-8.90880\n1.040000000\n-.05"; + new_ucmd!() + .arg(numeric_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("-8.90880\n-.05\n1.040000000\n1.444\n1.58590\n8.013\n"); + } } #[test] fn test_numeric_floats_with_nan() { - test_helper("numeric_floats_with_nan", "-n"); + for numeric_sort_param in vec!["-n", "--numeric-sort"] { + let input = "1.444\n1.0/0.0\n1.58590\n-8.90880\n1.040000000\n-.05"; + new_ucmd!() + .arg(numeric_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("-8.90880\n-.05\n1.0/0.0\n1.040000000\n1.444\n1.58590\n"); + } } #[test] fn test_numeric_unfixed_floats() { - test_helper("numeric_unfixed_floats", "-n"); + test_helper("numeric_fixed_floats", "-n"); } #[test] @@ -32,12 +53,26 @@ fn test_numeric_unsorted_ints() { #[test] fn test_human_block_sizes() { - test_helper("human_block_sizes", "-h"); + for human_numeric_sort_param in vec!["-h", "--human-numeric-sort"] { + let input = "8981K\n909991M\n-8T\n21G\n0.8M"; + new_ucmd!() + .arg(human_numeric_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("-8T\n0.8M\n8981K\n21G\n909991M\n"); + } } #[test] fn test_month_default() { - test_helper("month_default", "-M"); + for month_sort_param in vec!["-M", "--month-sort"] { + let input = "JAn\nMAY\n000may\nJun\nFeb"; + new_ucmd!() + .arg(month_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("000may\nJAn\nFeb\nMAY\nJun\n"); + } } #[test] @@ -47,12 +82,23 @@ fn test_month_stable() { #[test] fn test_default_unsorted_ints() { - test_helper("default_unsorted_ints", ""); + let input = "9\n1909888\n000\n1\n2"; + new_ucmd!() + .pipe_in(input) + .succeeds() + .stdout_only("000\n1\n1909888\n2\n9\n"); } #[test] fn test_numeric_unique_ints() { - test_helper("numeric_unsorted_ints_unique", "-nu"); + for numeric_unique_sort_param in vec!["-nu"] { + let input = "9\n9\n8\n1\n"; + new_ucmd!() + .arg(numeric_unique_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("1\n8\n9\n"); + } } #[test] From 8320b1ec5f58a94372edce2477480fb0116df262 Mon Sep 17 00:00:00 2001 From: Mikadore Date: Mon, 29 Mar 2021 13:08:48 +0200 Subject: [PATCH 037/132] Rewrote head (#1911) See https://github.com/uutils/coreutils/pull/1911 for the details --- src/uu/head/Cargo.toml | 2 +- src/uu/head/src/head.rs | 828 +++++++++++++----- src/uu/head/src/parse.rs | 282 ++++++ src/uu/head/src/split.rs | 60 ++ tests/by-util/test_head.rs | 105 ++- .../head/lorem_ipsum_backwards_file.expected | 24 + tests/fixtures/head/sequence | 100 +++ tests/fixtures/head/sequence.expected | 90 ++ 8 files changed, 1235 insertions(+), 256 deletions(-) create mode 100644 src/uu/head/src/parse.rs create mode 100644 src/uu/head/src/split.rs mode change 100644 => 100755 tests/by-util/test_head.rs create mode 100644 tests/fixtures/head/lorem_ipsum_backwards_file.expected create mode 100644 tests/fixtures/head/sequence create mode 100644 tests/fixtures/head/sequence.expected diff --git a/src/uu/head/Cargo.toml b/src/uu/head/Cargo.toml index adcce2726..1cd075113 100644 --- a/src/uu/head/Cargo.toml +++ b/src/uu/head/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/head.rs" [dependencies] -libc = "0.2.42" +clap = "2.33" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/head/src/head.rs b/src/uu/head/src/head.rs index 0036dbba9..a8f519f6b 100644 --- a/src/uu/head/src/head.rs +++ b/src/uu/head/src/head.rs @@ -1,240 +1,642 @@ -// * This file is part of the uutils coreutils package. -// * -// * (c) Alan Andrade -// * -// * For the full copyright and license information, please view the LICENSE -// * file that was distributed with this source code. -// * -// * Synced with: https://raw.github.com/avsm/src/master/usr.bin/head/head.c +use clap::{App, Arg}; +use std::convert::TryFrom; +use std::ffi::OsString; +use std::io::{ErrorKind, Read, Seek, SeekFrom, Write}; +use uucore::{crash, executable, show_error}; -#[macro_use] -extern crate uucore; +const EXIT_FAILURE: i32 = 1; +const EXIT_SUCCESS: i32 = 0; +const BUF_SIZE: usize = 65536; -use std::collections::VecDeque; -use std::fs::File; -use std::io::{stdin, BufRead, BufReader, Read}; -use std::path::Path; -use std::str::from_utf8; +const VERSION: &str = env!("CARGO_PKG_VERSION"); +const ABOUT: &str = "\ + Print the first 10 lines of each FILE to standard output.\n\ + With more than one FILE, precede each with a header giving the file name.\n\ + \n\ + With no FILE, or when FILE is -, read standard input.\n\ + \n\ + Mandatory arguments to long flags are mandatory for short flags too.\ + "; +const USAGE: &str = "head [FLAG]... [FILE]..."; -static SYNTAX: &str = ""; -static SUMMARY: &str = ""; -static LONG_HELP: &str = ""; +mod options { + pub const BYTES_NAME: &str = "BYTES"; + pub const LINES_NAME: &str = "LINES"; + pub const QUIET_NAME: &str = "QUIET"; + pub const VERBOSE_NAME: &str = "VERBOSE"; + pub const ZERO_NAME: &str = "ZERO"; + pub const FILES_NAME: &str = "FILE"; +} +mod parse; +mod split; -enum FilterMode { - Bytes(usize), +fn app<'a>() -> App<'a, 'a> { + App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(USAGE) + .arg( + Arg::with_name(options::BYTES_NAME) + .short("c") + .long("bytes") + .value_name("[-]NUM") + .takes_value(true) + .help( + "\ + print the first NUM bytes of each file;\n\ + with the leading '-', print all but the last\n\ + NUM bytes of each file\ + ", + ) + .overrides_with_all(&[options::BYTES_NAME, options::LINES_NAME]) + .allow_hyphen_values(true), + ) + .arg( + Arg::with_name(options::LINES_NAME) + .short("n") + .long("lines") + .value_name("[-]NUM") + .takes_value(true) + .help( + "\ + print the first NUM lines instead of the first 10;\n\ + with the leading '-', print all but the last\n\ + NUM lines of each file\ + ", + ) + .overrides_with_all(&[options::LINES_NAME, options::BYTES_NAME]) + .allow_hyphen_values(true), + ) + .arg( + Arg::with_name(options::QUIET_NAME) + .short("q") + .long("--quiet") + .visible_alias("silent") + .help("never print headers giving file names") + .overrides_with_all(&[options::VERBOSE_NAME, options::QUIET_NAME]), + ) + .arg( + Arg::with_name(options::VERBOSE_NAME) + .short("v") + .long("verbose") + .help("always print headers giving file names") + .overrides_with_all(&[options::QUIET_NAME, options::VERBOSE_NAME]), + ) + .arg( + Arg::with_name(options::ZERO_NAME) + .short("z") + .long("zero-terminated") + .help("line delimiter is NUL, not newline") + .overrides_with(options::ZERO_NAME), + ) + .arg(Arg::with_name(options::FILES_NAME).multiple(true)) +} +#[derive(PartialEq, Debug, Clone, Copy)] +enum Modes { Lines(usize), - NLines(usize), + Bytes(usize), } -struct Settings { - mode: FilterMode, - verbose: bool, - zero_terminated: bool, +fn parse_mode(src: &str, closure: F) -> Result<(Modes, bool), String> +where + F: FnOnce(usize) -> Modes, +{ + match parse::parse_num(src) { + Ok((n, last)) => Ok((closure(n), last)), + Err(reason) => match reason { + parse::ParseError::Syntax => Err(format!("'{}'", src)), + parse::ParseError::Overflow => { + Err(format!("'{}': Value too large for defined datatype", src)) + } + }, + } } -impl Default for Settings { - fn default() -> Settings { - Settings { - mode: FilterMode::Lines(10), - verbose: false, - zero_terminated: false, +fn arg_iterate<'a>( + mut args: impl uucore::Args + 'a, +) -> Result + 'a>, String> { + // argv[0] is always present + let first = args.next().unwrap(); + if let Some(second) = args.next() { + if let Some(s) = second.to_str() { + match parse::parse_obsolete(s) { + Some(Ok(iter)) => Ok(Box::new(vec![first].into_iter().chain(iter).chain(args))), + Some(Err(e)) => match e { + parse::ParseError::Syntax => Err(format!("bad argument format: '{}'", s)), + parse::ParseError::Overflow => Err(format!( + "invalid argument: '{}' Value too large for defined datatype", + s + )), + }, + None => Ok(Box::new(vec![first, second].into_iter().chain(args))), + } + } else { + Err("bad argument encoding".to_owned()) } + } else { + Ok(Box::new(vec![first].into_iter())) + } +} + +#[derive(Debug, PartialEq)] +struct HeadOptions { + pub quiet: bool, + pub verbose: bool, + pub zeroed: bool, + pub all_but_last: bool, + pub mode: Modes, + pub files: Vec, +} + +impl HeadOptions { + pub fn new() -> HeadOptions { + HeadOptions { + quiet: false, + verbose: false, + zeroed: false, + all_but_last: false, + mode: Modes::Lines(10), + files: Vec::new(), + } + } + + ///Construct options from matches + pub fn get_from(args: impl uucore::Args) -> Result { + let matches = app().get_matches_from(arg_iterate(args)?); + + let mut options = HeadOptions::new(); + + options.quiet = matches.is_present(options::QUIET_NAME); + options.verbose = matches.is_present(options::VERBOSE_NAME); + options.zeroed = matches.is_present(options::ZERO_NAME); + + let mode_and_from_end = if let Some(v) = matches.value_of(options::BYTES_NAME) { + match parse_mode(v, Modes::Bytes) { + Ok(v) => v, + Err(err) => { + return Err(format!("invalid number of bytes: {}", err)); + } + } + } else if let Some(v) = matches.value_of(options::LINES_NAME) { + match parse_mode(v, Modes::Lines) { + Ok(v) => v, + Err(err) => { + return Err(format!("invalid number of lines: {}", err)); + } + } + } else { + (Modes::Lines(10), false) + }; + + options.mode = mode_and_from_end.0; + options.all_but_last = mode_and_from_end.1; + + options.files = match matches.values_of(options::FILES_NAME) { + Some(v) => v.map(|s| s.to_owned()).collect(), + None => vec!["-".to_owned()], + }; + //println!("{:#?}", options); + Ok(options) + } +} +// to make clippy shut up +impl Default for HeadOptions { + fn default() -> Self { + Self::new() + } +} + +fn rbuf_n_bytes(input: &mut impl std::io::BufRead, n: usize) -> std::io::Result<()> { + if n == 0 { + return Ok(()); + } + let mut readbuf = [0u8; BUF_SIZE]; + let mut i = 0usize; + + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + + loop { + let read = loop { + match input.read(&mut readbuf) { + Ok(n) => break n, + Err(e) => match e.kind() { + ErrorKind::Interrupted => {} + _ => return Err(e), + }, + } + }; + if read == 0 { + // might be unexpected if + // we haven't read `n` bytes + // but this mirrors GNU's behavior + return Ok(()); + } + stdout.write_all(&readbuf[..read.min(n - i)])?; + i += read.min(n - i); + if i == n { + return Ok(()); + } + } +} + +fn rbuf_n_lines(input: &mut impl std::io::BufRead, n: usize, zero: bool) -> std::io::Result<()> { + if n == 0 { + return Ok(()); + } + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + let mut lines = 0usize; + split::walk_lines(input, zero, |e| match e { + split::Event::Data(dat) => { + stdout.write_all(dat)?; + Ok(true) + } + split::Event::Line => { + lines += 1; + if lines == n { + Ok(false) + } else { + Ok(true) + } + } + }) +} + +fn rbuf_but_last_n_bytes(input: &mut impl std::io::BufRead, n: usize) -> std::io::Result<()> { + if n == 0 { + //prints everything + return rbuf_n_bytes(input, std::usize::MAX); + } + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + + let mut ringbuf = vec![0u8; n]; + + // first we fill the ring buffer + if let Err(e) = input.read_exact(&mut ringbuf) { + if e.kind() == ErrorKind::UnexpectedEof { + return Ok(()); + } else { + return Err(e); + } + } + let mut buffer = [0u8; BUF_SIZE]; + loop { + let read = loop { + match input.read(&mut buffer) { + Ok(n) => break n, + Err(e) => match e.kind() { + ErrorKind::Interrupted => {} + _ => return Err(e), + }, + } + }; + if read == 0 { + return Ok(()); + } else if read >= n { + stdout.write_all(&ringbuf)?; + stdout.write_all(&buffer[..read - n])?; + for i in 0..n { + ringbuf[i] = buffer[read - n + i]; + } + } else { + stdout.write_all(&ringbuf[..read])?; + for i in 0..n - read { + ringbuf[i] = ringbuf[read + i]; + } + ringbuf[n - read..].copy_from_slice(&buffer[..read]); + } + } +} + +fn rbuf_but_last_n_lines( + input: &mut impl std::io::BufRead, + n: usize, + zero: bool, +) -> std::io::Result<()> { + if n == 0 { + //prints everything + return rbuf_n_bytes(input, std::usize::MAX); + } + let mut ringbuf = vec![Vec::new(); n]; + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + let mut line = Vec::new(); + let mut lines = 0usize; + split::walk_lines(input, zero, |e| match e { + split::Event::Data(dat) => { + line.extend_from_slice(dat); + Ok(true) + } + split::Event::Line => { + if lines < n { + ringbuf[lines] = std::mem::replace(&mut line, Vec::new()); + lines += 1; + } else { + stdout.write_all(&ringbuf[0])?; + ringbuf.rotate_left(1); + ringbuf[n - 1] = std::mem::replace(&mut line, Vec::new()); + } + Ok(true) + } + }) +} + +fn head_backwards_file(input: &mut std::fs::File, options: &HeadOptions) -> std::io::Result<()> { + assert!(options.all_but_last); + let size = input.seek(SeekFrom::End(0))?; + let size = usize::try_from(size).unwrap(); + match options.mode { + Modes::Bytes(n) => { + if n >= size { + return Ok(()); + } else { + input.seek(SeekFrom::Start(0))?; + rbuf_n_bytes( + &mut std::io::BufReader::with_capacity(BUF_SIZE, input), + size - n, + )?; + } + } + Modes::Lines(n) => { + let mut buffer = [0u8; BUF_SIZE]; + let buffer = &mut buffer[..BUF_SIZE.min(size)]; + let mut i = 0usize; + let mut lines = 0usize; + + let found = 'o: loop { + // the casts here are ok, `buffer.len()` should never be above a few k + input.seek(SeekFrom::Current( + -((buffer.len() as i64).min((size - i) as i64)), + ))?; + input.read_exact(buffer)?; + for byte in buffer.iter().rev() { + match byte { + b'\n' if !options.zeroed => { + lines += 1; + } + 0u8 if options.zeroed => { + lines += 1; + } + _ => {} + } + // if it were just `n`, + if lines == n + 1 { + break 'o i; + } + i += 1; + } + if size - i == 0 { + return Ok(()); + } + }; + input.seek(SeekFrom::Start(0))?; + rbuf_n_bytes( + &mut std::io::BufReader::with_capacity(BUF_SIZE, input), + size - found, + )?; + } + } + Ok(()) +} + +fn head_file(input: &mut std::fs::File, options: &HeadOptions) -> std::io::Result<()> { + if options.all_but_last { + head_backwards_file(input, options) + } else { + match options.mode { + Modes::Bytes(n) => { + rbuf_n_bytes(&mut std::io::BufReader::with_capacity(BUF_SIZE, input), n) + } + Modes::Lines(n) => rbuf_n_lines( + &mut std::io::BufReader::with_capacity(BUF_SIZE, input), + n, + options.zeroed, + ), + } + } +} + +fn uu_head(options: &HeadOptions) { + let mut first = true; + for fname in &options.files { + let res = match fname.as_str() { + "-" => { + if options.verbose { + if !first { + println!(); + } + println!("==> standard input <==") + } + let stdin = std::io::stdin(); + let mut stdin = stdin.lock(); + match options.mode { + Modes::Bytes(n) => { + if options.all_but_last { + rbuf_but_last_n_bytes(&mut stdin, n) + } else { + rbuf_n_bytes(&mut stdin, n) + } + } + Modes::Lines(n) => { + if options.all_but_last { + rbuf_but_last_n_lines(&mut stdin, n, options.zeroed) + } else { + rbuf_n_lines(&mut stdin, n, options.zeroed) + } + } + } + } + name => { + let mut file = match std::fs::File::open(name) { + Ok(f) => f, + Err(err) => match err.kind() { + ErrorKind::NotFound => { + crash!( + EXIT_FAILURE, + "head: cannot open '{}' for reading: No such file or directory", + name + ); + } + ErrorKind::PermissionDenied => { + crash!( + EXIT_FAILURE, + "head: cannot open '{}' for reading: Permission denied", + name + ); + } + _ => { + crash!( + EXIT_FAILURE, + "head: cannot open '{}' for reading: {}", + name, + err + ); + } + }, + }; + if (options.files.len() > 1 && !options.quiet) || options.verbose { + println!("==> {} <==", name) + } + head_file(&mut file, options) + } + }; + if res.is_err() { + if fname.as_str() == "-" { + crash!( + EXIT_FAILURE, + "head: error reading standard input: Input/output error" + ); + } else { + crash!( + EXIT_FAILURE, + "head: error reading {}: Input/output error", + fname + ); + } + } + first = false; } } pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); - - let mut settings: Settings = Default::default(); - - // handle obsolete -number syntax - let new_args = match obsolete(&args[0..]) { - (args, Some(n)) => { - settings.mode = FilterMode::Lines(n); - args - } - (args, None) => args, - }; - - let matches = app!(SYNTAX, SUMMARY, LONG_HELP) - .optopt( - "c", - "bytes", - "Print the first K bytes. With the leading '-', print all but the last K bytes", - "[-]K", - ) - .optopt( - "n", - "lines", - "Print the first K lines. With the leading '-', print all but the last K lines", - "[-]K", - ) - .optflag("q", "quiet", "never print headers giving file names") - .optflag("v", "verbose", "always print headers giving file names") - .optflag("z", "zero-terminated", "line delimiter is NUL, not newline") - .optflag("h", "help", "display this help and exit") - .optflag("V", "version", "output version information and exit") - .parse(new_args); - - let use_bytes = matches.opt_present("c"); - // TODO: suffixes (e.g. b, kB, etc.) - match matches.opt_str("n") { - Some(n) => { - if use_bytes { - show_error!("cannot specify both --bytes and --lines."); - return 1; - } - - match n.parse::() { - Ok(m) => { - settings.mode = if m < 0 { - let m: usize = m.abs() as usize; - FilterMode::NLines(m) - } else { - let m: usize = m.abs() as usize; - FilterMode::Lines(m) - } - } - Err(e) => { - show_error!("invalid line count '{}': {}", n, e); - return 1; - } - } - } - None => { - if let Some(count) = matches.opt_str("c") { - match count.parse::() { - Ok(m) => settings.mode = FilterMode::Bytes(m), - Err(e) => { - show_error!("invalid byte count '{}': {}", count, e); - return 1; - } - } - } + let args = match HeadOptions::get_from(args) { + Ok(o) => o, + Err(s) => { + crash!(EXIT_FAILURE, "head: {}", s); } }; + uu_head(&args); - let quiet = matches.opt_present("q"); - let verbose = matches.opt_present("v"); - settings.zero_terminated = matches.opt_present("z"); - let files = matches.free; - - // GNU implementation allows multiple declarations of "-q" and "-v" with the - // last flag winning. This can't be simulated with the getopts cargo unless - // we manually parse the arguments. Given the declaration of both flags, - // verbose mode always wins. This is a potential future improvement. - if files.len() > 1 && !quiet && !verbose { - settings.verbose = true; - } - if quiet { - settings.verbose = false; - } - if verbose { - settings.verbose = true; - } - - if files.is_empty() { - let mut buffer = BufReader::new(stdin()); - head(&mut buffer, &settings); - } else { - let mut first_time = true; - - for file in &files { - if settings.verbose { - if !first_time { - println!(); - } - println!("==> {} <==", file); - } - first_time = false; - - let path = Path::new(file); - if path.is_dir() || !path.metadata().is_ok() { - eprintln!( - "cannot open '{}' for reading: No such file or directory", - &path.to_str().unwrap() - ); - continue; - } - let reader = File::open(&path).unwrap(); - let mut buffer = BufReader::new(reader); - if !head(&mut buffer, &settings) { - break; - } - } - } - - 0 + EXIT_SUCCESS } -// It searches for an option in the form of -123123 -// -// In case is found, the options vector will get rid of that object so that -// getopts works correctly. -fn obsolete(options: &[String]) -> (Vec, Option) { - let mut options: Vec = options.to_vec(); - let mut a = 1; - let b = options.len(); +#[cfg(test)] +mod tests { + use std::ffi::OsString; - while a < b { - let previous = options[a - 1].clone(); - let current = options[a].clone(); - let current = current.as_bytes(); - - if previous != "-n" && current.len() > 1 && current[0] == b'-' { - let len = current.len(); - for pos in 1..len { - // Ensure that the argument is only made out of digits - if !(current[pos] as char).is_numeric() { - break; - } - - // If this is the last number - if pos == len - 1 { - options.remove(a); - let number: Option = - from_utf8(¤t[1..len]).unwrap().parse::().ok(); - return (options, Some(number.unwrap())); - } - } - } - - a += 1; + use super::*; + fn options(args: &str) -> Result { + let combined = "head ".to_owned() + args; + let args = combined.split_whitespace(); + HeadOptions::get_from(args.map(|s| OsString::from(s))) } + #[test] + fn test_args_modes() { + let args = options("-n -10M -vz").unwrap(); + assert!(args.zeroed); + assert!(args.verbose); + assert!(args.all_but_last); + assert_eq!(args.mode, Modes::Lines(10 * 1024 * 1024)); + } + #[test] + fn test_gnu_compatibility() { + let args = options("-n 1 -c 1 -n 5 -c kiB -vqvqv").unwrap(); + assert!(args.mode == Modes::Bytes(1024)); + assert!(args.verbose); + assert_eq!(options("-5").unwrap().mode, Modes::Lines(5)); + assert_eq!(options("-2b").unwrap().mode, Modes::Bytes(1024)); + assert_eq!(options("-5 -c 1").unwrap().mode, Modes::Bytes(1)); + } + #[test] + fn all_args_test() { + assert!(options("--silent").unwrap().quiet); + assert!(options("--quiet").unwrap().quiet); + assert!(options("-q").unwrap().quiet); + assert!(options("--verbose").unwrap().verbose); + assert!(options("-v").unwrap().verbose); + assert!(options("--zero-terminated").unwrap().zeroed); + assert!(options("-z").unwrap().zeroed); + assert_eq!(options("--lines 15").unwrap().mode, Modes::Lines(15)); + assert_eq!(options("-n 15").unwrap().mode, Modes::Lines(15)); + assert_eq!(options("--bytes 15").unwrap().mode, Modes::Bytes(15)); + assert_eq!(options("-c 15").unwrap().mode, Modes::Bytes(15)); + } + #[test] + fn test_options_errors() { + assert!(options("-n IsThisTheRealLife?").is_err()); + assert!(options("-c IsThisJustFantasy").is_err()); + } + #[test] + fn test_options_correct_defaults() { + let opts = HeadOptions::new(); + let opts2: HeadOptions = Default::default(); - (options, None) -} + assert_eq!(opts, opts2); -// TODO: handle errors on read -fn head(reader: &mut BufReader, settings: &Settings) -> bool { - match settings.mode { - FilterMode::Bytes(count) => { - for byte in reader.bytes().take(count) { - print!("{}", byte.unwrap() as char); - } - } - FilterMode::Lines(count) => { - if settings.zero_terminated { - for line in reader.split(0).take(count) { - print!("{}\0", String::from_utf8(line.unwrap()).unwrap()) - } - } else { - for line in reader.lines().take(count) { - println!("{}", line.unwrap()); - } - } - } - FilterMode::NLines(count) => { - let mut vector: VecDeque = VecDeque::new(); - - for line in reader.lines() { - vector.push_back(line.unwrap()); - if vector.len() <= count { - continue; - } - println!("{}", vector.pop_front().unwrap()); + assert!(opts.verbose == false); + assert!(opts.quiet == false); + assert!(opts.zeroed == false); + assert!(opts.all_but_last == false); + assert_eq!(opts.mode, Modes::Lines(10)); + assert!(opts.files.is_empty()); + } + #[test] + fn test_parse_mode() { + assert_eq!( + parse_mode("123", Modes::Lines), + Ok((Modes::Lines(123), false)) + ); + assert_eq!( + parse_mode("-456", Modes::Bytes), + Ok((Modes::Bytes(456), true)) + ); + assert!(parse_mode("Nonsensical Nonsense", Modes::Bytes).is_err()); + #[cfg(target_pointer_width = "64")] + assert!(parse_mode("1Y", Modes::Lines).is_err()); + #[cfg(target_pointer_width = "32")] + assert!(parse_mode("1T", Modes::Bytes).is_err()); + } + fn arg_outputs(src: &str) -> Result { + let split = src.split_whitespace().map(|x| OsString::from(x)); + match arg_iterate(split) { + Ok(args) => { + let vec = args + .map(|s| s.to_str().unwrap().to_owned()) + .collect::>(); + Ok(vec.join(" ")) } + Err(e) => Err(e), } } - true + #[test] + fn test_arg_iterate() { + // test that normal args remain unchanged + assert_eq!( + arg_outputs("head -n -5 -zv"), + Ok("head -n -5 -zv".to_owned()) + ); + // tests that nonsensical args are unchanged + assert_eq!( + arg_outputs("head -to_be_or_not_to_be,..."), + Ok("head -to_be_or_not_to_be,...".to_owned()) + ); + //test that the obsolete syntax is unrolled + assert_eq!( + arg_outputs("head -123qvqvqzc"), + Ok("head -q -z -c 123".to_owned()) + ); + //test that bad obsoletes are an error + assert!(arg_outputs("head -123FooBar").is_err()); + //test overflow + assert!(arg_outputs("head -100000000000000000000000000000000000000000").is_err()); + //test that empty args remain unchanged + assert_eq!(arg_outputs("head"), Ok("head".to_owned())); + } + #[test] + #[cfg(linux)] + fn test_arg_iterate_bad_encoding() { + let invalid = unsafe { std::str::from_utf8_unchecked(b"\x80\x81") }; + // this arises from a conversion from OsString to &str + assert!( + arg_iterate(vec![OsString::from("head"), OsString::from(invalid)].into_iter()).is_err() + ); + } + #[test] + fn rbuf_early_exit() { + let mut empty = std::io::BufReader::new(std::io::Cursor::new(Vec::new())); + assert!(rbuf_n_bytes(&mut empty, 0).is_ok()); + assert!(rbuf_n_lines(&mut empty, 0, false).is_ok()); + } } diff --git a/src/uu/head/src/parse.rs b/src/uu/head/src/parse.rs new file mode 100644 index 000000000..470d821e0 --- /dev/null +++ b/src/uu/head/src/parse.rs @@ -0,0 +1,282 @@ +use std::convert::TryFrom; +use std::ffi::OsString; + +#[derive(PartialEq, Debug)] +pub enum ParseError { + Syntax, + Overflow, +} +/// Parses obsolete syntax +/// head -NUM[kmzv] +pub fn parse_obsolete(src: &str) -> Option, ParseError>> { + let mut chars = src.char_indices(); + if let Some((_, '-')) = chars.next() { + let mut num_end = 0usize; + let mut has_num = false; + let mut last_char = 0 as char; + while let Some((n, c)) = chars.next() { + if c.is_numeric() { + has_num = true; + num_end = n; + } else { + last_char = c; + break; + } + } + if has_num { + match src[1..=num_end].parse::() { + Ok(num) => { + let mut quiet = false; + let mut verbose = false; + let mut zero_terminated = false; + let mut multiplier = None; + let mut c = last_char; + loop { + // not that here, we only match lower case 'k', 'c', and 'm' + match c { + // we want to preserve order + // this also saves us 1 heap allocation + 'q' => { + quiet = true; + verbose = false + } + 'v' => { + verbose = true; + quiet = false + } + 'z' => zero_terminated = true, + 'c' => multiplier = Some(1), + 'b' => multiplier = Some(512), + 'k' => multiplier = Some(1024), + 'm' => multiplier = Some(1024 * 1024), + '\0' => {} + _ => return Some(Err(ParseError::Syntax)), + } + if let Some((_, next)) = chars.next() { + c = next + } else { + break; + } + } + let mut options = Vec::new(); + if quiet { + options.push(OsString::from("-q")) + } + if verbose { + options.push(OsString::from("-v")) + } + if zero_terminated { + options.push(OsString::from("-z")) + } + if let Some(n) = multiplier { + options.push(OsString::from("-c")); + let num = match num.checked_mul(n) { + Some(n) => n, + None => return Some(Err(ParseError::Overflow)), + }; + options.push(OsString::from(format!("{}", num))); + } else { + options.push(OsString::from("-n")); + options.push(OsString::from(format!("{}", num))); + } + Some(Ok(options.into_iter())) + } + Err(_) => Some(Err(ParseError::Overflow)), + } + } else { + None + } + } else { + None + } +} +/// Parses an -c or -n argument, +/// the bool specifies whether to read from the end +pub fn parse_num(src: &str) -> Result<(usize, bool), ParseError> { + let mut num_start = 0; + let mut chars = src.char_indices(); + let (mut chars, all_but_last) = match chars.next() { + Some((_, c)) => { + if c == '-' { + num_start += 1; + (chars, true) + } else { + (src.char_indices(), false) + } + } + None => return Err(ParseError::Syntax), + }; + let mut num_end = 0usize; + let mut last_char = 0 as char; + let mut num_count = 0usize; + while let Some((n, c)) = chars.next() { + if c.is_numeric() { + num_end = n; + num_count += 1; + } else { + last_char = c; + break; + } + } + + let num = if num_count > 0 { + match src[num_start..=num_end].parse::() { + Ok(n) => Some(n), + Err(_) => return Err(ParseError::Overflow), + } + } else { + None + }; + + if last_char == 0 as char { + if let Some(n) = num { + Ok((n, all_but_last)) + } else { + Err(ParseError::Syntax) + } + } else { + let base: u128 = match chars.next() { + Some((_, c)) => { + let b = match c { + 'B' if last_char != 'b' => 1000, + 'i' if last_char != 'b' => { + if let Some((_, 'B')) = chars.next() { + 1024 + } else { + return Err(ParseError::Syntax); + } + } + _ => return Err(ParseError::Syntax), + }; + if chars.next().is_some() { + return Err(ParseError::Syntax); + } else { + b + } + } + None => 1024, + }; + let mul = match last_char.to_lowercase().next().unwrap() { + 'b' => 512, + 'k' => base.pow(1), + 'm' => base.pow(2), + 'g' => base.pow(3), + 't' => base.pow(4), + 'p' => base.pow(5), + 'e' => base.pow(6), + 'z' => base.pow(7), + 'y' => base.pow(8), + _ => return Err(ParseError::Syntax), + }; + let mul = match usize::try_from(mul) { + Ok(n) => n, + Err(_) => return Err(ParseError::Overflow), + }; + match num.unwrap_or(1).checked_mul(mul) { + Some(n) => Ok((n, all_but_last)), + None => Err(ParseError::Overflow), + } + } +} +#[cfg(test)] +mod tests { + use super::*; + fn obsolete(src: &str) -> Option, ParseError>> { + let r = parse_obsolete(src); + match r { + Some(s) => match s { + Ok(v) => Some(Ok(v.map(|s| s.to_str().unwrap().to_owned()).collect())), + Err(e) => Some(Err(e)), + }, + None => None, + } + } + fn obsolete_result(src: &[&str]) -> Option, ParseError>> { + Some(Ok(src.iter().map(|s| s.to_string()).collect())) + } + #[test] + #[cfg(not(target_pointer_width = "128"))] + fn test_parse_overflow_x64() { + assert_eq!(parse_num("1Y"), Err(ParseError::Overflow)); + assert_eq!(parse_num("1Z"), Err(ParseError::Overflow)); + assert_eq!(parse_num("100E"), Err(ParseError::Overflow)); + assert_eq!(parse_num("100000P"), Err(ParseError::Overflow)); + assert_eq!(parse_num("1000000000T"), Err(ParseError::Overflow)); + assert_eq!( + parse_num("10000000000000000000000"), + Err(ParseError::Overflow) + ); + } + #[test] + #[cfg(target_pointer_width = "32")] + fn test_parse_overflow_x32() { + assert_eq!(parse_num("1T"), Err(ParseError::Overflow)); + assert_eq!(parse_num("1000G"), Err(ParseError::Overflow)); + } + #[test] + fn test_parse_bad_syntax() { + assert_eq!(parse_num("5MiB nonsense"), Err(ParseError::Syntax)); + assert_eq!(parse_num("Nonsense string"), Err(ParseError::Syntax)); + assert_eq!(parse_num("5mib"), Err(ParseError::Syntax)); + assert_eq!(parse_num("biB"), Err(ParseError::Syntax)); + assert_eq!(parse_num("-"), Err(ParseError::Syntax)); + assert_eq!(parse_num(""), Err(ParseError::Syntax)); + } + #[test] + fn test_parse_numbers() { + assert_eq!(parse_num("k"), Ok((1024, false))); + assert_eq!(parse_num("MiB"), Ok((1024 * 1024, false))); + assert_eq!(parse_num("-5"), Ok((5, true))); + assert_eq!(parse_num("b"), Ok((512, false))); + assert_eq!(parse_num("-2GiB"), Ok((2 * 1024 * 1024 * 1024, true))); + assert_eq!(parse_num("5M"), Ok((5 * 1024 * 1024, false))); + assert_eq!(parse_num("5MB"), Ok((5 * 1000 * 1000, false))); + } + #[test] + fn test_parse_numbers_obsolete() { + assert_eq!(obsolete("-5"), obsolete_result(&["-n", "5"])); + assert_eq!(obsolete("-100"), obsolete_result(&["-n", "100"])); + assert_eq!(obsolete("-5m"), obsolete_result(&["-c", "5242880"])); + assert_eq!(obsolete("-1k"), obsolete_result(&["-c", "1024"])); + assert_eq!(obsolete("-2b"), obsolete_result(&["-c", "1024"])); + assert_eq!(obsolete("-1mmk"), obsolete_result(&["-c", "1024"])); + assert_eq!(obsolete("-1vz"), obsolete_result(&["-v", "-z", "-n", "1"])); + assert_eq!( + obsolete("-1vzqvq"), + obsolete_result(&["-q", "-z", "-n", "1"]) + ); + assert_eq!(obsolete("-1vzc"), obsolete_result(&["-v", "-z", "-c", "1"])); + assert_eq!( + obsolete("-105kzm"), + obsolete_result(&["-z", "-c", "110100480"]) + ); + } + #[test] + fn test_parse_errors_obsolete() { + assert_eq!(obsolete("-5n"), Some(Err(ParseError::Syntax))); + assert_eq!(obsolete("-5c5"), Some(Err(ParseError::Syntax))); + } + #[test] + fn test_parse_obsolete_nomatch() { + assert_eq!(obsolete("-k"), None); + assert_eq!(obsolete("asd"), None); + } + #[test] + #[cfg(target_pointer_width = "64")] + fn test_parse_obsolete_overflow_x64() { + assert_eq!( + obsolete("-1000000000000000m"), + Some(Err(ParseError::Overflow)) + ); + assert_eq!( + obsolete("-10000000000000000000000"), + Some(Err(ParseError::Overflow)) + ); + } + #[test] + #[cfg(target_pointer_width = "32")] + fn test_parse_obsolete_overflow_x32() { + assert_eq!(obsolete("-42949672960"), Some(Err(ParseError::Overflow))); + assert_eq!(obsolete("-42949672k"), Some(Err(ParseError::Overflow))); + } +} diff --git a/src/uu/head/src/split.rs b/src/uu/head/src/split.rs new file mode 100644 index 000000000..9e9a0c685 --- /dev/null +++ b/src/uu/head/src/split.rs @@ -0,0 +1,60 @@ +#[derive(Debug)] +pub enum Event<'a> { + Data(&'a [u8]), + Line, +} +/// Loops over the lines read from a BufRead. +/// # Arguments +/// * `input` the ReadBuf to read from +/// * `zero` whether to use 0u8 as a line delimiter +/// * `on_event` a closure receiving some bytes read in a slice, or +/// event signalling a line was just read. +/// this is guaranteed to be signalled *directly* after the +/// slice containing the (CR on win)LF / 0 is passed +/// +/// Return whether to continue +pub fn walk_lines( + input: &mut impl std::io::BufRead, + zero: bool, + mut on_event: F, +) -> std::io::Result<()> +where + F: FnMut(Event) -> std::io::Result, +{ + let mut buffer = [0u8; super::BUF_SIZE]; + loop { + let read = loop { + match input.read(&mut buffer) { + Ok(n) => break n, + Err(e) => match e.kind() { + std::io::ErrorKind::Interrupted => {} + _ => return Err(e), + }, + } + }; + if read == 0 { + return Ok(()); + } + let mut base = 0usize; + for (i, byte) in buffer[..read].iter().enumerate() { + match byte { + b'\n' if !zero => { + on_event(Event::Data(&buffer[base..=i]))?; + base = i + 1; + if !on_event(Event::Line)? { + return Ok(()); + } + } + 0u8 if zero => { + on_event(Event::Data(&buffer[base..=i]))?; + base = i + 1; + if !on_event(Event::Line)? { + return Ok(()); + } + } + _ => {} + } + } + on_event(Event::Data(&buffer[base..read]))?; + } +} diff --git a/tests/by-util/test_head.rs b/tests/by-util/test_head.rs old mode 100644 new mode 100755 index a1086c004..d91cc1289 --- a/tests/by-util/test_head.rs +++ b/tests/by-util/test_head.rs @@ -86,88 +86,74 @@ fn test_verbose() { .stdout_is_fixture("lorem_ipsum_verbose.expected"); } -#[test] -fn test_zero_terminated() { - new_ucmd!() - .args(&["-z", "zero_terminated.txt"]) - .run() - .stdout_is_fixture("zero_terminated.expected"); -} - #[test] #[ignore] fn test_spams_newline() { + //this test is does not mirror what GNU does new_ucmd!().pipe_in("a").succeeds().stdout_is("a\n"); } #[test] -#[ignore] -fn test_unsupported_byte_syntax() { +fn test_byte_syntax() { new_ucmd!() .args(&["-1c"]) .pipe_in("abc") - .fails() - //GNU head returns "a" - .stdout_is("") - .stderr_is("head: error: Unrecognized option: \'1\'"); + .run() + .stdout_is("a"); } #[test] -#[ignore] -fn test_unsupported_line_syntax() { +fn test_line_syntax() { new_ucmd!() .args(&["-n", "2048m"]) .pipe_in("a\n") - .fails() - //.stdout_is("a\n"); What GNU head returns. - .stdout_is("") - .stderr_is("head: error: invalid line count \'2048m\': invalid digit found in string"); + .run() + .stdout_is("a\n"); } #[test] -#[ignore] -fn test_unsupported_zero_terminated_syntax() { +fn test_zero_terminated_syntax() { new_ucmd!() - .args(&["-z -n 1"]) + .args(&["-z", "-n", "1"]) .pipe_in("x\0y") - .fails() - //GNU Head returns "x\0" - .stderr_is("head: error: Unrecognized option: \'z\'"); + .run() + .stdout_is("x\0"); } #[test] -#[ignore] -fn test_unsupported_zero_terminated_syntax_2() { +fn test_zero_terminated_syntax_2() { new_ucmd!() - .args(&["-z -n 2"]) + .args(&["-z", "-n", "2"]) .pipe_in("x\0y") - .fails() - //GNU Head returns "x\0y" - .stderr_is("head: error: Unrecognized option: \'z\'"); + .run() + .stdout_is("x\0y"); } #[test] -#[ignore] -fn test_unsupported_negative_byte_syntax() { +fn test_negative_byte_syntax() { new_ucmd!() .args(&["--bytes=-2"]) .pipe_in("a\n") - .fails() - //GNU Head returns "" - .stderr_is("head: error: invalid byte count \'-2\': invalid digit found in string"); + .run() + .stdout_is(""); } #[test] -#[ignore] -fn test_bug_in_negative_zero_lines() { +fn test_negative_zero_lines() { new_ucmd!() .args(&["--lines=-0"]) .pipe_in("a\nb\n") .succeeds() - //GNU Head returns "a\nb\n" - .stdout_is(""); + .stdout_is("a\nb\n"); +} +#[test] +fn test_negative_zero_bytes() { + new_ucmd!() + .args(&["--bytes=-0"]) + .pipe_in("qwerty") + .succeeds() + .stdout_is("qwerty"); } - #[test] fn test_no_such_file_or_directory() { let result = new_ucmd!().arg("no_such_file.toml").run(); @@ -179,3 +165,38 @@ fn test_no_such_file_or_directory() { .contains("cannot open 'no_such_file.toml' for reading: No such file or directory") ) } + +// there was a bug not caught by previous tests +// where for negative n > 3, the total amount of lines +// was correct, but it would eat from the second line +#[test] +fn test_sequence_fixture() { + new_ucmd!() + .args(&["-n", "-10", "sequence"]) + .run() + .stdout_is_fixture("sequence.expected"); +} +#[test] +fn test_file_backwards() { + new_ucmd!() + .args(&["-c", "-10", "lorem_ipsum.txt"]) + .run() + .stdout_is_fixture("lorem_ipsum_backwards_file.expected"); +} + +#[test] +fn test_zero_terminated() { + new_ucmd!() + .args(&["-z", "zero_terminated.txt"]) + .run() + .stdout_is_fixture("zero_terminated.expected"); +} + +#[test] +fn test_obsolete_extras() { + new_ucmd!() + .args(&["-5zv"]) + .pipe_in("1\02\03\04\05\06") + .succeeds() + .stdout_is("==> standard input <==\n1\02\03\04\05\0"); +} diff --git a/tests/fixtures/head/lorem_ipsum_backwards_file.expected b/tests/fixtures/head/lorem_ipsum_backwards_file.expected new file mode 100644 index 000000000..fcf432187 --- /dev/null +++ b/tests/fixtures/head/lorem_ipsum_backwards_file.expected @@ -0,0 +1,24 @@ +Lorem ipsum dolor sit amet, +consectetur adipiscing elit. +Nunc interdum suscipit sem vel ornare. +Proin euismod, +justo sed mollis dictum, +eros urna ultricies augue, +eu pharetra mi ex id ante. +Duis convallis porttitor aliquam. +Nunc vitae tincidunt ex. +Suspendisse iaculis ligula ac diam consectetur lacinia. +Donec vel velit dui. +Etiam fringilla, +dolor quis tempor vehicula, +lacus turpis bibendum velit, +et pellentesque elit odio a magna. +Cras vulputate tortor non libero vehicula euismod. +Aliquam tincidunt nisl eget enim cursus, +viverra sagittis magna commodo. +Cras rhoncus egestas leo nec blandit. +Suspendisse potenti. +Etiam ullamcorper leo vel lacus vestibulum, +cursus semper eros efficitur. +In hac habitasse platea dictumst. +Phasellus scelerisque vehicula f \ No newline at end of file diff --git a/tests/fixtures/head/sequence b/tests/fixtures/head/sequence new file mode 100644 index 000000000..190423f88 --- /dev/null +++ b/tests/fixtures/head/sequence @@ -0,0 +1,100 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 diff --git a/tests/fixtures/head/sequence.expected b/tests/fixtures/head/sequence.expected new file mode 100644 index 000000000..17d2a1390 --- /dev/null +++ b/tests/fixtures/head/sequence.expected @@ -0,0 +1,90 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 From 5f17719a59344066ae0b4adff51a7096d97a9b43 Mon Sep 17 00:00:00 2001 From: Ricardo Iglesias Date: Mon, 29 Mar 2021 04:10:13 -0700 Subject: [PATCH 038/132] Implemented --indicator-style flag on ls. (#1907) * Implemented --indicator-style flag on ls. * Rust fmt * Grouped indicator_style args. * Added tests for sockets and pipes. Needed to modify util.rs to add support for pipes (aka FIFOs). * Updated util.rs to remove FIFO operations on Windows * Fixed slight error in specifying (not(windows)) * Fixed style violations and added indicator_style test for non-unix systems --- Cargo.toml | 2 + src/uu/ls/src/ls.rs | 182 ++++++++++++++++++++++++++++++++------- tests/by-util/test_ls.rs | 114 ++++++++++++++++++++++++ tests/common/util.rs | 26 +++++- 4 files changed, 290 insertions(+), 34 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 08e9a3bb2..9136b5d64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -345,11 +345,13 @@ time = "0.1" unindent = "0.1" uucore = { version=">=0.0.7", package="uucore", path="src/uucore", features=["entries"] } walkdir = "2.2" +tempdir = "0.3" [target.'cfg(unix)'.dev-dependencies] rust-users = { version="0.10", package="users" } unix_socket = "0.5.0" + [[bin]] name = "coreutils" path = "src/bin/coreutils.rs" diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 201ddc7a6..80a7bf328 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -104,6 +104,14 @@ pub mod options { pub static HUMAN_READABLE: &str = "human-readable"; pub static SI: &str = "si"; } + + pub mod indicator_style { + pub static NONE: &str = "none"; + pub static SLASH: &str = "slash"; + pub static FILE_TYPE: &str = "file-type"; + pub static CLASSIFY: &str = "classify"; + } + pub static WIDTH: &str = "width"; pub static AUTHOR: &str = "author"; pub static NO_GROUP: &str = "no-group"; @@ -113,12 +121,15 @@ pub mod options { pub static IGNORE_BACKUPS: &str = "ignore-backups"; pub static DIRECTORY: &str = "directory"; pub static CLASSIFY: &str = "classify"; + pub static FILE_TYPE: &str = "file-type"; + pub static SLASH: &str = "p"; pub static INODE: &str = "inode"; pub static DEREFERENCE: &str = "dereference"; pub static REVERSE: &str = "reverse"; pub static RECURSIVE: &str = "recursive"; pub static COLOR: &str = "color"; pub static PATHS: &str = "paths"; + pub static INDICATOR_STYLE: &str = "indicator-style"; } #[derive(PartialEq, Eq)] @@ -157,6 +168,14 @@ enum Time { Change, } +#[derive(PartialEq, Eq)] +enum IndicatorStyle { + None, + Slash, + FileType, + Classify, +} + struct Config { format: Format, files: Files, @@ -164,7 +183,6 @@ struct Config { recursive: bool, reverse: bool, dereference: bool, - classify: bool, ignore_backups: bool, size_format: SizeFormat, directory: bool, @@ -175,6 +193,7 @@ struct Config { color: bool, long: LongFormat, width: Option, + indicator_style: IndicatorStyle, } // Fields that can be removed or added to the long format @@ -227,12 +246,19 @@ impl Config { // options, but manually whether they have an index that's greater than // the other format options. If so, we set the appropriate format. if format != Format::Long { - let idx = options.indices_of(opt).map(|x| x.max().unwrap()).unwrap_or(0); - if [options::format::LONG_NO_OWNER, options::format::LONG_NO_GROUP, options::format::LONG_NUMERIC_UID_GID] - .iter() - .flat_map(|opt| options.indices_of(opt)) - .flatten() - .any(|i| i >= idx) + let idx = options + .indices_of(opt) + .map(|x| x.max().unwrap()) + .unwrap_or(0); + if [ + options::format::LONG_NO_OWNER, + options::format::LONG_NO_GROUP, + options::format::LONG_NUMERIC_UID_GID, + ] + .iter() + .flat_map(|opt| options.indices_of(opt)) + .flatten() + .any(|i| i >= idx) { format = Format::Long; } else { @@ -243,7 +269,6 @@ impl Config { } } } - let files = if options.is_present(options::files::ALL) { Files::All @@ -334,6 +359,32 @@ impl Config { }) .or_else(|| termsize::get().map(|s| s.cols)); + let indicator_style = if let Some(field) = options.value_of(options::INDICATOR_STYLE) { + match field { + "none" => IndicatorStyle::None, + "file-type" => IndicatorStyle::FileType, + "classify" => IndicatorStyle::Classify, + "slash" => IndicatorStyle::Slash, + &_ => IndicatorStyle::None, + } + } else if options.is_present(options::indicator_style::NONE) { + IndicatorStyle::None + } else if options.is_present(options::indicator_style::CLASSIFY) + || options.is_present(options::CLASSIFY) + { + IndicatorStyle::Classify + } else if options.is_present(options::indicator_style::SLASH) + || options.is_present(options::SLASH) + { + IndicatorStyle::Slash + } else if options.is_present(options::indicator_style::FILE_TYPE) + || options.is_present(options::FILE_TYPE) + { + IndicatorStyle::FileType + } else { + IndicatorStyle::None + }; + Config { format, files, @@ -341,7 +392,6 @@ impl Config { recursive: options.is_present(options::RECURSIVE), reverse: options.is_present(options::REVERSE), dereference: options.is_present(options::DEREFERENCE), - classify: options.is_present(options::CLASSIFY), ignore_backups: options.is_present(options::IGNORE_BACKUPS), size_format, directory: options.is_present(options::DIRECTORY), @@ -352,6 +402,7 @@ impl Config { inode: options.is_present(options::INODE), long, width, + indicator_style, } } } @@ -623,15 +674,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 { specified.", ), ) - .arg( - Arg::with_name(options::CLASSIFY) - .short("F") - .long(options::CLASSIFY) - .help("Append a character to each file name indicating the file type. Also, for \ - regular files that are executable, append '*'. The file type indicators are \ - '/' for directories, '@' for symbolic links, '|' for FIFOs, '=' for sockets, \ - '>' for doors, and nothing for regular files.", - )) .arg( Arg::with_name(options::size::HUMAN_READABLE) .short("h") @@ -659,7 +701,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 { file the link references rather than the link itself.", ), ) - .arg( Arg::with_name(options::REVERSE) .short("r") @@ -689,8 +730,57 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .require_equals(true) .min_values(0), ) + .arg( + Arg::with_name(options::INDICATOR_STYLE) + .long(options::INDICATOR_STYLE) + .help(" append indicator with style WORD to entry names: none (default), slash\ + (-p), file-type (--file-type), classify (-F)") + .takes_value(true) + .possible_values(&["none", "slash", "file-type", "classify"]) + .overrides_with_all(&[ + options::FILE_TYPE, + options::SLASH, + options::CLASSIFY, + options::INDICATOR_STYLE, + ])) + .arg( + Arg::with_name(options::CLASSIFY) + .short("F") + .long(options::CLASSIFY) + .help("Append a character to each file name indicating the file type. Also, for \ + regular files that are executable, append '*'. The file type indicators are \ + '/' for directories, '@' for symbolic links, '|' for FIFOs, '=' for sockets, \ + '>' for doors, and nothing for regular files.") + .overrides_with_all(&[ + options::FILE_TYPE, + options::SLASH, + options::CLASSIFY, + options::INDICATOR_STYLE, + ]) + ) + .arg( + Arg::with_name(options::FILE_TYPE) + .long(options::FILE_TYPE) + .help("Same as --classify, but do not append '*'") + .overrides_with_all(&[ + options::FILE_TYPE, + options::SLASH, + options::CLASSIFY, + options::INDICATOR_STYLE, + ])) + .arg( + Arg::with_name(options::SLASH) + .short(options::SLASH) + .help("Append / indicator to directories." + ) + .overrides_with_all(&[ + options::FILE_TYPE, + options::SLASH, + options::CLASSIFY, + options::INDICATOR_STYLE, + ])) - // Positional arguments + // Positional arguments .arg(Arg::with_name(options::PATHS).multiple(true).takes_value(true)); let matches = app.get_matches_from(args); @@ -1117,15 +1207,24 @@ fn display_file_name( config: &Config, ) -> Cell { let mut name = get_file_name(path, strip); + let file_type = metadata.file_type(); - if config.classify { - let file_type = metadata.file_type(); - if file_type.is_dir() { - name.push('/'); - } else if file_type.is_symlink() { - name.push('@'); + match config.indicator_style { + IndicatorStyle::Classify | IndicatorStyle::FileType => { + if file_type.is_dir() { + name.push('/'); + } + if file_type.is_symlink() { + name.push('@'); + } } - } + IndicatorStyle::Slash => { + if file_type.is_dir() { + name.push('/'); + } + } + _ => (), + }; if config.format == Format::Long && metadata.file_type().is_symlink() { if let Ok(target) = path.read_link() { @@ -1181,8 +1280,7 @@ fn display_file_name( let mut width = UnicodeWidthStr::width(&*name); let ext; - - if config.color || config.classify { + if config.color || config.indicator_style != IndicatorStyle::None { let file_type = metadata.file_type(); let (code, sym) = if file_type.is_dir() { @@ -1235,11 +1333,29 @@ fn display_file_name( if config.color { name = color_name(name, code); } - if config.classify { - if let Some(s) = sym { - name.push(s); - width += 1; + + let char_opt = match config.indicator_style { + IndicatorStyle::Classify => sym, + IndicatorStyle::FileType => { + // Don't append an asterisk. + match sym { + Some('*') => None, + _ => sym, + } } + IndicatorStyle::Slash => { + // Append only a slash. + match sym { + Some('/') => Some('/'), + _ => None, + } + } + IndicatorStyle::None => None, + }; + + if let Some(c) = char_opt { + name.push(c); + width += 1; } } diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 7d5a3da7b..638102cc7 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1,3 +1,5 @@ +#[cfg(unix)] +extern crate unix_socket; use crate::common::util::*; extern crate regex; @@ -11,7 +13,13 @@ extern crate libc; #[cfg(not(windows))] use self::libc::umask; #[cfg(not(windows))] +use std::path::PathBuf; +#[cfg(not(windows))] use std::sync::Mutex; +#[cfg(not(windows))] +extern crate tempdir; +#[cfg(not(windows))] +use self::tempdir::TempDir; #[cfg(not(windows))] lazy_static! { @@ -813,6 +821,112 @@ fn test_ls_inode() { assert_eq!(inode_short, inode_long) } +#[test] +#[cfg(not(windows))] +fn test_ls_indicator_style() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + // Setup: Directory, Symlink, and Pipes. + at.mkdir("directory"); + assert!(at.dir_exists("directory")); + + at.touch(&at.plus_as_string("link-src")); + at.symlink_file("link-src", "link-dest.link"); + assert!(at.is_symlink("link-dest.link")); + + at.mkfifo("named-pipe.fifo"); + assert!(at.is_fifo("named-pipe.fifo")); + + // Classify, File-Type, and Slash all contain indicators for directories. + let options = vec!["classify", "file-type", "slash"]; + for opt in options { + // Verify that classify and file-type both contain indicators for symlinks. + let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run(); + println!("stdout = {:?}", result.stdout); + assert!(result.stdout.contains("/")); + } + + // Same test as above, but with the alternate flags. + let options = vec!["--classify", "--file-type", "-p"]; + for opt in options { + let result = scene.ucmd().arg(format!("{}", opt)).run(); + println!("stdout = {:?}", result.stdout); + assert!(result.stdout.contains("/")); + } + + // Classify and File-Type all contain indicators for pipes and links. + let options = vec!["classify", "file-type"]; + for opt in options { + // Verify that classify and file-type both contain indicators for symlinks. + let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run(); + println!("stdout = {}", result.stdout); + assert!(result.stdout.contains("@")); + assert!(result.stdout.contains("|")); + } + + // Test sockets. Because the canonical way of making sockets to test is with + // TempDir, we need a separate test. + { + use self::unix_socket::UnixListener; + + let dir = TempDir::new("unix_socket").expect("failed to create dir"); + let socket_path = dir.path().join("sock"); + let _listener = UnixListener::bind(&socket_path).expect("failed to create socket"); + + new_ucmd!() + .args(&[ + PathBuf::from(dir.path().to_str().unwrap()), + PathBuf::from("--indicator-style=classify"), + ]) + .succeeds() + .stdout_only("sock=\n"); + } +} + +// Essentially the same test as above, but only test symlinks and directories, +// not pipes or sockets. +#[test] +#[cfg(not(unix))] +fn test_ls_indicator_style() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + // Setup: Directory, Symlink. + at.mkdir("directory"); + assert!(at.dir_exists("directory")); + + at.touch(&at.plus_as_string("link-src")); + at.symlink_file("link-src", "link-dest.link"); + assert!(at.is_symlink("link-dest.link")); + + // Classify, File-Type, and Slash all contain indicators for directories. + let options = vec!["classify", "file-type", "slash"]; + for opt in options { + // Verify that classify and file-type both contain indicators for symlinks. + let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run(); + println!("stdout = {:?}", result.stdout); + assert!(result.stdout.contains("/")); + } + + // Same test as above, but with the alternate flags. + let options = vec!["--classify", "--file-type", "-p"]; + for opt in options { + let result = scene.ucmd().arg(format!("{}", opt)).run(); + println!("stdout = {:?}", result.stdout); + assert!(result.stdout.contains("/")); + } + + // Classify and File-Type all contain indicators for pipes and links. + let options = vec!["classify", "file-type"]; + for opt in options { + // Verify that classify and file-type both contain indicators for symlinks. + let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run(); + println!("stdout = {}", result.stdout); + assert!(result.stdout.contains("@")); + } +} + #[cfg(not(any(target_vendor = "apple", target_os = "windows")))] // Truncate not available on mac or win #[test] fn test_ls_human_si() { diff --git a/tests/common/util.rs b/tests/common/util.rs index a2fab66c6..d33b1943d 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -1,7 +1,8 @@ #![allow(dead_code)] +use libc; use std::env; -use std::ffi::OsStr; +use std::ffi::{CString, OsStr}; use std::fs::{self, File, OpenOptions}; use std::io::{Read, Result, Write}; #[cfg(unix)] @@ -290,6 +291,29 @@ impl AtPath { File::create(&self.plus(file)).unwrap(); } + #[cfg(not(windows))] + pub fn mkfifo(&self, fifo: &str) { + let full_path = self.plus_as_string(fifo); + log_info("mkfifo", &full_path); + unsafe { + let fifo_name: CString = CString::new(full_path).expect("CString creation failed."); + libc::mkfifo(fifo_name.as_ptr(), libc::S_IWUSR | libc::S_IRUSR); + } + } + + #[cfg(not(windows))] + pub fn is_fifo(&self, fifo: &str) -> bool { + unsafe { + let name = CString::new(self.plus_as_string(fifo)).unwrap(); + let mut stat: libc::stat = std::mem::zeroed(); + if libc::stat(name.as_ptr(), &mut stat) >= 0 { + libc::S_IFIFO & stat.st_mode != 0 + } else { + false + } + } + } + pub fn symlink_file(&self, src: &str, dst: &str) { log_info( "symlink", From 32ddef9b9e8110f0032c437b615d22b6148bcbf2 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 29 Mar 2021 14:35:12 +0200 Subject: [PATCH 039/132] refresh cargo.lock with recent updates (#1964) --- Cargo.lock | 2000 ++++++++++++++++++++++++++-------------------------- 1 file changed, 1018 insertions(+), 982 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07a99069c..b8293f666 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,2265 +4,2139 @@ name = "advapi32-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "aho-corasick" version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" dependencies = [ - "memchr 2.3.4", + "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.9", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "arrayvec" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" dependencies = [ - "nodrop", + "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", - "libc", - "winapi 0.3.9", + "hermit-abi 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bit-set" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" dependencies = [ - "bit-vec", + "bit-vec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bit-vec" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "blake2-rfc" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" dependencies = [ - "arrayvec", - "constant_time_eq", + "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "block-buffer" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" dependencies = [ - "byte-tools", - "generic-array", + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bstr" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" dependencies = [ - "lazy_static", - "memchr 2.3.4", - "regex-automata", - "serde", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bumpalo" version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" [[package]] name = "byte-tools" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cast" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" dependencies = [ - "rustc_version", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" dependencies = [ - "num-integer", - "num-traits", - "time", + "num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clap" version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "constant_time_eq" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "conv" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" dependencies = [ - "custom_derive", + "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "coreutils" version = "0.0.4" dependencies = [ - "conv", - "filetime", - "glob 0.3.0", - "lazy_static", - "libc", - "nix 0.20.0", - "rand 0.7.3", - "regex", - "sha1", - "tempfile", - "textwrap", - "time", - "unindent", - "unix_socket", - "users", - "uu_arch", - "uu_base32", - "uu_base64", - "uu_basename", - "uu_cat", - "uu_chgrp", - "uu_chmod", - "uu_chown", - "uu_chroot", - "uu_cksum", - "uu_comm", - "uu_cp", - "uu_csplit", - "uu_cut", - "uu_date", - "uu_df", - "uu_dircolors", - "uu_dirname", - "uu_du", - "uu_echo", - "uu_env", - "uu_expand", - "uu_expr", - "uu_factor", - "uu_false", - "uu_fmt", - "uu_fold", - "uu_groups", - "uu_hashsum", - "uu_head", - "uu_hostid", - "uu_hostname", - "uu_id", - "uu_install", - "uu_join", - "uu_kill", - "uu_link", - "uu_ln", - "uu_logname", - "uu_ls", - "uu_mkdir", - "uu_mkfifo", - "uu_mknod", - "uu_mktemp", - "uu_more", - "uu_mv", - "uu_nice", - "uu_nl", - "uu_nohup", - "uu_nproc", - "uu_numfmt", - "uu_od", - "uu_paste", - "uu_pathchk", - "uu_pinky", - "uu_printenv", - "uu_printf", - "uu_ptx", - "uu_pwd", - "uu_readlink", - "uu_realpath", - "uu_relpath", - "uu_rm", - "uu_rmdir", - "uu_seq", - "uu_shred", - "uu_shuf", - "uu_sleep", - "uu_sort", - "uu_split", - "uu_stat", - "uu_stdbuf", - "uu_sum", - "uu_sync", - "uu_tac", - "uu_tail", - "uu_tee", - "uu_test", - "uu_timeout", - "uu_touch", - "uu_tr", - "uu_true", - "uu_truncate", - "uu_tsort", - "uu_tty", - "uu_uname", - "uu_unexpand", - "uu_uniq", - "uu_unlink", - "uu_uptime", - "uu_users", - "uu_wc", - "uu_who", - "uu_whoami", - "uu_yes", - "uucore", - "walkdir", + "conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "unindent 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uu_arch 0.0.4", + "uu_base32 0.0.4", + "uu_base64 0.0.4", + "uu_basename 0.0.4", + "uu_cat 0.0.4", + "uu_chgrp 0.0.4", + "uu_chmod 0.0.4", + "uu_chown 0.0.4", + "uu_chroot 0.0.4", + "uu_cksum 0.0.4", + "uu_comm 0.0.4", + "uu_cp 0.0.4", + "uu_csplit 0.0.4", + "uu_cut 0.0.4", + "uu_date 0.0.4", + "uu_df 0.0.4", + "uu_dircolors 0.0.4", + "uu_dirname 0.0.4", + "uu_du 0.0.4", + "uu_echo 0.0.4", + "uu_env 0.0.4", + "uu_expand 0.0.4", + "uu_expr 0.0.4", + "uu_factor 0.0.4", + "uu_false 0.0.4", + "uu_fmt 0.0.4", + "uu_fold 0.0.4", + "uu_groups 0.0.4", + "uu_hashsum 0.0.4", + "uu_head 0.0.4", + "uu_hostid 0.0.4", + "uu_hostname 0.0.4", + "uu_id 0.0.4", + "uu_install 0.0.4", + "uu_join 0.0.4", + "uu_kill 0.0.4", + "uu_link 0.0.4", + "uu_ln 0.0.4", + "uu_logname 0.0.4", + "uu_ls 0.0.4", + "uu_mkdir 0.0.4", + "uu_mkfifo 0.0.4", + "uu_mknod 0.0.4", + "uu_mktemp 0.0.4", + "uu_more 0.0.4", + "uu_mv 0.0.4", + "uu_nice 0.0.4", + "uu_nl 0.0.4", + "uu_nohup 0.0.4", + "uu_nproc 0.0.4", + "uu_numfmt 0.0.4", + "uu_od 0.0.4", + "uu_paste 0.0.4", + "uu_pathchk 0.0.4", + "uu_pinky 0.0.4", + "uu_printenv 0.0.4", + "uu_printf 0.0.4", + "uu_ptx 0.0.4", + "uu_pwd 0.0.4", + "uu_readlink 0.0.4", + "uu_realpath 0.0.4", + "uu_relpath 0.0.4", + "uu_rm 0.0.4", + "uu_rmdir 0.0.4", + "uu_seq 0.0.4", + "uu_shred 0.0.4", + "uu_shuf 0.0.4", + "uu_sleep 0.0.4", + "uu_sort 0.0.4", + "uu_split 0.0.4", + "uu_stat 0.0.4", + "uu_stdbuf 0.0.4", + "uu_sum 0.0.4", + "uu_sync 0.0.4", + "uu_tac 0.0.4", + "uu_tail 0.0.4", + "uu_tee 0.0.4", + "uu_test 0.0.4", + "uu_timeout 0.0.4", + "uu_touch 0.0.4", + "uu_tr 0.0.4", + "uu_true 0.0.4", + "uu_truncate 0.0.4", + "uu_tsort 0.0.4", + "uu_tty 0.0.4", + "uu_uname 0.0.4", + "uu_unexpand 0.0.4", + "uu_uniq 0.0.4", + "uu_unlink 0.0.4", + "uu_uptime 0.0.4", + "uu_users 0.0.4", + "uu_wc 0.0.4", + "uu_who 0.0.4", + "uu_whoami 0.0.4", + "uu_yes 0.0.4", + "uucore 0.0.7", + "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cpp" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4875a08600be48dcc9cb6ee07f104a3e0752e95184dede6a30044d6480bf50e8" dependencies = [ - "cpp_macros", + "cpp_macros 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cpp_build" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c47531e7e09532ad4827098729794f5e1a5b1c2ccbb5e295498d2e7ab451c445" dependencies = [ - "cc", - "cpp_common 0.4.0", - "cpp_syn", - "cpp_synmap", - "cpp_synom", - "lazy_static", + "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_common 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_synmap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cpp_common" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e39149a7943affa02f5b6e347ca2840a129cc78d5883ee229f0f1c4027d628" dependencies = [ - "cpp_syn", - "cpp_synom", - "lazy_static", - "quote 0.3.15", + "cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cpp_common" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df78ad28e5fe814285016779fb3d3b874520c799a847e6190bf2b834cc4ff283" dependencies = [ - "lazy_static", - "proc-macro2", - "syn", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cpp_macros" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f93a21e618c10abc84ebb63ffa5952e1f7a4568b8141d542d5ef860e4a8fc25" dependencies = [ - "aho-corasick", - "byteorder", - "cpp_common 0.5.6", - "if_rust_version", - "lazy_static", - "proc-macro2", - "quote 1.0.9", - "syn", + "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_common 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "if_rust_version 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cpp_syn" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8cd649bf5b3804d92fe12a60c7698f5a538a6033ed8a668bf5241d4d4f1644e" dependencies = [ - "cpp_synom", - "quote 0.3.15", - "unicode-xid 0.0.4", + "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cpp_synmap" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897e4f9cdbe2874edd3ffe53718ee5d8b89e2a970057b2c93d3214104f2e90b6" dependencies = [ - "cpp_syn", - "cpp_synom", - "memchr 1.0.2", + "cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cpp_synom" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc8da5694233b646150c785118f77835ad0a49680c7f312a10ef30957c67b6d" dependencies = [ - "unicode-xid 0.0.4", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "criterion" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot", - "csv", - "itertools 0.10.0", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion-plot 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "csv 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "oorandom 11.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "plotters 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "tinytemplate 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "criterion-plot" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" dependencies = [ - "cast", - "itertools 0.9.0", + "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-channel" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-deque" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-epoch", - "crossbeam-utils", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-utils" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" dependencies = [ - "autocfg", - "cfg-if 1.0.0", - "lazy_static", + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "csv" version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" dependencies = [ - "bstr", - "csv-core", - "itoa", - "ryu", - "serde", + "bstr 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", + "csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "csv-core" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" dependencies = [ - "memchr 2.3.4", + "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "custom_derive" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" [[package]] name = "data-encoding" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" [[package]] name = "digest" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" dependencies = [ - "generic-array", + "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "dunce" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2641c4a7c0c4101df53ea572bffdc561c146f6c2eb09e4df02bc4811e3feeb4" [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ - "log", - "regex", + "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fake-simd" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "file_diff" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" [[package]] name = "filetime" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.2.5", - "winapi 0.3.9", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fs_extra" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "generic-array" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2297fb0e3ea512e380da24b52dca3924028f59df5e3a17a18f81d8349ca7ebe" dependencies = [ - "nodrop", - "typenum", + "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "getopts" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" dependencies = [ - "unicode-width", + "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "getrandom" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "half" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" [[package]] name = "hermit-abi" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" dependencies = [ - "libc", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hex" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" [[package]] name = "hostname" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "match_cfg 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "if_rust_version" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46dbcb333e86939721589d25a3557e180b52778cb33c7fdfe9e0158ff790d5ec" [[package]] name = "ioctl-sys" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2c4b26352496eaaa8ca7cfa9bd99e93419d3f7983dc6e99c2a35fe9e33504a" [[package]] name = "itertools" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" dependencies = [ - "either", + "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itertools" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" dependencies = [ - "either", + "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itertools" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" dependencies = [ - "either", + "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itoa" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "js-sys" version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821" dependencies = [ - "wasm-bindgen", + "wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" [[package]] name = "log" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "match_cfg" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "maybe-uninit" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "md5" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48" [[package]] name = "memchr" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" dependencies = [ - "libc", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "memchr" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "memoffset" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" dependencies = [ - "autocfg", + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "nix" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" dependencies = [ - "bitflags", - "cc", - "cfg-if 0.1.10", - "libc", - "void", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "nix" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ - "bitflags", - "cc", - "cfg-if 1.0.0", - "libc", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "nodrop" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "num-integer" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg", - "num-traits", + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg", + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num_cpus" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ - "hermit-abi", - "libc", + "hermit-abi 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "number_prefix" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "numtoa" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" [[package]] name = "onig" version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8518fcb2b1b8c2f45f0ad499df4fda6087fc3475ca69a185c173b8315d2fb383" dependencies = [ - "bitflags", - "lazy_static", - "libc", - "onig_sys", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "onig_sys" version = "69.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388410bf5fa341f10e58e6db3975f4bea1ac30247dd79d37a9e5ced3cb4cc3b0" dependencies = [ - "cc", - "pkg-config", + "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "oorandom" version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "paste" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" dependencies = [ - "paste-impl", - "proc-macro-hack", + "paste-impl 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "paste-impl" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" dependencies = [ - "proc-macro-hack", + "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pkg-config" version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] name = "platform-info" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ea9cd21d89bffb387b6c7363d23bead0807be9de676c671b474dd29e7436d3" dependencies = [ - "libc", - "winapi 0.3.9", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "plotters" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", + "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plotters-svg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "plotters-backend" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" [[package]] name = "plotters-svg" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" dependencies = [ - "plotters-backend", + "plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "proc-macro-hack" version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ - "unicode-xid 0.2.1", + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quickcheck" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" dependencies = [ - "env_logger", - "log", - "rand 0.7.3", - "rand_core 0.5.1", + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" [[package]] name = "quote" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "proc-macro2", + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "winapi 0.3.9", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", + "getrandom 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_chacha" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" dependencies = [ - "rand_core 0.4.2", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_pcg" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core 0.5.1", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", + "crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" dependencies = [ - "bitflags", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_termios" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" dependencies = [ - "redox_syscall 0.2.5", + "redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" dependencies = [ - "aho-corasick", - "memchr 2.3.4", - "regex-syntax", + "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-automata" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" dependencies = [ - "byteorder", + "byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" [[package]] name = "remove_dir_all" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.9", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "retain_mut" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53552c6c49e1e13f1a203ef0080ab3bbef0beb570a528993e83df057a9d9bba1" [[package]] name = "rust-ini" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" [[package]] name = "rustc_version" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "winapi-util", + "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser", + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" [[package]] name = "serde_cbor" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" dependencies = [ - "half", - "serde", + "half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn", + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" dependencies = [ - "itoa", - "ryu", - "serde", + "itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sha1" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" [[package]] name = "sha2" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" dependencies = [ - "block-buffer", - "byte-tools", - "digest", - "fake-simd", - "generic-array", + "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sha3" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0" dependencies = [ - "block-buffer", - "byte-tools", - "digest", - "generic-array", + "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "smallvec" version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" dependencies = [ - "maybe-uninit", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" dependencies = [ - "proc-macro2", - "quote 1.0.9", - "unicode-xid 0.2.1", + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if 0.1.10", - "libc", - "rand 0.7.3", - "redox_syscall 0.1.57", - "remove_dir_all", - "winapi 0.3.9", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "term_grid" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "230d3e804faaed5a39b08319efb797783df2fd9671b39b7596490cb486d702cf" dependencies = [ - "unicode-width", + "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "term_size" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" dependencies = [ - "libc", - "winapi 0.3.9", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "termion" version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" dependencies = [ - "libc", - "numtoa", - "redox_syscall 0.2.5", - "redox_termios", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "termsize" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e86d824a8e90f342ad3ef4bd51ef7119a9b681b0cc9f8ee7b2852f02ccd2517" dependencies = [ - "atty", - "kernel32-sys", - "libc", - "termion", - "winapi 0.2.8", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "term_size", - "unicode-width", + "term_size 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thiserror" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thiserror-impl" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn", + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" dependencies = [ - "libc", - "redox_syscall 0.1.57", - "winapi 0.3.9", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tinytemplate" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ - "serde", - "serde_json", + "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "twox-hash" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" dependencies = [ - "cfg-if 0.1.10", - "rand 0.7.3", - "static_assertions", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "typenum" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" [[package]] name = "unicode-width" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "unindent" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" [[package]] name = "unix_socket" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" dependencies = [ - "cfg-if 0.1.10", - "libc", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "users" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486" dependencies = [ - "libc", - "log", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_arch" version = "0.0.4" dependencies = [ - "platform-info", - "uucore", - "uucore_procs", + "platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_base32" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_base64" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_basename" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_cat" version = "0.0.4" dependencies = [ - "clap", - "quick-error", - "unix_socket", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_chgrp" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", - "walkdir", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_chmod" version = "0.0.4" dependencies = [ - "libc", - "uucore", - "uucore_procs", - "walkdir", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_chown" version = "0.0.4" dependencies = [ - "clap", - "glob 0.3.0", - "uucore", - "uucore_procs", - "walkdir", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_chroot" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_cksum" version = "0.0.4" dependencies = [ - "clap", - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_comm" version = "0.0.4" dependencies = [ - "clap", - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_cp" version = "0.0.4" dependencies = [ - "clap", - "filetime", - "ioctl-sys", - "libc", - "quick-error", - "uucore", - "uucore_procs", - "walkdir", - "winapi 0.3.9", - "xattr", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "ioctl-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_csplit" version = "0.0.4" dependencies = [ - "getopts", - "glob 0.2.11", - "regex", - "thiserror", - "uucore", - "uucore_procs", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_cut" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_date" version = "0.0.4" dependencies = [ - "chrono", - "clap", - "libc", - "uucore", - "uucore_procs", - "winapi 0.3.9", + "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_df" version = "0.0.4" dependencies = [ - "clap", - "libc", - "number_prefix", - "uucore", - "uucore_procs", - "winapi 0.3.9", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_dircolors" version = "0.0.4" dependencies = [ - "glob 0.3.0", - "uucore", - "uucore_procs", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_dirname" version = "0.0.4" dependencies = [ - "libc", - "uucore", - "uucore_procs", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_du" version = "0.0.4" dependencies = [ - "time", - "uucore", - "uucore_procs", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_echo" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_env" version = "0.0.4" dependencies = [ - "clap", - "libc", - "rust-ini", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_expand" version = "0.0.4" dependencies = [ - "clap", - "unicode-width", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_expr" version = "0.0.4" dependencies = [ - "libc", - "onig", - "uucore", - "uucore_procs", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "onig 4.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_factor" version = "0.0.4" dependencies = [ - "criterion", - "num-traits", - "paste", - "quickcheck", - "rand 0.7.3", - "rand_chacha", - "smallvec", - "uucore", - "uucore_procs", + "criterion 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_false" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_fmt" version = "0.0.4" dependencies = [ - "clap", - "libc", - "unicode-width", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_fold" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_groups" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_hashsum" version = "0.0.4" dependencies = [ - "blake2-rfc", - "clap", - "digest", - "hex", - "libc", - "md5", - "regex", - "regex-syntax", - "sha1", - "sha2", - "sha3", - "uucore", - "uucore_procs", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "md5 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_head" version = "0.0.4" dependencies = [ - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_hostid" version = "0.0.4" dependencies = [ - "libc", - "uucore", - "uucore_procs", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_hostname" version = "0.0.4" dependencies = [ - "clap", - "hostname", - "libc", - "uucore", - "uucore_procs", - "winapi 0.3.9", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hostname 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_id" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_install" version = "0.0.4" dependencies = [ - "clap", - "file_diff", - "filetime", - "libc", - "time", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "file_diff 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_join" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_kill" version = "0.0.4" dependencies = [ - "libc", - "uucore", - "uucore_procs", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_link" version = "0.0.4" dependencies = [ - "libc", - "uucore", - "uucore_procs", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_ln" version = "0.0.4" dependencies = [ - "clap", - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_logname" version = "0.0.4" dependencies = [ - "libc", - "uucore", - "uucore_procs", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_ls" version = "0.0.4" dependencies = [ - "atty", - "clap", - "lazy_static", - "number_prefix", - "term_grid", - "termsize", - "time", - "unicode-width", - "uucore", - "uucore_procs", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term_grid 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "termsize 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_mkdir" version = "0.0.4" dependencies = [ - "clap", - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_mkfifo" version = "0.0.4" dependencies = [ - "clap", - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_mknod" version = "0.0.4" dependencies = [ - "getopts", - "libc", - "uucore", - "uucore_procs", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_mktemp" version = "0.0.4" dependencies = [ - "clap", - "rand 0.5.6", - "tempfile", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_more" version = "0.0.4" dependencies = [ - "getopts", - "nix 0.13.1", - "redox_syscall 0.1.57", - "redox_termios", - "uucore", - "uucore_procs", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_mv" version = "0.0.4" dependencies = [ - "clap", - "fs_extra", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_nice" version = "0.0.4" dependencies = [ - "clap", - "libc", - "nix 0.13.1", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_nl" version = "0.0.4" dependencies = [ - "aho-corasick", - "clap", - "libc", - "memchr 2.3.4", - "regex", - "regex-syntax", - "uucore", - "uucore_procs", + "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_nohup" version = "0.0.4" dependencies = [ - "clap", - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_nproc" version = "0.0.4" dependencies = [ - "clap", - "libc", - "num_cpus", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_numfmt" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_od" version = "0.0.4" dependencies = [ - "byteorder", - "clap", - "half", - "libc", - "uucore", - "uucore_procs", + "byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_paste" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_pathchk" version = "0.0.4" dependencies = [ - "clap", - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_pinky" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_printenv" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_printf" version = "0.0.4" dependencies = [ - "itertools 0.8.2", - "uucore", - "uucore_procs", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_ptx" version = "0.0.4" dependencies = [ - "aho-corasick", - "clap", - "libc", - "memchr 2.3.4", - "regex", - "regex-syntax", - "uucore", - "uucore_procs", + "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_pwd" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_readlink" version = "0.0.4" dependencies = [ - "clap", - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_realpath" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_relpath" version = "0.0.4" dependencies = [ - "getopts", - "uucore", - "uucore_procs", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_rm" version = "0.0.4" dependencies = [ - "clap", - "remove_dir_all", - "uucore", - "uucore_procs", - "walkdir", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_rmdir" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_seq" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_shred" version = "0.0.4" dependencies = [ - "filetime", - "getopts", - "libc", - "rand 0.5.6", - "time", - "uucore", - "uucore_procs", + "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_shuf" version = "0.0.4" dependencies = [ - "clap", - "rand 0.5.6", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_sleep" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_sort" version = "0.0.4" dependencies = [ - "clap", - "itertools 0.8.2", - "rand 0.7.3", - "semver", - "twox-hash", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "twox-hash 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_split" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_stat" version = "0.0.4" dependencies = [ - "clap", - "time", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_stdbuf" version = "0.0.4" dependencies = [ - "getopts", - "tempfile", - "uu_stdbuf_libstdbuf", - "uucore", - "uucore_procs", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uu_stdbuf_libstdbuf 0.0.4", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_stdbuf_libstdbuf" version = "0.0.4" dependencies = [ - "cpp", - "cpp_build", - "libc", - "uucore", - "uucore_procs", + "cpp 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_build 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] @@ -2278,394 +2152,556 @@ dependencies = [ name = "uu_sync" version = "0.0.4" dependencies = [ - "clap", - "libc", - "uucore", - "uucore_procs", - "winapi 0.3.9", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_tac" version = "0.0.4" dependencies = [ - "getopts", - "uucore", - "uucore_procs", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_tail" version = "0.0.4" dependencies = [ - "clap", - "libc", - "redox_syscall 0.1.57", - "uucore", - "uucore_procs", - "winapi 0.3.9", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_tee" version = "0.0.4" dependencies = [ - "clap", - "libc", - "retain_mut", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "retain_mut 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_test" version = "0.0.4" dependencies = [ - "libc", - "redox_syscall 0.1.57", - "uucore", - "uucore_procs", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_timeout" version = "0.0.4" dependencies = [ - "getopts", - "libc", - "uucore", - "uucore_procs", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_touch" version = "0.0.4" dependencies = [ - "clap", - "filetime", - "time", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_tr" version = "0.0.4" dependencies = [ - "bit-set", - "clap", - "fnv", - "uucore", - "uucore_procs", + "bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_true" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_truncate" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_tsort" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_tty" version = "0.0.4" dependencies = [ - "getopts", - "libc", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_uname" version = "0.0.4" dependencies = [ - "clap", - "platform-info", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_unexpand" version = "0.0.4" dependencies = [ - "clap", - "unicode-width", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_uniq" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_unlink" version = "0.0.4" dependencies = [ - "getopts", - "libc", - "uucore", - "uucore_procs", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_uptime" version = "0.0.4" dependencies = [ - "chrono", - "clap", - "uucore", - "uucore_procs", + "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_users" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_wc" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_who" version = "0.0.4" dependencies = [ - "uucore", - "uucore_procs", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uu_whoami" version = "0.0.4" dependencies = [ - "advapi32-sys", - "clap", - "uucore", - "uucore_procs", - "winapi 0.3.9", + "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uu_yes" version = "0.0.4" dependencies = [ - "clap", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] name = "uucore" version = "0.0.7" dependencies = [ - "data-encoding", - "dunce", - "getopts", - "lazy_static", - "libc", - "nix 0.13.1", - "platform-info", - "termion", - "thiserror", - "time", - "wild", + "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "dunce 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "wild 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uucore_procs" version = "0.0.5" dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn", + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "vec_map" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "walkdir" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ - "same-file", - "winapi 0.3.9", - "winapi-util", + "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe" dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen-macro", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3" dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote 1.0.9", - "syn", - "wasm-bindgen-shared", + "bumpalo 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b" dependencies = [ - "quote 1.0.9", - "wasm-bindgen-macro-support", + "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d" dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa" [[package]] name = "web-sys" version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310" dependencies = [ - "js-sys", - "wasm-bindgen", + "js-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wild" version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020" dependencies = [ - "glob 0.3.0", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "xattr" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" dependencies = [ - "libc", + "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", ] + +[metadata] +"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" +"checksum aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +"checksum autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +"checksum bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +"checksum bit-vec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" +"checksum bstr 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" +"checksum bumpalo 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" +"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" +"checksum byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" +"checksum cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +"checksum chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" +"checksum clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)" = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" +"checksum cpp 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4875a08600be48dcc9cb6ee07f104a3e0752e95184dede6a30044d6480bf50e8" +"checksum cpp_build 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c47531e7e09532ad4827098729794f5e1a5b1c2ccbb5e295498d2e7ab451c445" +"checksum cpp_common 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79e39149a7943affa02f5b6e347ca2840a129cc78d5883ee229f0f1c4027d628" +"checksum cpp_common 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "df78ad28e5fe814285016779fb3d3b874520c799a847e6190bf2b834cc4ff283" +"checksum cpp_macros 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f93a21e618c10abc84ebb63ffa5952e1f7a4568b8141d542d5ef860e4a8fc25" +"checksum cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8cd649bf5b3804d92fe12a60c7698f5a538a6033ed8a668bf5241d4d4f1644e" +"checksum cpp_synmap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "897e4f9cdbe2874edd3ffe53718ee5d8b89e2a970057b2c93d3214104f2e90b6" +"checksum cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc8da5694233b646150c785118f77835ad0a49680c7f312a10ef30957c67b6d" +"checksum criterion 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" +"checksum criterion-plot 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" +"checksum crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +"checksum crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +"checksum crossbeam-epoch 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" +"checksum crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" +"checksum csv 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" +"checksum csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" +"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" +"checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" +"checksum dunce 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b2641c4a7c0c4101df53ea572bffdc561c146f6c2eb09e4df02bc4811e3feeb4" +"checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +"checksum file_diff 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" +"checksum filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" +"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +"checksum fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2297fb0e3ea512e380da24b52dca3924028f59df5e3a17a18f81d8349ca7ebe" +"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +"checksum getrandom 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +"checksum half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" +"checksum hermit-abi 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +"checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" +"checksum hostname 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +"checksum if_rust_version 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46dbcb333e86939721589d25a3557e180b52778cb33c7fdfe9e0158ff790d5ec" +"checksum ioctl-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e2c4b26352496eaaa8ca7cfa9bd99e93419d3f7983dc6e99c2a35fe9e33504a" +"checksum itertools 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" +"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" +"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +"checksum itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +"checksum js-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +"checksum libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)" = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" +"checksum log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +"checksum match_cfg 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +"checksum md5 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48" +"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" +"checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +"checksum memoffset 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" +"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" +"checksum nix 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" +"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +"checksum num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +"checksum num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +"checksum number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" +"checksum onig 4.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8518fcb2b1b8c2f45f0ad499df4fda6087fc3475ca69a185c173b8315d2fb383" +"checksum onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388410bf5fa341f10e58e6db3975f4bea1ac30247dd79d37a9e5ced3cb4cc3b0" +"checksum oorandom 11.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +"checksum paste 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" +"checksum paste-impl 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" +"checksum pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +"checksum platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ea9cd21d89bffb387b6c7363d23bead0807be9de676c671b474dd29e7436d3" +"checksum plotters 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" +"checksum plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" +"checksum plotters-svg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" +"checksum ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +"checksum proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +"checksum proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +"checksum quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +"checksum rayon 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +"checksum rayon-core 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +"checksum redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +"checksum redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" +"checksum regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" +"checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" +"checksum regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)" = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" +"checksum remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +"checksum retain_mut 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53552c6c49e1e13f1a203ef0080ab3bbef0beb570a528993e83df057a9d9bba1" +"checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)" = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +"checksum serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" +"checksum serde_derive 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)" = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +"checksum serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)" = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" +"checksum sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0" +"checksum smallvec 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +"checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)" = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" +"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +"checksum term_grid 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "230d3e804faaed5a39b08319efb797783df2fd9671b39b7596490cb486d702cf" +"checksum term_size 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" +"checksum termion 1.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" +"checksum termsize 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "5e86d824a8e90f342ad3ef4bd51ef7119a9b681b0cc9f8ee7b2852f02ccd2517" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" +"checksum thiserror-impl 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" +"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" +"checksum tinytemplate 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +"checksum twox-hash 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" +"checksum typenum 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +"checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" +"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +"checksum unindent 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" +"checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" +"checksum users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486" +"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +"checksum wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe" +"checksum wasm-bindgen-backend 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3" +"checksum wasm-bindgen-macro 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b" +"checksum wasm-bindgen-macro-support 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d" +"checksum wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa" +"checksum web-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310" +"checksum wild 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" From d88de3c6a6f1b3113802d4eec120969566b64849 Mon Sep 17 00:00:00 2001 From: Raymond Wang <61680028+RazB924@users.noreply.github.com> Date: Tue, 30 Mar 2021 01:46:48 +1030 Subject: [PATCH 040/132] tr: more explicit flag names (#1966) --- src/uu/tr/src/tr.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index ff1bb49d5..b94b11b9d 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -225,10 +225,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .arg(Arg::with_name(options::SETS).multiple(true)) .get_matches_from(args); - let dflag = matches.is_present(options::DELETE); - let cflag = matches.is_present(options::COMPLEMENT); - let sflag = matches.is_present(options::SQUEEZE); - let tflag = matches.is_present(options::TRUNCATE); + let delete_flag = matches.is_present(options::DELETE); + let complement_flag = matches.is_present(options::COMPLEMENT); + let squeeze_flag = matches.is_present(options::SQUEEZE); + let truncate_flag = matches.is_present(options::TRUNCATE); let sets: Vec = match matches.values_of(options::SETS) { Some(v) => v.map(|v| v.to_string()).collect(), @@ -243,7 +243,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { return 1; } - if !(dflag || sflag) && sets.len() < 2 { + if !(delete_flag || squeeze_flag) && sets.len() < 2 { show_error!( "missing operand after ‘{}’\nTry `{} --help` for more information.", sets[0], @@ -252,7 +252,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { return 1; } - if cflag && !dflag && !sflag { + if complement_flag && !delete_flag && !squeeze_flag { show_error!("-c is only supported with -d or -s"); return 1; } @@ -264,21 +264,21 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let mut buffered_stdout = BufWriter::new(locked_stdout); let set1 = ExpandSet::new(sets[0].as_ref()); - if dflag { - if sflag { + if delete_flag { + if squeeze_flag { let set2 = ExpandSet::new(sets[1].as_ref()); - let op = DeleteAndSqueezeOperation::new(set1, set2, cflag); + let op = DeleteAndSqueezeOperation::new(set1, set2, complement_flag); translate_input(&mut locked_stdin, &mut buffered_stdout, op); } else { - let op = DeleteOperation::new(set1, cflag); + let op = DeleteOperation::new(set1, complement_flag); translate_input(&mut locked_stdin, &mut buffered_stdout, op); } - } else if sflag { - let op = SqueezeOperation::new(set1, cflag); + } else if squeeze_flag { + let op = SqueezeOperation::new(set1, complement_flag); translate_input(&mut locked_stdin, &mut buffered_stdout, op); } else { let mut set2 = ExpandSet::new(sets[1].as_ref()); - let op = TranslateOperation::new(set1, &mut set2, tflag); + let op = TranslateOperation::new(set1, &mut set2, truncate_flag); translate_input(&mut locked_stdin, &mut buffered_stdout, op) } From 25df51a52580ad417d24fcb1862c17cc7b1853d7 Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Mon, 29 Mar 2021 19:44:42 +0300 Subject: [PATCH 041/132] fix(cksum): check metadata of the path (#1951) * fix: check metadata of the path * chore: use existing path --- src/uu/cksum/src/cksum.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index bc71a2d97..b7659ea62 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -140,7 +140,20 @@ fn cksum(fname: &str) -> io::Result<(u32, usize)> { let mut rd: Box = match fname { "-" => Box::new(stdin()), _ => { - file = File::open(&Path::new(fname))?; + let path = &Path::new(fname); + if path.is_dir() { + return Err(std::io::Error::new( + io::ErrorKind::InvalidInput, + "Is a directory", + )); + }; + if !path.metadata().is_ok() { + return Err(std::io::Error::new( + io::ErrorKind::NotFound, + "No such file or directory", + )); + }; + file = File::open(&path)?; Box::new(BufReader::new(file)) } }; From 2647a72e9ec77270070b169863e21714e988f4f8 Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Mon, 29 Mar 2021 22:07:09 +0200 Subject: [PATCH 042/132] chmod: fixed behavior for dangling symlinks (#1775) --- src/uu/chmod/src/chmod.rs | 38 +++++++----- tests/by-util/test_chmod.rs | 120 ++++++++++++++++++++++++++++++------ 2 files changed, 123 insertions(+), 35 deletions(-) diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index 819c674a0..d9d8c8cf2 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -206,7 +206,17 @@ impl Chmoder { let filename = &filename[..]; let file = Path::new(filename); if !file.exists() { - show_error!("no such file or directory '{}'", filename); + if is_symlink(file) { + println!( + "failed to change mode of '{}' from 0000 (---------) to 0000 (---------)", + filename + ); + if !self.quiet { + show_error!("cannot operate on dangling symlink '{}'", filename); + } + } else { + show_error!("cannot access '{}': No such file or directory", filename); + } return Err(1); } if self.recursive && self.preserve_root && filename == "/" { @@ -240,18 +250,16 @@ impl Chmoder { let mut fperm = match fs::metadata(file) { Ok(meta) => meta.mode() & 0o7777, Err(err) => { - if !self.quiet { - if is_symlink(file) { - if self.verbose { - show_info!( - "neither symbolic link '{}' nor referent has been changed", - file.display() - ); - } - return Ok(()); - } else { - show_error!("{}: '{}'", err, file.display()); + if is_symlink(file) { + if self.verbose { + println!( + "neither symbolic link '{}' nor referent has been changed", + file.display() + ); } + return Ok(()); + } else { + show_error!("{}: '{}'", err, file.display()); } return Err(1); } @@ -291,11 +299,11 @@ impl Chmoder { fn change_file(&self, fperm: u32, mode: u32, file: &Path) -> Result<(), i32> { if fperm == mode { if self.verbose && !self.changes { - show_info!( - "mode of '{}' retained as {:o} ({})", + println!( + "mode of '{}' retained as {:04o} ({})", file.display(), fperm, - display_permissions_unix(fperm) + display_permissions_unix(fperm), ); } Ok(()) diff --git a/tests/by-util/test_chmod.rs b/tests/by-util/test_chmod.rs index 3a53202fc..78fee462d 100644 --- a/tests/by-util/test_chmod.rs +++ b/tests/by-util/test_chmod.rs @@ -329,10 +329,9 @@ fn test_chmod_non_existing_file() { .arg("-r,a+w") .arg("dont-exist") .fails(); - assert_eq!( - result.stderr, - "chmod: error: no such file or directory 'dont-exist'\n" - ); + assert!(result + .stderr + .contains("cannot access 'dont-exist': No such file or directory")); } #[test] @@ -351,30 +350,111 @@ fn test_chmod_preserve_root() { #[test] fn test_chmod_symlink_non_existing_file() { - let (at, mut ucmd) = at_and_ucmd!(); - at.symlink_file("/non-existing", "test-long.link"); + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; - let _result = ucmd - .arg("-R") + let non_existing = "test_chmod_symlink_non_existing_file"; + let test_symlink = "test_chmod_symlink_non_existing_file_symlink"; + let expected_stdout = &format!( + "failed to change mode of '{}' from 0000 (---------) to 0000 (---------)", + test_symlink + ); + let expected_stderr = &format!("cannot operate on dangling symlink '{}'", test_symlink); + + at.symlink_file(non_existing, test_symlink); + let mut result; + + // this cannot succeed since the symbolic link dangles + result = scene.ucmd().arg("755").arg("-v").arg(test_symlink).fails(); + + println!("stdout = {:?}", result.stdout); + println!("stderr = {:?}", result.stderr); + + assert!(result.stdout.contains(expected_stdout)); + assert!(result.stderr.contains(expected_stderr)); + assert_eq!(result.code, Some(1)); + + // this should be the same than with just '-v' but without stderr + result = scene + .ucmd() .arg("755") .arg("-v") - .arg("test-long.link") + .arg("-f") + .arg(test_symlink) .fails(); + + println!("stdout = {:?}", result.stdout); + println!("stderr = {:?}", result.stderr); + + assert!(result.stdout.contains(expected_stdout)); + assert!(result.stderr.is_empty()); + assert_eq!(result.code, Some(1)); } #[test] -fn test_chmod_symlink_non_existing_recursive() { - let (at, mut ucmd) = at_and_ucmd!(); - at.mkdir("tmp"); - at.symlink_file("/non-existing", "tmp/test-long.link"); +fn test_chmod_symlink_non_existing_file_recursive() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; - let result = ucmd.arg("-R").arg("755").arg("-v").arg("tmp").succeeds(); - // it should be a success - println!("stderr {}", result.stderr); - println!("stdout {}", result.stdout); - assert!(result - .stderr - .contains("neither symbolic link 'tmp/test-long.link' nor referent has been changed")); + let non_existing = "test_chmod_symlink_non_existing_file_recursive"; + let test_symlink = "test_chmod_symlink_non_existing_file_recursive_symlink"; + let test_directory = "test_chmod_symlink_non_existing_file_directory"; + + at.mkdir(test_directory); + at.symlink_file( + non_existing, + &format!("{}/{}", test_directory, test_symlink), + ); + let mut result; + + // this should succeed + result = scene + .ucmd() + .arg("-R") + .arg("755") + .arg(test_directory) + .succeeds(); + assert_eq!(result.code, Some(0)); + assert!(result.stdout.is_empty()); + assert!(result.stderr.is_empty()); + + let expected_stdout = &format!( + "mode of '{}' retained as 0755 (rwxr-xr-x)\nneither symbolic link '{}/{}' nor referent has been changed", + test_directory, test_directory, test_symlink + ); + + // '-v': this should succeed without stderr + result = scene + .ucmd() + .arg("-R") + .arg("-v") + .arg("755") + .arg(test_directory) + .succeeds(); + + println!("stdout = {:?}", result.stdout); + println!("stderr = {:?}", result.stderr); + + assert!(result.stdout.contains(expected_stdout)); + assert!(result.stderr.is_empty()); + assert_eq!(result.code, Some(0)); + + // '-vf': this should be the same than with just '-v' + result = scene + .ucmd() + .arg("-R") + .arg("-v") + .arg("-f") + .arg("755") + .arg(test_directory) + .succeeds(); + + println!("stdout = {:?}", result.stdout); + println!("stderr = {:?}", result.stderr); + + assert!(result.stdout.contains(expected_stdout)); + assert!(result.stderr.is_empty()); + assert_eq!(result.code, Some(0)); } #[test] From 902476980820ed936d7028fba6eaced970f1697f Mon Sep 17 00:00:00 2001 From: Sivachandran Date: Tue, 30 Mar 2021 12:03:24 +0530 Subject: [PATCH 043/132] Add instructions for code coverage report generation (#1963) --- DEVELOPER_INSTRUCTIONS.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 DEVELOPER_INSTRUCTIONS.md diff --git a/DEVELOPER_INSTRUCTIONS.md b/DEVELOPER_INSTRUCTIONS.md new file mode 100644 index 000000000..be6373409 --- /dev/null +++ b/DEVELOPER_INSTRUCTIONS.md @@ -0,0 +1,26 @@ +Code Coverage Report Generation +--------------------------------- + +Code coverage report can be generated using [grcov](https://github.com/mozilla/grcov). + +### Using Nightly Rust + +To generate [gcov-based](https://github.com/mozilla/grcov#example-how-to-generate-gcda-files-for-cc) coverage report + +```bash +$ export CARGO_INCREMENTAL=0 +$ export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" +$ export RUSTDOCFLAGS="-Cpanic=abort" +$ cargo build # e.g., --features feat_os_unix +$ cargo test # e.g., --features feat_os_unix test_pathchk +$ grcov . -s . --binary-path ./target/debug/ -t html --branch --ignore-not-existing --ignore build.rs --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?\#\[derive\()" -o ./target/debug/coverage/ +$ # open target/debug/coverage/index.html in browser +``` + +if changes are not reflected in the report then run `cargo clean` and run the above commands. + +### Using Stable Rust + +If you are using stable version of Rust that doesn't enable code coverage instrumentation by default +then add `-Z-Zinstrument-coverage` flag to `RUSTFLAGS` env variable specified above. + From 775682508a479512dfb7269c97e82258170d3717 Mon Sep 17 00:00:00 2001 From: Kourosh Date: Tue, 30 Mar 2021 23:09:58 +0430 Subject: [PATCH 044/132] more: move from getopts to clap (#1962) --- src/uu/more/Cargo.toml | 2 +- src/uu/more/src/more.rs | 85 +++++++++++++++-------------------------- 2 files changed, 31 insertions(+), 56 deletions(-) diff --git a/src/uu/more/Cargo.toml b/src/uu/more/Cargo.toml index acd9378b2..243462232 100644 --- a/src/uu/more/Cargo.toml +++ b/src/uu/more/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/more.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" uucore = { version = ">=0.0.7", package = "uucore", path = "../../uucore" } uucore_procs = { version = ">=0.0.5", package = "uucore_procs", path = "../../uucore_procs" } diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 524b0fbc4..981b5f502 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -10,9 +10,8 @@ #[macro_use] extern crate uucore; -use getopts::Options; use std::fs::File; -use std::io::{stdout, Read, Write}; +use std::io::{stdin, stdout, BufRead, BufReader, Read, Write}; #[cfg(all(unix, not(target_os = "fuchsia")))] extern crate nix; @@ -24,70 +23,44 @@ extern crate redox_termios; #[cfg(target_os = "redox")] extern crate syscall; -#[derive(Clone, Eq, PartialEq)] -pub enum Mode { - More, - Help, - Version, +use clap::{App, Arg, ArgMatches}; + +static VERSION: &str = env!("CARGO_PKG_VERSION"); +static ABOUT: &str = "A file perusal filter for CRT viewing."; + +mod options { + pub const FILE: &str = "file"; } -static NAME: &str = "more"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); +fn get_usage() -> String { + format!("{} [options] ...", executable!()) +} pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); + let usage = get_usage(); - let mut opts = Options::new(); + let matches = App::new(executable!()) + .version(VERSION) + .usage(&usage[..]) + .about(ABOUT) + .arg( + Arg::with_name(options::FILE) + .number_of_values(1) + .multiple(true), + ) + .get_matches_from(args); // FixME: fail without panic for now; but `more` should work with no arguments (ie, for piped input) - if args.len() < 2 { - println!("{}: incorrect usage", args[0]); + if let None | Some("-") = matches.value_of(options::FILE) { + println!("{}: incorrect usage", executable!()); return 1; } - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("v", "version", "output version information and exit"); - - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(e) => { - show_error!("{}", e); - panic!() - } - }; - let usage = opts.usage("more TARGET."); - let mode = if matches.opt_present("version") { - Mode::Version - } else if matches.opt_present("help") { - Mode::Help - } else { - Mode::More - }; - - match mode { - Mode::More => more(matches), - Mode::Help => help(&usage), - Mode::Version => version(), - } + more(matches); 0 } -fn version() { - println!("{} {}", NAME, VERSION); -} - -fn help(usage: &str) { - let msg = format!( - "{0} {1}\n\n\ - Usage: {0} TARGET\n \ - \n\ - {2}", - NAME, VERSION, usage - ); - println!("{}", msg); -} - #[cfg(all(unix, not(target_os = "fuchsia")))] fn setup_term() -> termios::Termios { let mut term = termios::tcgetattr(0).unwrap(); @@ -138,9 +111,11 @@ fn reset_term(term: &mut redox_termios::Termios) { let _ = syscall::close(fd); } -fn more(matches: getopts::Matches) { - let files = matches.free; - let mut f = File::open(files.first().unwrap()).unwrap(); +fn more(matches: ArgMatches) { + let mut f: Box = match matches.value_of(options::FILE) { + None | Some("-") => Box::new(BufReader::new(stdin())), + Some(filename) => Box::new(BufReader::new(File::open(filename).unwrap())), + }; let mut buffer = [0; 1024]; let mut term = setup_term(); From 3e06882acce7a952e080b79f5c919d2222c9073d Mon Sep 17 00:00:00 2001 From: Neculai Balaban Date: Tue, 30 Mar 2021 21:51:11 +0300 Subject: [PATCH 045/132] loosely document supported architectures (#1899) - add script to generate a table of bins that compile - add section in README --- README.md | 28 +++++ docs/compiles_table.csv | 21 ++++ docs/compiles_table.py | 234 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+) create mode 100644 docs/compiles_table.csv create mode 100644 docs/compiles_table.py diff --git a/README.md b/README.md index 7433f49e6..b6d265278 100644 --- a/README.md +++ b/README.md @@ -372,6 +372,34 @@ Utilities | whoami | | | | yes | | | +Targets that compile +------- + +This is an auto-generated table showing which binaries compile for each target-triple. Note that this **does not** indicate that they are fully implemented, or that the tests pass. + +|######OS######|###ARCH####|arch|base32|base64|basename|cat|chgrp|chmod|chown|chroot|cksum|comm|cp|csplit|cut|date|df|dircolors|dirname|du|echo|env|expand|expr|factor|false|fmt|fold|groups|hashsum|head|hostid|hostname|id|install|join|kill|link|ln|logname|ls|mkdir|mkfifo|mknod|mktemp|more|mv|nice|nl|nohup|nproc|numfmt|od|paste|pathchk|pinky|printenv|printf|ptx|pwd|readlink|realpath|relpath|rm|rmdir|seq|shred|shuf|sleep|sort|split|stat|stdbuf|sum|sync|tac|tail|tee|test|timeout|touch|tr|true|truncate|tsort|tty|uname|unexpand|uniq|unlink|uptime|users|wc|who|whoami|yes| +|--------------|-----------|----|------|------|--------|---|-----|-----|-----|------|-----|----|--|------|---|----|--|---------|-------|--|----|---|------|----|------|-----|---|----|------|-------|----|------|--------|--|-------|----|----|----|--|-------|--|-----|------|-----|------|----|--|----|--|-----|-----|------|--|-----|-------|-----|--------|------|---|---|--------|--------|-------|--|-----|---|-----|----|-----|----|-----|----|------|---|----|---|----|---|----|-------|-----|--|----|--------|-----|---|-----|--------|----|------|------|-----|--|---|------|---| +|linux-gnu|aarch64|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| +|linux-gnu|i686|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| +|linux-gnu|powerpc64|y|y|y|y|y|y|y|y|y|y|y| |y|y|y|y|y|y|y|y|y|y| |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| +|linux-gnu|riscv64gc| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +|linux-gnu|x86_64|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| +|windows-msvc|aarch64|y|y|y|y|y| | | | |y|y|y|y|y|y|y|y|y| |y|y|y| |y|y|y|y| |y|y|y|y| | |y| |y|y|y| |y| | |y|y|y| |y| |y|y|y|y| | |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| | |y|y|y|y|y|y| |y|y|y|y|y| |y|y|y| |y| |y| | |y| +|windows-gnu|i686|y|y|y|y|y| | | | |y|y|y|y|y|y|y|y|y| |y|y|y| |y|y|y|y| |y|y|y|y| | |y| |y|y|y|y|y| | |y|y|y| |y| |y|y|y|y| | |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| | |y|y|y|y|y|y| |y|y|y|y|y|y|y|y|y| |y| |y| |y|y| +|windows-msvc|i686|y|y|y|y|y| | | | |y|y|y|y|y|y|y|y|y| |y|y|y| |y|y|y|y| |y|y|y|y| | |y| |y|y|y|y|y| | |y|y|y| |y| |y|y|y|y| | |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| | |y|y|y|y|y|y| |y|y|y|y|y| |y|y|y| |y| |y| |y|y| +|windows-gnu|x86_64|y|y|y|y|y| | | | |y|y|y|y|y|y|y|y|y| |y|y|y| |y|y|y|y| |y|y|y|y| | |y| |y|y|y|y|y| | |y|y|y| |y| |y|y|y|y| | |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| | |y|y|y|y|y|y| |y|y|y|y|y|y|y|y|y| |y| |y| |y|y| +|windows-msvc|x86_64|y|y|y|y|y| | | | |y|y|y|y|y|y|y|y|y| |y|y|y| |y|y|y|y| |y|y|y|y| | |y| |y|y|y|y|y| | |y|y|y| |y| |y|y|y|y| | |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| | |y|y|y|y|y|y| |y|y|y|y|y| |y|y|y| |y| |y| |y|y| +|apple MacOS|x86_64|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| +|freebsd|x86_64|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| +|netbsd|x86_64|y|y|y|y|y|y|y|y| |y|y|y|y|y|y| |y|y|y|y|y|y| |y|y|y|y|y|y|y|y|y| |y|y| |y|y|y|y|y|y|y|y|y|y|y|y| |y|y|y|y|y| |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| |y|y|y|y|y|y| |y|y|y| | |y| |y|y| +|android|aarch64|y|y|y|y|y|y|y|y| |y|y|y|y|y|y| |y|y|y|y|y|y| |y|y|y|y|y|y|y|y|y| |y|y| |y|y|y|y|y|y|y|y|y|y|y|y| |y|y|y|y|y| |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| |y|y| |y|y|y|y| |y|y|y|y|y|y| |y|y|y| | |y| |y|y| +|android|x86_64|y|y|y|y|y|y|y|y| |y|y|y|y|y|y| |y|y|y|y|y|y| |y|y|y|y|y|y|y|y|y| |y|y| |y|y|y|y|y|y|y|y|y|y|y|y| |y|y|y|y|y| |y|y|y|y|y|y|y|y|y|y|y|y|y|y|y| |y|y| |y|y|y|y| |y|y|y|y|y|y| |y|y|y| | |y| |y|y| +|solaris|x86_64| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +|wasi|wasm32| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +|redox|x86_64| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +|fuchsia|aarch64| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +|fuchsia|x86_64| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + License ------- diff --git a/docs/compiles_table.csv b/docs/compiles_table.csv new file mode 100644 index 000000000..6da110132 --- /dev/null +++ b/docs/compiles_table.csv @@ -0,0 +1,21 @@ +target,arch,base32,base64,basename,cat,chgrp,chmod,chown,chroot,cksum,comm,cp,csplit,cut,date,df,dircolors,dirname,du,echo,env,expand,expr,factor,false,fmt,fold,groups,hashsum,head,hostid,hostname,id,install,join,kill,link,ln,logname,ls,mkdir,mkfifo,mknod,mktemp,more,mv,nice,nl,nohup,nproc,numfmt,od,paste,pathchk,pinky,printenv,printf,ptx,pwd,readlink,realpath,relpath,rm,rmdir,seq,shred,shuf,sleep,sort,split,stat,stdbuf,sum,sync,tac,tail,tee,test,timeout,touch,tr,true,truncate,tsort,tty,uname,unexpand,uniq,unlink,uptime,users,wc,who,whoami,yes +aarch64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +i686-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +powerpc64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +riscv64gc-unknown-linux-gnu,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +x86_64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +aarch64-pc-windows-msvc,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,101,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,101,0,101,0,101,101,0 +i686-pc-windows-gnu,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,101,0,101,0,0 +i686-pc-windows-msvc,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,101,0,101,0,101,0,0 +x86_64-pc-windows-gnu,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,101,0,101,0,0 +x86_64-pc-windows-msvc,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,101,0,101,0,101,0,0 +x86_64-apple-darwin,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +x86_64-unknown-freebsd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +x86_64-unknown-netbsd,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,101,101,0,101,0,0 +aarch64-linux-android,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,101,101,0,101,0,0 +x86_64-linux-android,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,101,101,0,101,0,0 +x86_64-sun-solaris,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +wasm32-wasi,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +x86_64-unknown-redox,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +aarch64-fuchsia,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +x86_64-fuchsia,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 diff --git a/docs/compiles_table.py b/docs/compiles_table.py new file mode 100644 index 000000000..0cbfdf0e9 --- /dev/null +++ b/docs/compiles_table.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 +import multiprocessing +import subprocess +import argparse +import csv +import sys +from collections import defaultdict +from pathlib import Path + +# third party dependencies +from tqdm import tqdm + +BINS_PATH=Path("../src/uu") +CACHE_PATH=Path("compiles_table.csv") +TARGETS = [ + # Linux - GNU + "aarch64-unknown-linux-gnu", + "i686-unknown-linux-gnu", + "powerpc64-unknown-linux-gnu", + "riscv64gc-unknown-linux-gnu", + "x86_64-unknown-linux-gnu", + # Windows + "aarch64-pc-windows-msvc", + "i686-pc-windows-gnu", + "i686-pc-windows-msvc", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + # Apple + "x86_64-apple-darwin", + "aarch64-apple-ios", + "x86_64-apple-ios", + # BSDs + "x86_64-unknown-freebsd", + "x86_64-unknown-netbsd", + # Android + "aarch64-linux-android", + "x86_64-linux-android", + # Solaris + "x86_64-sun-solaris", + # WASM + "wasm32-wasi", + # Redox + "x86_64-unknown-redox", + # Fuchsia + "aarch64-fuchsia", + "x86_64-fuchsia", +] + +class Target(str): + def __new__(cls, content): + obj = super().__new__(cls, content) + obj.arch, obj.platfrom, obj.os = Target.parse(content) + return obj + + @staticmethod + def parse(s): + elem = s.split("-") + if len(elem) == 2: + arch, platform, os = elem[0], "n/a", elem[1] + else: + arch, platform, os = elem[0], elem[1], "-".join(elem[2:]) + if os == "ios": + os = "apple IOS" + if os == "darwin": + os = "apple MacOS" + return (arch, platform, os) + + @staticmethod + def get_heading(): + return ["OS", "ARCH"] + + def get_row_heading(self): + return [self.os, self.arch] + + def requires_nightly(self): + return "redox" in self + + # Perform the 'it-compiles' check + def check(self, binary): + if self.requires_nightly(): + args = [ "cargo", "+nightly", "check", + "-p", f"uu_{binary}", "--bin", binary, + f"--target={self}"] + else: + args = ["cargo", "check", + "-p", f"uu_{binary}", "--bin", binary, + f"--target={self}"] + + res = subprocess.run(args, capture_output=True) + return res.returncode + + # Validate that the dependencies for running this target are met + def is_installed(self): + # check IOS sdk is installed, raise exception otherwise + if "ios" in self: + res = subprocess.run(["which", "xcrun"], capture_output=True) + if len(res.stdout) == 0: + raise Exception("Error: IOS sdk does not seem to be installed. Please do that manually") + if not self.requires_nightly(): + # check std toolchains are installed + toolchains = subprocess.run(["rustup", "target", "list"], capture_output=True) + toolchains = toolchains.stdout.decode('utf-8').split("\n") + if "installed" not in next(filter(lambda x: self in x, toolchains)): + raise Exception(f"Error: the {t} target is not installed. Please do that manually") + else: + # check nightly toolchains are installed + toolchains = subprocess.run(["rustup", "+nightly", "target", "list"], capture_output=True) + toolchains = toolchains.stdout.decode('utf-8').split("\n") + if "installed" not in next(filter(lambda x: self in x, toolchains)): + raise Exception(f"Error: the {t} nightly target is not installed. Please do that manually") + return True + +def install_targets(): + cmd = ["rustup", "target", "add"] + TARGETS + print(" ".join(cmd)) + ret = subprocess.run(cmd) + assert(ret.returncode == 0) + +def get_all_bins(): + bins = map(lambda x: x.name, BINS_PATH.iterdir()) + return sorted(list(bins)) + +def get_targets(selection): + if "all" in selection: + return list(map(Target, TARGETS)) + else: + # preserve the same order as in TARGETS + return list(map(Target, filter(lambda x: x in selection, TARGETS))) + +def test_helper(tup): + bin, target = tup + retcode = target.check(bin) + return (target, bin, retcode) + +def test_all_targets(targets, bins): + pool = multiprocessing.Pool() + inputs = [(b, t) for b in bins for t in targets] + + outputs = list(tqdm(pool.imap(test_helper, inputs), total=len(inputs))) + + table = defaultdict(dict) + for (t, b, r) in outputs: + table[t][b] = r + return table + +def save_csv(file, table): + targets = get_targets(table.keys()) # preserve order in CSV + bins = list(list(table.values())[0].keys()) + with open(file, "w") as csvfile: + header = ["target"] + bins + writer = csv.DictWriter(csvfile, fieldnames=header) + writer.writeheader() + for t in targets: + d = {"target" : t} + d.update(table[t]) + writer.writerow(d) + +def load_csv(file): + table = {} + cols = [] + rows = [] + with open(file, "r") as csvfile: + reader = csv.DictReader(csvfile) + cols = list(filter(lambda x: x!="target", reader.fieldnames)) + for row in reader: + t = Target(row["target"]) + rows += [t] + del row["target"] + table[t] = dict([k, int(v)] for k, v in row.items()) + return (table, rows, cols) + +def merge_tables(old, new): + from copy import deepcopy + tmp = deepcopy(old) + tmp.update(deepcopy(new)) + return tmp + +def render_md(fd, table, headings: str, row_headings: Target): + def print_row(lst, lens=[]): + lens = lens + [0] * (len(lst) - len(lens)) + for e, l in zip(lst, lens): + fmt = '|{}' if l == 0 else '|{:>%s}' % len(header[0]) + fd.write(fmt.format(e)) + fd.write("|\n") + def cell_render(target, bin): + return "y" if table[target][bin] == 0 else " " + + # add some 'hard' padding to specific columns + lens = [ + max(map(lambda x: len(x.os), row_headings)) + 2, + max(map(lambda x: len(x.arch), row_headings)) + 2 + ] + header = Target.get_heading() + header[0] = ("{:#^%d}" % lens[0]).format(header[0]) + header[1] = ("{:#^%d}" % lens[1]).format(header[1]) + + header += headings + print_row(header) + lines = list(map(lambda x: '-'*len(x), header)) + print_row(lines) + + for t in row_headings: + row = list(map(lambda b: cell_render(t, b), headings)) + row = t.get_row_heading() + row + print_row(row) + +if __name__ == "__main__": + # create the top-level parser + parser = argparse.ArgumentParser(prog='compiles_table.py') + subparsers = parser.add_subparsers(help='sub-command to execute', required=True, dest="cmd") + # create the parser for the "check" command + parser_a = subparsers.add_parser('check', help='run cargo check on specified targets and update csv cache') + parser_a.add_argument("targets", metavar="TARGET", type=str, nargs='+', choices=["all"]+TARGETS, + help="target-triple to check, as shown by 'rustup target list'") + # create the parser for the "render" command + parser_b = subparsers.add_parser('render', help='print a markdown table to stdout') + parser_b.add_argument("--equidistant", action="store_true", + help="NOT IMPLEMENTED: render each column with an equal width (in plaintext)") + args = parser.parse_args() + + if args.cmd == "render": + table, targets, bins = load_csv(CACHE_PATH) + render_md(sys.stdout, table, bins, targets) + + if args.cmd == "check": + targets = get_targets(args.targets) + bins = get_all_bins() + + assert(all(map(Target.is_installed, targets))) + table = test_all_targets(targets, bins) + + prev_table, _, _ = load_csv(CACHE_PATH) + new_table = merge_tables(prev_table, table) + save_csv(CACHE_PATH, new_table) \ No newline at end of file From 698dab12a6528e471d08d1b723c083b0e3989699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81rni=20Dagur?= Date: Tue, 30 Mar 2021 18:53:02 +0000 Subject: [PATCH 046/132] wc: Don't read() if we only need to count number of bytes (Version 2) (#1851) * wc: Don't read() if we only need to count number of bytes * Resolve a few code review comments * Use write macros instead of print * Fix wc tests in case only one thing is printed * wc: Fix style * wc: Use return value of first splice rather than second * wc: Make main loop more readable * wc: Don't unwrap on failed write to stdout * wc: Increment error count when stats fail to print * Re-add Cargo.lock --- Cargo.lock | 2017 +++++++++++++++++----------------- src/uu/wc/Cargo.toml | 5 + src/uu/wc/src/count_bytes.rs | 95 ++ src/uu/wc/src/wc.rs | 411 ++++--- tests/by-util/test_wc.rs | 6 +- 5 files changed, 1382 insertions(+), 1152 deletions(-) create mode 100644 src/uu/wc/src/count_bytes.rs diff --git a/Cargo.lock b/Cargo.lock index b8293f666..6b79e018b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,2707 +1,2710 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "advapi32-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "aho-corasick" version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" dependencies = [ - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.4", ] [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9", ] [[package]] name = "arrayvec" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" dependencies = [ - "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", + "winapi 0.3.9", ] [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bit-set" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" dependencies = [ - "bit-vec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bit-vec", ] [[package]] name = "bit-vec" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "blake2-rfc" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" dependencies = [ - "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec", + "constant_time_eq", ] [[package]] name = "block-buffer" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" dependencies = [ - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools", + "generic-array", ] [[package]] name = "bstr" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "memchr 2.3.4", + "regex-automata", + "serde", ] [[package]] name = "bumpalo" version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" [[package]] name = "byte-tools" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cast" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version", ] [[package]] name = "cc" version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" dependencies = [ - "num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits", + "time", ] [[package]] name = "clap" version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", ] [[package]] name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", ] [[package]] name = "constant_time_eq" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "conv" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" dependencies = [ - "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "custom_derive", ] [[package]] name = "coreutils" version = "0.0.4" dependencies = [ - "conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "unindent 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uu_arch 0.0.4", - "uu_base32 0.0.4", - "uu_base64 0.0.4", - "uu_basename 0.0.4", - "uu_cat 0.0.4", - "uu_chgrp 0.0.4", - "uu_chmod 0.0.4", - "uu_chown 0.0.4", - "uu_chroot 0.0.4", - "uu_cksum 0.0.4", - "uu_comm 0.0.4", - "uu_cp 0.0.4", - "uu_csplit 0.0.4", - "uu_cut 0.0.4", - "uu_date 0.0.4", - "uu_df 0.0.4", - "uu_dircolors 0.0.4", - "uu_dirname 0.0.4", - "uu_du 0.0.4", - "uu_echo 0.0.4", - "uu_env 0.0.4", - "uu_expand 0.0.4", - "uu_expr 0.0.4", - "uu_factor 0.0.4", - "uu_false 0.0.4", - "uu_fmt 0.0.4", - "uu_fold 0.0.4", - "uu_groups 0.0.4", - "uu_hashsum 0.0.4", - "uu_head 0.0.4", - "uu_hostid 0.0.4", - "uu_hostname 0.0.4", - "uu_id 0.0.4", - "uu_install 0.0.4", - "uu_join 0.0.4", - "uu_kill 0.0.4", - "uu_link 0.0.4", - "uu_ln 0.0.4", - "uu_logname 0.0.4", - "uu_ls 0.0.4", - "uu_mkdir 0.0.4", - "uu_mkfifo 0.0.4", - "uu_mknod 0.0.4", - "uu_mktemp 0.0.4", - "uu_more 0.0.4", - "uu_mv 0.0.4", - "uu_nice 0.0.4", - "uu_nl 0.0.4", - "uu_nohup 0.0.4", - "uu_nproc 0.0.4", - "uu_numfmt 0.0.4", - "uu_od 0.0.4", - "uu_paste 0.0.4", - "uu_pathchk 0.0.4", - "uu_pinky 0.0.4", - "uu_printenv 0.0.4", - "uu_printf 0.0.4", - "uu_ptx 0.0.4", - "uu_pwd 0.0.4", - "uu_readlink 0.0.4", - "uu_realpath 0.0.4", - "uu_relpath 0.0.4", - "uu_rm 0.0.4", - "uu_rmdir 0.0.4", - "uu_seq 0.0.4", - "uu_shred 0.0.4", - "uu_shuf 0.0.4", - "uu_sleep 0.0.4", - "uu_sort 0.0.4", - "uu_split 0.0.4", - "uu_stat 0.0.4", - "uu_stdbuf 0.0.4", - "uu_sum 0.0.4", - "uu_sync 0.0.4", - "uu_tac 0.0.4", - "uu_tail 0.0.4", - "uu_tee 0.0.4", - "uu_test 0.0.4", - "uu_timeout 0.0.4", - "uu_touch 0.0.4", - "uu_tr 0.0.4", - "uu_true 0.0.4", - "uu_truncate 0.0.4", - "uu_tsort 0.0.4", - "uu_tty 0.0.4", - "uu_uname 0.0.4", - "uu_unexpand 0.0.4", - "uu_uniq 0.0.4", - "uu_unlink 0.0.4", - "uu_uptime 0.0.4", - "uu_users 0.0.4", - "uu_wc 0.0.4", - "uu_who 0.0.4", - "uu_whoami 0.0.4", - "uu_yes 0.0.4", - "uucore 0.0.7", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "conv", + "filetime", + "glob 0.3.0", + "lazy_static", + "libc", + "nix 0.20.0", + "rand 0.7.3", + "regex", + "sha1", + "tempdir", + "tempfile", + "textwrap", + "time", + "unindent", + "unix_socket", + "users", + "uu_arch", + "uu_base32", + "uu_base64", + "uu_basename", + "uu_cat", + "uu_chgrp", + "uu_chmod", + "uu_chown", + "uu_chroot", + "uu_cksum", + "uu_comm", + "uu_cp", + "uu_csplit", + "uu_cut", + "uu_date", + "uu_df", + "uu_dircolors", + "uu_dirname", + "uu_du", + "uu_echo", + "uu_env", + "uu_expand", + "uu_expr", + "uu_factor", + "uu_false", + "uu_fmt", + "uu_fold", + "uu_groups", + "uu_hashsum", + "uu_head", + "uu_hostid", + "uu_hostname", + "uu_id", + "uu_install", + "uu_join", + "uu_kill", + "uu_link", + "uu_ln", + "uu_logname", + "uu_ls", + "uu_mkdir", + "uu_mkfifo", + "uu_mknod", + "uu_mktemp", + "uu_more", + "uu_mv", + "uu_nice", + "uu_nl", + "uu_nohup", + "uu_nproc", + "uu_numfmt", + "uu_od", + "uu_paste", + "uu_pathchk", + "uu_pinky", + "uu_printenv", + "uu_printf", + "uu_ptx", + "uu_pwd", + "uu_readlink", + "uu_realpath", + "uu_relpath", + "uu_rm", + "uu_rmdir", + "uu_seq", + "uu_shred", + "uu_shuf", + "uu_sleep", + "uu_sort", + "uu_split", + "uu_stat", + "uu_stdbuf", + "uu_sum", + "uu_sync", + "uu_tac", + "uu_tail", + "uu_tee", + "uu_test", + "uu_timeout", + "uu_touch", + "uu_tr", + "uu_true", + "uu_truncate", + "uu_tsort", + "uu_tty", + "uu_uname", + "uu_unexpand", + "uu_uniq", + "uu_unlink", + "uu_uptime", + "uu_users", + "uu_wc", + "uu_who", + "uu_whoami", + "uu_yes", + "uucore", + "walkdir", ] [[package]] name = "cpp" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4875a08600be48dcc9cb6ee07f104a3e0752e95184dede6a30044d6480bf50e8" dependencies = [ - "cpp_macros 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_macros", ] [[package]] name = "cpp_build" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c47531e7e09532ad4827098729794f5e1a5b1c2ccbb5e295498d2e7ab451c445" dependencies = [ - "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_common 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_synmap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "cpp_common 0.4.0", + "cpp_syn", + "cpp_synmap", + "cpp_synom", + "lazy_static", ] [[package]] name = "cpp_common" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e39149a7943affa02f5b6e347ca2840a129cc78d5883ee229f0f1c4027d628" dependencies = [ - "cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_syn", + "cpp_synom", + "lazy_static", + "quote 0.3.15", ] [[package]] name = "cpp_common" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df78ad28e5fe814285016779fb3d3b874520c799a847e6190bf2b834cc4ff283" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "proc-macro2", + "syn", ] [[package]] name = "cpp_macros" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f93a21e618c10abc84ebb63ffa5952e1f7a4568b8141d542d5ef860e4a8fc25" dependencies = [ - "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_common 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "if_rust_version 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "byteorder", + "cpp_common 0.5.6", + "if_rust_version", + "lazy_static", + "proc-macro2", + "quote 1.0.9", + "syn", ] [[package]] name = "cpp_syn" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8cd649bf5b3804d92fe12a60c7698f5a538a6033ed8a668bf5241d4d4f1644e" dependencies = [ - "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_synom", + "quote 0.3.15", + "unicode-xid 0.0.4", ] [[package]] name = "cpp_synmap" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897e4f9cdbe2874edd3ffe53718ee5d8b89e2a970057b2c93d3214104f2e90b6" dependencies = [ - "cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_syn", + "cpp_synom", + "memchr 1.0.2", ] [[package]] name = "cpp_synom" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc8da5694233b646150c785118f77835ad0a49680c7f312a10ef30957c67b6d" dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4", ] [[package]] name = "criterion" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion-plot 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "csv 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "oorandom 11.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "plotters 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", - "tinytemplate 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools 0.10.0", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", ] [[package]] name = "criterion-plot" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" dependencies = [ - "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cast", + "itertools 0.9.0", ] [[package]] name = "crossbeam-channel" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "crossbeam-utils", ] [[package]] name = "crossbeam-deque" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-epoch 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", ] [[package]] name = "crossbeam-utils" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "cfg-if 1.0.0", + "lazy_static", ] [[package]] name = "csv" version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" dependencies = [ - "bstr 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", ] [[package]] name = "csv-core" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" dependencies = [ - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.4", ] [[package]] name = "custom_derive" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" [[package]] name = "data-encoding" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" [[package]] name = "digest" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" dependencies = [ - "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", ] [[package]] name = "dunce" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2641c4a7c0c4101df53ea572bffdc561c146f6c2eb09e4df02bc4811e3feeb4" [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ - "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log", + "regex", ] [[package]] name = "fake-simd" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "file_diff" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" [[package]] name = "filetime" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.5", + "winapi 0.3.9", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fs_extra" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "generic-array" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2297fb0e3ea512e380da24b52dca3924028f59df5e3a17a18f81d8349ca7ebe" dependencies = [ - "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop", + "typenum", ] [[package]] name = "getopts" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" dependencies = [ - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "getrandom" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "libc", + "wasi", ] [[package]] name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "half" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" [[package]] name = "hermit-abi" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "hex" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" [[package]] name = "hostname" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "match_cfg 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "match_cfg", + "winapi 0.3.9", ] [[package]] name = "if_rust_version" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46dbcb333e86939721589d25a3557e180b52778cb33c7fdfe9e0158ff790d5ec" [[package]] name = "ioctl-sys" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2c4b26352496eaaa8ca7cfa9bd99e93419d3f7983dc6e99c2a35fe9e33504a" [[package]] name = "itertools" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" dependencies = [ - "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] name = "itertools" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" dependencies = [ - "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] name = "itertools" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" dependencies = [ - "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] name = "itoa" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "js-sys" -version = "0.3.49" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" dependencies = [ - "wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen", ] [[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" [[package]] name = "log" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", ] [[package]] name = "match_cfg" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "maybe-uninit" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "md5" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48" [[package]] name = "memchr" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "memchr" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "memoffset" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] name = "nix" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cc", + "cfg-if 0.1.10", + "libc", + "void", ] [[package]] name = "nix" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", ] [[package]] name = "nodrop" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "num-integer" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "num-traits", ] [[package]] name = "num-traits" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] name = "num_cpus" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ - "hermit-abi 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", ] [[package]] name = "number_prefix" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "numtoa" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" [[package]] name = "onig" version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8518fcb2b1b8c2f45f0ad499df4fda6087fc3475ca69a185c173b8315d2fb383" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "lazy_static", + "libc", + "onig_sys", ] [[package]] name = "onig_sys" version = "69.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388410bf5fa341f10e58e6db3975f4bea1ac30247dd79d37a9e5ced3cb4cc3b0" dependencies = [ - "cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "pkg-config", ] [[package]] name = "oorandom" version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "paste" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" dependencies = [ - "paste-impl 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)", + "paste-impl", + "proc-macro-hack", ] [[package]] name = "paste-impl" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" dependencies = [ - "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack", ] [[package]] name = "pkg-config" version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] name = "platform-info" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ea9cd21d89bffb387b6c7363d23bead0807be9de676c671b474dd29e7436d3" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi 0.3.9", ] [[package]] name = "plotters" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" dependencies = [ - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "plotters-svg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", ] [[package]] name = "plotters-backend" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" [[package]] name = "plotters-svg" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" dependencies = [ - "plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plotters-backend", ] [[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "proc-macro-hack" version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ - "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.1", ] [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quickcheck" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" dependencies = [ - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger", + "log", + "rand 0.7.3", + "rand_core 0.5.1", ] [[package]] name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" [[package]] name = "quote" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] name = "rand" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi 0.3.9", ] [[package]] name = "rand" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "winapi 0.3.9", ] [[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "libc", + "rand_chacha", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", ] [[package]] name = "rand_chacha" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ - "ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" dependencies = [ - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2", ] [[package]] name = "rand_core" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1", ] [[package]] name = "rand_pcg" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1", ] [[package]] name = "rayon" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" dependencies = [ - "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", ] [[package]] name = "rayon-core" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" dependencies = [ - "crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", ] [[package]] name = "rdrand" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "redox_syscall" version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", ] [[package]] name = "redox_termios" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" dependencies = [ - "redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.2.5", ] [[package]] name = "regex" version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" dependencies = [ - "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr 2.3.4", + "regex-syntax", ] [[package]] name = "regex-automata" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" dependencies = [ - "byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", ] [[package]] name = "regex-syntax" version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" [[package]] name = "remove_dir_all" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9", ] [[package]] name = "retain_mut" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53552c6c49e1e13f1a203ef0080ab3bbef0beb570a528993e83df057a9d9bba1" [[package]] name = "rust-ini" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" [[package]] name = "rustc_version" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver", ] [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util", ] [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver-parser", ] [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" [[package]] name = "serde_cbor" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" dependencies = [ - "half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "half", + "serde", ] [[package]] name = "serde_derive" version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "syn", ] [[package]] name = "serde_json" version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" dependencies = [ - "itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa", + "ryu", + "serde", ] [[package]] name = "sha1" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" [[package]] name = "sha2" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" dependencies = [ - "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer", + "byte-tools", + "digest", + "fake-simd", + "generic-array", ] [[package]] name = "sha3" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0" dependencies = [ - "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer", + "byte-tools", + "digest", + "generic-array", ] [[package]] name = "smallvec" version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" dependencies = [ - "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit", ] [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "unicode-xid 0.2.1", ] [[package]] name = "tempdir" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" dependencies = [ - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.6", + "remove_dir_all", ] [[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10", + "libc", + "rand 0.7.3", + "redox_syscall 0.1.57", + "remove_dir_all", + "winapi 0.3.9", ] [[package]] name = "term_grid" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230d3e804faaed5a39b08319efb797783df2fd9671b39b7596490cb486d702cf" dependencies = [ - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "term_size" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi 0.3.9", ] [[package]] name = "termion" version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "numtoa", + "redox_syscall 0.2.5", + "redox_termios", ] [[package]] name = "termsize" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e86d824a8e90f342ad3ef4bd51ef7119a9b681b0cc9f8ee7b2852f02ccd2517" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "kernel32-sys", + "libc", + "termion", + "winapi 0.2.8", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "term_size 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "term_size", + "unicode-width", ] [[package]] name = "thiserror" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" dependencies = [ - "thiserror-impl 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "syn", ] [[package]] name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "redox_syscall 0.1.57", + "winapi 0.3.9", ] [[package]] name = "tinytemplate" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ - "serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", + "serde_json", ] [[package]] name = "twox-hash" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10", + "rand 0.7.3", + "static_assertions", ] [[package]] name = "typenum" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" [[package]] name = "unicode-width" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "unindent" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" [[package]] name = "unix_socket" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10", + "libc", ] [[package]] name = "users" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "log", ] [[package]] name = "uu_arch" version = "0.0.4" dependencies = [ - "platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "platform-info", + "uucore", + "uucore_procs", ] [[package]] name = "uu_base32" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_base64" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_basename" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_cat" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "quick-error", + "unix_socket", + "uucore", + "uucore_procs", ] [[package]] name = "uu_chgrp" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore", + "uucore_procs", + "walkdir", ] [[package]] name = "uu_chmod" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "libc", + "uucore", + "uucore_procs", + "walkdir", ] [[package]] name = "uu_chown" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "glob 0.3.0", + "uucore", + "uucore_procs", + "walkdir", ] [[package]] name = "uu_chroot" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_cksum" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_comm" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_cp" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "ioctl-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "filetime", + "ioctl-sys", + "libc", + "quick-error", + "uucore", + "uucore_procs", + "walkdir", + "winapi 0.3.9", + "xattr", ] [[package]] name = "uu_csplit" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "glob 0.2.11", + "regex", + "thiserror", + "uucore", + "uucore_procs", ] [[package]] name = "uu_cut" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_date" version = "0.0.4" dependencies = [ - "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "clap", + "libc", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_df" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "libc", + "number_prefix", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_dircolors" version = "0.0.4" dependencies = [ - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "glob 0.3.0", + "uucore", + "uucore_procs", ] [[package]] name = "uu_dirname" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_du" version = "0.0.4" dependencies = [ - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_echo" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_env" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "rust-ini", + "uucore", + "uucore_procs", ] [[package]] name = "uu_expand" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "unicode-width", + "uucore", + "uucore_procs", ] [[package]] name = "uu_expr" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "onig 4.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "onig", + "uucore", + "uucore_procs", ] [[package]] name = "uu_factor" version = "0.0.4" dependencies = [ - "criterion 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "criterion", + "num-traits", + "paste", + "quickcheck", + "rand 0.7.3", + "rand_chacha", + "smallvec", + "uucore", + "uucore_procs", ] [[package]] name = "uu_false" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_fmt" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "unicode-width", + "uucore", + "uucore_procs", ] [[package]] name = "uu_fold" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_groups" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_hashsum" version = "0.0.4" dependencies = [ - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "md5 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "blake2-rfc", + "clap", + "digest", + "hex", + "libc", + "md5", + "regex", + "regex-syntax", + "sha1", + "sha2", + "sha3", + "uucore", + "uucore_procs", ] [[package]] name = "uu_head" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_hostid" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_hostname" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hostname 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "hostname", + "libc", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_id" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_install" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "file_diff 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "file_diff", + "filetime", + "libc", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_join" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_kill" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_link" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_ln" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_logname" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_ls" version = "0.0.4" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "term_grid 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "termsize 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "atty", + "clap", + "lazy_static", + "number_prefix", + "term_grid", + "termsize", + "time", + "unicode-width", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mkdir" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mkfifo" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mknod" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mktemp" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "rand 0.5.6", + "tempfile", + "uucore", + "uucore_procs", ] [[package]] name = "uu_more" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "nix 0.13.1", + "redox_syscall 0.1.57", + "redox_termios", + "uucore", + "uucore_procs", ] [[package]] name = "uu_mv" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "fs_extra", + "uucore", + "uucore_procs", ] [[package]] name = "uu_nice" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "nix 0.13.1", + "uucore", + "uucore_procs", ] [[package]] name = "uu_nl" version = "0.0.4" dependencies = [ - "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "aho-corasick", + "clap", + "libc", + "memchr 2.3.4", + "regex", + "regex-syntax", + "uucore", + "uucore_procs", ] [[package]] name = "uu_nohup" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_nproc" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "num_cpus", + "uucore", + "uucore_procs", ] [[package]] name = "uu_numfmt" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_od" version = "0.0.4" dependencies = [ - "byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "byteorder", + "clap", + "half", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_paste" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_pathchk" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_pinky" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_printenv" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_printf" version = "0.0.4" dependencies = [ - "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "itertools 0.8.2", + "uucore", + "uucore_procs", ] [[package]] name = "uu_ptx" version = "0.0.4" dependencies = [ - "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "aho-corasick", + "clap", + "libc", + "memchr 2.3.4", + "regex", + "regex-syntax", + "uucore", + "uucore_procs", ] [[package]] name = "uu_pwd" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_readlink" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_realpath" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_relpath" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "uucore", + "uucore_procs", ] [[package]] name = "uu_rm" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "remove_dir_all", + "uucore", + "uucore_procs", + "walkdir", ] [[package]] name = "uu_rmdir" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_seq" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_shred" version = "0.0.4" dependencies = [ - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "filetime", + "getopts", + "libc", + "rand 0.5.6", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_shuf" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "rand 0.5.6", + "uucore", + "uucore_procs", ] [[package]] name = "uu_sleep" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_sort" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "twox-hash 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "itertools 0.8.2", + "rand 0.7.3", + "semver", + "twox-hash", + "uucore", + "uucore_procs", ] [[package]] name = "uu_split" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_stat" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_stdbuf" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uu_stdbuf_libstdbuf 0.0.4", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "tempfile", + "uu_stdbuf_libstdbuf", + "uucore", + "uucore_procs", ] [[package]] name = "uu_stdbuf_libstdbuf" version = "0.0.4" dependencies = [ - "cpp 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "cpp_build 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "cpp", + "cpp_build", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_sum" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_sync" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "libc", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_tac" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "uucore", + "uucore_procs", ] [[package]] name = "uu_tail" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "libc", + "redox_syscall 0.1.57", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_tee" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "retain_mut 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "retain_mut", + "uucore", + "uucore_procs", ] [[package]] name = "uu_test" version = "0.0.4" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "libc", + "redox_syscall 0.1.57", + "uucore", + "uucore_procs", ] [[package]] name = "uu_timeout" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_touch" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "filetime", + "time", + "uucore", + "uucore_procs", ] [[package]] name = "uu_tr" version = "0.0.4" dependencies = [ - "bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "bit-set", + "clap", + "fnv", + "uucore", + "uucore_procs", ] [[package]] name = "uu_true" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_truncate" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_tsort" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_tty" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_uname" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "platform-info", + "uucore", + "uucore_procs", ] [[package]] name = "uu_unexpand" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "unicode-width", + "uucore", + "uucore_procs", ] [[package]] name = "uu_uniq" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_unlink" version = "0.0.4" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "getopts", + "libc", + "uucore", + "uucore_procs", ] [[package]] name = "uu_uptime" version = "0.0.4" dependencies = [ - "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "chrono", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_users" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uu_wc" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "libc", + "nix 0.20.0", + "thiserror", + "uucore", + "uucore_procs", ] [[package]] name = "uu_who" version = "0.0.4" dependencies = [ - "uucore 0.0.7", - "uucore_procs 0.0.5", + "uucore", + "uucore_procs", ] [[package]] name = "uu_whoami" version = "0.0.4" dependencies = [ - "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "advapi32-sys", + "clap", + "uucore", + "uucore_procs", + "winapi 0.3.9", ] [[package]] name = "uu_yes" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] name = "uucore" version = "0.0.7" dependencies = [ - "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dunce 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "wild 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "data-encoding", + "dunce", + "getopts", + "lazy_static", + "libc", + "nix 0.13.1", + "platform-info", + "termion", + "thiserror", + "time", + "wild", ] [[package]] name = "uucore_procs" version = "0.0.5" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "syn", ] [[package]] name = "vec_map" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "walkdir" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ - "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file", + "winapi 0.3.9", + "winapi-util", ] [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.72" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" dependencies = [ - "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0", + "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.72" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" dependencies = [ - "bumpalo 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote 1.0.9", + "syn", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.72" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" dependencies = [ - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.9", + "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.72" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" dependencies = [ - "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.9", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.72" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" [[package]] name = "web-sys" -version = "0.3.49" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" dependencies = [ - "js-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys", + "wasm-bindgen", ] [[package]] name = "wild" version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020" dependencies = [ - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0", ] [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "xattr" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" dependencies = [ - "libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] - -[metadata] -"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" -"checksum aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -"checksum autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -"checksum bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" -"checksum bit-vec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" -"checksum bstr 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" -"checksum bumpalo 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" -"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" -"checksum byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" -"checksum cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -"checksum chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" -"checksum clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)" = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" -"checksum cpp 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4875a08600be48dcc9cb6ee07f104a3e0752e95184dede6a30044d6480bf50e8" -"checksum cpp_build 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c47531e7e09532ad4827098729794f5e1a5b1c2ccbb5e295498d2e7ab451c445" -"checksum cpp_common 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79e39149a7943affa02f5b6e347ca2840a129cc78d5883ee229f0f1c4027d628" -"checksum cpp_common 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "df78ad28e5fe814285016779fb3d3b874520c799a847e6190bf2b834cc4ff283" -"checksum cpp_macros 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f93a21e618c10abc84ebb63ffa5952e1f7a4568b8141d542d5ef860e4a8fc25" -"checksum cpp_syn 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8cd649bf5b3804d92fe12a60c7698f5a538a6033ed8a668bf5241d4d4f1644e" -"checksum cpp_synmap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "897e4f9cdbe2874edd3ffe53718ee5d8b89e2a970057b2c93d3214104f2e90b6" -"checksum cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc8da5694233b646150c785118f77835ad0a49680c7f312a10ef30957c67b6d" -"checksum criterion 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" -"checksum criterion-plot 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" -"checksum crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" -"checksum crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" -"checksum crossbeam-epoch 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" -"checksum crossbeam-utils 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" -"checksum csv 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -"checksum csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" -"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" -"checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" -"checksum dunce 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b2641c4a7c0c4101df53ea572bffdc561c146f6c2eb09e4df02bc4811e3feeb4" -"checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum file_diff 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" -"checksum filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" -"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -"checksum fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum generic-array 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2297fb0e3ea512e380da24b52dca3924028f59df5e3a17a18f81d8349ca7ebe" -"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" -"checksum getrandom 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -"checksum half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" -"checksum hermit-abi 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" -"checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" -"checksum hostname 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -"checksum if_rust_version 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46dbcb333e86939721589d25a3557e180b52778cb33c7fdfe9e0158ff790d5ec" -"checksum ioctl-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e2c4b26352496eaaa8ca7cfa9bd99e93419d3f7983dc6e99c2a35fe9e33504a" -"checksum itertools 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" -"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" -"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -"checksum itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" -"checksum js-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)" = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" -"checksum log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -"checksum match_cfg 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" -"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -"checksum md5 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48" -"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" -"checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" -"checksum memoffset 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" -"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" -"checksum nix 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" -"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -"checksum num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -"checksum num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -"checksum number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" -"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" -"checksum onig 4.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8518fcb2b1b8c2f45f0ad499df4fda6087fc3475ca69a185c173b8315d2fb383" -"checksum onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388410bf5fa341f10e58e6db3975f4bea1ac30247dd79d37a9e5ced3cb4cc3b0" -"checksum oorandom 11.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -"checksum paste 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" -"checksum paste-impl 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" -"checksum pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" -"checksum platform-info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ea9cd21d89bffb387b6c7363d23bead0807be9de676c671b474dd29e7436d3" -"checksum plotters 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" -"checksum plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" -"checksum plotters-svg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" -"checksum ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" -"checksum proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" -"checksum proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" -"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -"checksum quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" -"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -"checksum rayon 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" -"checksum rayon-core 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" -"checksum redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" -"checksum redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" -"checksum regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" -"checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" -"checksum regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)" = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" -"checksum remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -"checksum retain_mut 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53552c6c49e1e13f1a203ef0080ab3bbef0beb570a528993e83df057a9d9bba1" -"checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)" = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" -"checksum serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" -"checksum serde_derive 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)" = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" -"checksum serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)" = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" -"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" -"checksum sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0" -"checksum smallvec 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -"checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum syn 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)" = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" -"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" -"checksum term_grid 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "230d3e804faaed5a39b08319efb797783df2fd9671b39b7596490cb486d702cf" -"checksum term_size 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" -"checksum termion 1.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" -"checksum termsize 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "5e86d824a8e90f342ad3ef4bd51ef7119a9b681b0cc9f8ee7b2852f02ccd2517" -"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" -"checksum thiserror-impl 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tinytemplate 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -"checksum twox-hash 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" -"checksum typenum 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" -"checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" -"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -"checksum unindent 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" -"checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" -"checksum users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486" -"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -"checksum wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe" -"checksum wasm-bindgen-backend 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3" -"checksum wasm-bindgen-macro 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b" -"checksum wasm-bindgen-macro-support 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d" -"checksum wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa" -"checksum web-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310" -"checksum wild 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" diff --git a/src/uu/wc/Cargo.toml b/src/uu/wc/Cargo.toml index 894ac44dd..4e6cef101 100644 --- a/src/uu/wc/Cargo.toml +++ b/src/uu/wc/Cargo.toml @@ -18,6 +18,11 @@ path = "src/wc.rs" clap = "2.33" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } +thiserror = "1.0" + +[target.'cfg(unix)'.dependencies] +nix = "0.20" +libc = "0.2" [[bin]] name = "wc" diff --git a/src/uu/wc/src/count_bytes.rs b/src/uu/wc/src/count_bytes.rs new file mode 100644 index 000000000..dc90f67cc --- /dev/null +++ b/src/uu/wc/src/count_bytes.rs @@ -0,0 +1,95 @@ +use super::{WcResult, WordCountable}; + +#[cfg(any(target_os = "linux", target_os = "android"))] +use std::fs::OpenOptions; +use std::io::ErrorKind; + +#[cfg(unix)] +use libc::S_IFREG; +#[cfg(unix)] +use nix::sys::stat::fstat; +#[cfg(any(target_os = "linux", target_os = "android"))] +use std::os::unix::io::{AsRawFd, RawFd}; + +#[cfg(any(target_os = "linux", target_os = "android"))] +use libc::S_IFIFO; +#[cfg(any(target_os = "linux", target_os = "android"))] +use nix::fcntl::{splice, SpliceFFlags}; +#[cfg(any(target_os = "linux", target_os = "android"))] +use nix::unistd::pipe; + +const BUF_SIZE: usize = 16384; + +/// This is a Linux-specific function to count the number of bytes using the +/// `splice` system call, which is faster than using `read`. +#[inline] +#[cfg(any(target_os = "linux", target_os = "android"))] +fn count_bytes_using_splice(fd: RawFd) -> nix::Result { + let null_file = OpenOptions::new() + .write(true) + .open("/dev/null") + .map_err(|_| nix::Error::last())?; + let null = null_file.as_raw_fd(); + let (pipe_rd, pipe_wr) = pipe()?; + + let mut byte_count = 0; + loop { + let res = splice(fd, None, pipe_wr, None, BUF_SIZE, SpliceFFlags::empty())?; + if res == 0 { + break; + } + byte_count += res; + splice(pipe_rd, None, null, None, res, SpliceFFlags::empty())?; + } + + Ok(byte_count) +} + +/// In the special case where we only need to count the number of bytes. There +/// are several optimizations we can do: +/// 1. On Unix, we can simply `stat` the file if it is regular. +/// 2. On Linux -- if the above did not work -- we can use splice to count +/// the number of bytes if the file is a FIFO. +/// 3. Otherwise, we just read normally, but without the overhead of counting +/// other things such as lines and words. +#[inline] +pub(crate) fn count_bytes_fast(handle: &mut T) -> WcResult { + #[cfg(unix)] + { + let fd = handle.as_raw_fd(); + match fstat(fd) { + Ok(stat) => { + // If the file is regular, then the `st_size` should hold + // the file's size in bytes. + if (stat.st_mode & S_IFREG) != 0 { + return Ok(stat.st_size as usize); + } + #[cfg(any(target_os = "linux", target_os = "android"))] + { + // Else, if we're on Linux and our file is a FIFO pipe + // (or stdin), we use splice to count the number of bytes. + if (stat.st_mode & S_IFIFO) != 0 { + if let Ok(n) = count_bytes_using_splice(fd) { + return Ok(n); + } + } + } + } + _ => {} + } + } + + // Fall back on `read`, but without the overhead of counting words and lines. + let mut buf = [0 as u8; BUF_SIZE]; + let mut byte_count = 0; + loop { + match handle.read(&mut buf) { + Ok(0) => return Ok(byte_count), + Ok(n) => { + byte_count += n; + } + Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, + Err(e) => return Err(e.into()), + } + } +} diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 972802f81..22463caa4 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -10,14 +10,31 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg, ArgMatches}; +mod count_bytes; +use count_bytes::count_bytes_fast; +use clap::{App, Arg, ArgMatches}; +use thiserror::Error; + +use std::cmp::max; use std::fs::File; -use std::io::{stdin, BufRead, BufReader, Read}; +use std::io::{self, BufRead, BufReader, Read, StdinLock, Write}; +use std::ops::{Add, AddAssign}; +#[cfg(unix)] +use std::os::unix::io::AsRawFd; use std::path::Path; -use std::result::Result as StdResult; use std::str::from_utf8; +#[derive(Error, Debug)] +pub enum WcError { + #[error("{0}")] + Io(#[from] io::Error), + #[error("Expected a file, found directory {0}")] + IsDirectory(String), +} + +type WcResult = Result; + struct Settings { show_bytes: bool, show_chars: bool, @@ -53,10 +70,46 @@ impl Settings { show_max_line_length: false, } } + + fn number_enabled(&self) -> u32 { + let mut result = 0; + result += self.show_bytes as u32; + result += self.show_chars as u32; + result += self.show_lines as u32; + result += self.show_max_line_length as u32; + result += self.show_words as u32; + result + } } -struct Result { - title: String, +#[cfg(unix)] +trait WordCountable: AsRawFd + Read { + type Buffered: BufRead; + fn get_buffered(self) -> Self::Buffered; +} +#[cfg(not(unix))] +trait WordCountable: Read { + type Buffered: BufRead; + fn get_buffered(self) -> Self::Buffered; +} + +impl WordCountable for StdinLock<'_> { + type Buffered = Self; + + fn get_buffered(self) -> Self::Buffered { + self + } +} +impl WordCountable for File { + type Buffered = BufReader; + + fn get_buffered(self) -> Self::Buffered { + BufReader::new(self) + } +} + +#[derive(Debug, Default, Copy, Clone)] +struct WordCount { bytes: usize, chars: usize, lines: usize, @@ -64,6 +117,45 @@ struct Result { max_line_length: usize, } +impl Add for WordCount { + type Output = Self; + + fn add(self, other: Self) -> Self { + Self { + bytes: self.bytes + other.bytes, + chars: self.chars + other.chars, + lines: self.lines + other.lines, + words: self.words + other.words, + max_line_length: max(self.max_line_length, other.max_line_length), + } + } +} + +impl AddAssign for WordCount { + fn add_assign(&mut self, other: Self) { + *self = *self + other + } +} + +impl WordCount { + fn with_title<'a>(self, title: &'a str) -> TitledWordCount<'a> { + return TitledWordCount { + title: title, + count: self, + }; + } +} + +/// This struct supplements the actual word count with a title that is displayed +/// to the user at the end of the program. +/// The reason we don't simply include title in the `WordCount` struct is that +/// it would result in unneccesary copying of `String`. +#[derive(Debug, Default, Clone)] +struct TitledWordCount<'a> { + title: &'a str, + count: WordCount, +} + static ABOUT: &str = "Display newline, word, and byte counts for each FILE, and a total line if more than one FILE is specified."; static VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -137,12 +229,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let settings = Settings::new(&matches); - match wc(files, &settings) { - Ok(()) => ( /* pass */ ), - Err(e) => return e, + if wc(files, &settings).is_ok() { + 0 + } else { + 1 } - - 0 } const CR: u8 = b'\r'; @@ -157,151 +248,187 @@ fn is_word_separator(byte: u8) -> bool { byte == SPACE || byte == TAB || byte == CR || byte == SYN || byte == FF } -fn wc(files: Vec, settings: &Settings) -> StdResult<(), i32> { - let mut total_line_count: usize = 0; - let mut total_word_count: usize = 0; - let mut total_char_count: usize = 0; - let mut total_byte_count: usize = 0; - let mut total_longest_line_length: usize = 0; - - let mut results = vec![]; - let mut max_width: usize = 0; +fn word_count_from_reader( + mut reader: T, + settings: &Settings, + path: &String, +) -> WcResult { + let only_count_bytes = settings.show_bytes + && (!(settings.show_chars + || settings.show_lines + || settings.show_max_line_length + || settings.show_words)); + if only_count_bytes { + return Ok(WordCount { + bytes: count_bytes_fast(&mut reader)?, + ..WordCount::default() + }); + } // we do not need to decode the byte stream if we're only counting bytes/newlines let decode_chars = settings.show_chars || settings.show_words || settings.show_max_line_length; + let mut line_count: usize = 0; + let mut word_count: usize = 0; + let mut byte_count: usize = 0; + let mut char_count: usize = 0; + let mut longest_line_length: usize = 0; + let mut raw_line = Vec::new(); + let mut ends_lf: bool; + + // reading from a TTY seems to raise a condition on, rather than return Some(0) like a file. + // hence the option wrapped in a result here + let mut buffered_reader = reader.get_buffered(); + loop { + match buffered_reader.read_until(LF, &mut raw_line) { + Ok(n) => { + if n == 0 { + break; + } + } + Err(ref e) => { + if !raw_line.is_empty() { + show_warning!("Error while reading {}: {}", path, e); + } else { + break; + } + } + }; + + // GNU 'wc' only counts lines that end in LF as lines + ends_lf = *raw_line.last().unwrap() == LF; + line_count += ends_lf as usize; + + byte_count += raw_line.len(); + + if decode_chars { + // try and convert the bytes to UTF-8 first + let current_char_count; + match from_utf8(&raw_line[..]) { + Ok(line) => { + word_count += line.split_whitespace().count(); + current_char_count = line.chars().count(); + } + Err(..) => { + word_count += raw_line.split(|&x| is_word_separator(x)).count(); + current_char_count = raw_line.iter().filter(|c| c.is_ascii()).count() + } + } + char_count += current_char_count; + if current_char_count > longest_line_length { + // -L is a GNU 'wc' extension so same behavior on LF + longest_line_length = current_char_count - (ends_lf as usize); + } + } + + raw_line.truncate(0); + } + + Ok(WordCount { + bytes: byte_count, + chars: char_count, + lines: line_count, + words: word_count, + max_line_length: longest_line_length, + }) +} + +fn word_count_from_path(path: &String, settings: &Settings) -> WcResult { + if path == "-" { + let stdin = io::stdin(); + let stdin_lock = stdin.lock(); + return Ok(word_count_from_reader(stdin_lock, settings, path)?); + } else { + let path_obj = Path::new(path); + if path_obj.is_dir() { + return Err(WcError::IsDirectory(path.clone())); + } else { + let file = File::open(path)?; + return Ok(word_count_from_reader(file, settings, path)?); + } + } +} + +fn wc(files: Vec, settings: &Settings) -> Result<(), u32> { + let mut total_word_count = WordCount::default(); + let mut results = vec![]; + let mut max_width: usize = 0; + let mut error_count = 0; + + let num_files = files.len(); + for path in &files { - let mut reader = open(&path[..])?; - - let mut line_count: usize = 0; - let mut word_count: usize = 0; - let mut byte_count: usize = 0; - let mut char_count: usize = 0; - let mut longest_line_length: usize = 0; - let mut raw_line = Vec::new(); - let mut ends_lf: bool; - // reading from a TTY seems to raise a condition on, rather than return Some(0) like a file. - // hence the option wrapped in a result here - while match reader.read_until(LF, &mut raw_line) { - Ok(n) if n > 0 => true, - Err(ref e) if !raw_line.is_empty() => { - show_warning!("Error while reading {}: {}", path, e); - !raw_line.is_empty() - } - _ => false, - } { - // GNU 'wc' only counts lines that end in LF as lines - ends_lf = *raw_line.last().unwrap() == LF; - line_count += ends_lf as usize; - - byte_count += raw_line.len(); - - if decode_chars { - // try and convert the bytes to UTF-8 first - let current_char_count; - match from_utf8(&raw_line[..]) { - Ok(line) => { - word_count += line.split_whitespace().count(); - current_char_count = line.chars().count(); - } - Err(..) => { - word_count += raw_line.split(|&x| is_word_separator(x)).count(); - current_char_count = raw_line.iter().filter(|c| c.is_ascii()).count() - } - } - char_count += current_char_count; - if current_char_count > longest_line_length { - // -L is a GNU 'wc' extension so same behavior on LF - longest_line_length = current_char_count - (ends_lf as usize); - } - } - - raw_line.truncate(0); - } - - results.push(Result { - title: path.clone(), - bytes: byte_count, - chars: char_count, - lines: line_count, - words: word_count, - max_line_length: longest_line_length, + let word_count = word_count_from_path(&path, settings).unwrap_or_else(|err| { + show_error!("{}", err); + error_count += 1; + WordCount::default() }); - - total_line_count += line_count; + max_width = max(max_width, word_count.bytes.to_string().len() + 1); total_word_count += word_count; - total_char_count += char_count; - total_byte_count += byte_count; - - if longest_line_length > total_longest_line_length { - total_longest_line_length = longest_line_length; - } - - // used for formatting - max_width = total_byte_count.to_string().len() + 1; + results.push(word_count.with_title(path)); } for result in &results { - print_stats(settings, &result, max_width); + if let Err(err) = print_stats(settings, &result, max_width) { + show_warning!("failed to print result for {}: {}", result.title, err); + error_count += 1; + } } - if files.len() > 1 { - let result = Result { - title: "total".to_owned(), - bytes: total_byte_count, - chars: total_char_count, - lines: total_line_count, - words: total_word_count, - max_line_length: total_longest_line_length, - }; - print_stats(settings, &result, max_width); + if num_files > 1 { + let total_result = total_word_count.with_title("total"); + if let Err(err) = print_stats(settings, &total_result, max_width) { + show_warning!("failed to print total: {}", err); + error_count += 1; + } + } + + if error_count == 0 { + Ok(()) + } else { + Err(error_count) + } +} + +fn print_stats( + settings: &Settings, + result: &TitledWordCount, + mut min_width: usize, +) -> WcResult<()> { + let stdout = io::stdout(); + let mut stdout_lock = stdout.lock(); + + if settings.number_enabled() <= 1 { + // Prevent a leading space in case we only need to display a single + // number. + min_width = 0; + } + + if settings.show_lines { + write!(stdout_lock, "{:1$}", result.count.lines, min_width)?; + } + if settings.show_words { + write!(stdout_lock, "{:1$}", result.count.words, min_width)?; + } + if settings.show_bytes { + write!(stdout_lock, "{:1$}", result.count.bytes, min_width)?; + } + if settings.show_chars { + write!(stdout_lock, "{:1$}", result.count.chars, min_width)?; + } + if settings.show_max_line_length { + write!( + stdout_lock, + "{:1$}", + result.count.max_line_length, min_width + )?; + } + + if result.title == "-" { + writeln!(stdout_lock, "")?; + } else { + writeln!(stdout_lock, " {}", result.title)?; } Ok(()) } - -fn print_stats(settings: &Settings, result: &Result, max_width: usize) { - if settings.show_lines { - print!("{:1$}", result.lines, max_width); - } - if settings.show_words { - print!("{:1$}", result.words, max_width); - } - if settings.show_bytes { - print!("{:1$}", result.bytes, max_width); - } - if settings.show_chars { - print!("{:1$}", result.chars, max_width); - } - if settings.show_max_line_length { - print!("{:1$}", result.max_line_length, max_width); - } - - if result.title != "-" { - println!(" {}", result.title); - } else { - println!(); - } -} - -fn open(path: &str) -> StdResult>, i32> { - if "-" == path { - let reader = Box::new(stdin()) as Box; - return Ok(BufReader::new(reader)); - } - - let fpath = Path::new(path); - if fpath.is_dir() { - show_info!("{}: is a directory", path); - } - match File::open(&fpath) { - Ok(fd) => { - let reader = Box::new(fd) as Box; - Ok(BufReader::new(reader)) - } - Err(e) => { - show_error!("wc: {}: {}", path, e); - Err(1) - } - } -} diff --git a/tests/by-util/test_wc.rs b/tests/by-util/test_wc.rs index b064d7e0e..fd1143f05 100644 --- a/tests/by-util/test_wc.rs +++ b/tests/by-util/test_wc.rs @@ -25,7 +25,7 @@ fn test_stdin_line_len_regression() { .args(&["-L"]) .pipe_in("\n123456") .run() - .stdout_is(" 6\n"); + .stdout_is("6\n"); } #[test] @@ -34,7 +34,7 @@ fn test_stdin_only_bytes() { .args(&["-c"]) .pipe_in_fixture("lorem_ipsum.txt") .run() - .stdout_is(" 772\n"); + .stdout_is("772\n"); } #[test] @@ -59,7 +59,7 @@ fn test_single_only_lines() { new_ucmd!() .args(&["-l", "moby_dick.txt"]) .run() - .stdout_is(" 18 moby_dick.txt\n"); + .stdout_is("18 moby_dick.txt\n"); } #[test] From da18ffa496a71d6409710789088864b1f15cd355 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 30 Mar 2021 20:54:25 +0200 Subject: [PATCH 047/132] refresh cargo.lock with recent updates --- Cargo.lock | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b79e018b..ab8e59352 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,7 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - [[package]] name = "advapi32-sys" version = "0.2.0" @@ -2005,7 +2003,7 @@ dependencies = [ name = "uu_more" version = "0.0.4" dependencies = [ - "getopts", + "clap", "nix 0.13.1", "redox_syscall 0.1.57", "redox_termios", From be03c948ed3b077f0d492353e5126b26016861bc Mon Sep 17 00:00:00 2001 From: desbma Date: Tue, 30 Mar 2021 21:24:01 +0200 Subject: [PATCH 048/132] Add pre-commit hook + run fmt (#1959) --- .pre-commit-config.yaml | 8 ++++++++ src/uu/tee/src/tee.rs | 33 ++++++++++++++++----------------- tests/by-util/test_pathchk.rs | 32 ++++++++++++++++---------------- tests/by-util/test_rm.rs | 2 +- 4 files changed, 41 insertions(+), 34 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..66d2a5f5a --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,8 @@ +# https://pre-commit.com +repos: + - repo: https://github.com/doublify/pre-commit-rust + rev: v1.0 + hooks: + - id: cargo-check + - id: clippy + - id: fmt diff --git a/src/uu/tee/src/tee.rs b/src/uu/tee/src/tee.rs index 4b0f19038..7c6a86b4c 100644 --- a/src/uu/tee/src/tee.rs +++ b/src/uu/tee/src/tee.rs @@ -9,10 +9,10 @@ extern crate uucore; use clap::{App, Arg}; +use retain_mut::RetainMut; use std::fs::OpenOptions; use std::io::{copy, sink, stdin, stdout, Error, ErrorKind, Read, Result, Write}; use std::path::{Path, PathBuf}; -use retain_mut::RetainMut; #[cfg(unix)] use uucore::libc; @@ -98,19 +98,19 @@ fn tee(options: Options) -> Result<()> { .files .clone() .into_iter() - .map(|file| - NamedWriter { - name: file.clone(), - inner: open(file, options.append), - } - ) + .map(|file| NamedWriter { + name: file.clone(), + inner: open(file, options.append), + }) .collect(); - - writers.insert(0, NamedWriter { - name: "'standard output'".to_owned(), - inner: Box::new(stdout()), - }); + writers.insert( + 0, + NamedWriter { + name: "'standard output'".to_owned(), + inner: Box::new(stdout()), + }, + ); let mut output = MultiWriter::new(writers); let input = &mut NamedReader { @@ -119,8 +119,7 @@ fn tee(options: Options) -> Result<()> { // TODO: replaced generic 'copy' call to be able to stop copying // if all outputs are closed (due to errors) - if copy(input, &mut output).is_err() || output.flush().is_err() || - output.error_occured() { + if copy(input, &mut output).is_err() || output.flush().is_err() || output.error_occured() { Err(Error::new(ErrorKind::Other, "")) } else { Ok(()) @@ -150,7 +149,7 @@ struct MultiWriter { } impl MultiWriter { - fn new (writers: Vec) -> Self { + fn new(writers: Vec) -> Self { Self { initial_len: writers.len(), writers, @@ -170,7 +169,7 @@ impl Write for MultiWriter { show_info!("{}: {}", writer.name, f.to_string()); false } - _ => true + _ => true, } }); Ok(buf.len()) @@ -184,7 +183,7 @@ impl Write for MultiWriter { show_info!("{}: {}", writer.name, f.to_string()); false } - _ => true + _ => true, } }); Ok(()) diff --git a/tests/by-util/test_pathchk.rs b/tests/by-util/test_pathchk.rs index d01beccc2..3bc12f0b6 100644 --- a/tests/by-util/test_pathchk.rs +++ b/tests/by-util/test_pathchk.rs @@ -38,10 +38,7 @@ fn test_posix_mode() { // fail on long path new_ucmd!() - .args(&[ - "-p", - &"dir".repeat(libc::PATH_MAX as usize + 1).as_str(), - ]) + .args(&["-p", &"dir".repeat(libc::PATH_MAX as usize + 1).as_str()]) .fails() .no_stdout(); @@ -79,10 +76,7 @@ fn test_posix_special() { // fail on long path new_ucmd!() - .args(&[ - "-P", - &"dir".repeat(libc::PATH_MAX as usize + 1).as_str(), - ]) + .args(&["-P", &"dir".repeat(libc::PATH_MAX as usize + 1).as_str()]) .fails() .no_stdout(); @@ -107,7 +101,10 @@ fn test_posix_all() { // test the posix special mode // accept some reasonable default - new_ucmd!().args(&["-p", "-P", "dir/file"]).succeeds().no_stdout(); + new_ucmd!() + .args(&["-p", "-P", "dir/file"]) + .succeeds() + .no_stdout(); // accept non-leading hyphen new_ucmd!() @@ -136,10 +133,16 @@ fn test_posix_all() { .no_stdout(); // fail on non-portable chars - new_ucmd!().args(&["-p", "-P", "dir#/$file"]).fails().no_stdout(); + new_ucmd!() + .args(&["-p", "-P", "dir#/$file"]) + .fails() + .no_stdout(); // fail on leading hyphen char - new_ucmd!().args(&["-p", "-P", "dir/-file"]).fails().no_stdout(); + new_ucmd!() + .args(&["-p", "-P", "dir/-file"]) + .fails() + .no_stdout(); // fail on empty path new_ucmd!().args(&["-p", "-P", ""]).fails().no_stdout(); @@ -149,8 +152,5 @@ fn test_posix_all() { fn test_args_parsing() { // fail on no args let empty_args: [String; 0] = []; - new_ucmd!() - .args(&empty_args) - .fails() - .no_stdout(); -} \ No newline at end of file + new_ucmd!().args(&empty_args).fails().no_stdout(); +} diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 40cc6839a..149d509c5 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -177,7 +177,7 @@ fn test_rm_directory_without_flag() { let dir = "test_rm_directory_without_flag_dir"; at.mkdir(dir); - + let result = ucmd.arg(dir).fails(); println!("{}", result.stderr); assert!(result From ba315de6aa90a4e62401d6d5fd10b8b5d6d89c02 Mon Sep 17 00:00:00 2001 From: desbma Date: Tue, 30 Mar 2021 21:39:24 +0200 Subject: [PATCH 049/132] Add pre-commit instructions --- DEVELOPER_INSTRUCTIONS.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/DEVELOPER_INSTRUCTIONS.md b/DEVELOPER_INSTRUCTIONS.md index be6373409..c3b20dd46 100644 --- a/DEVELOPER_INSTRUCTIONS.md +++ b/DEVELOPER_INSTRUCTIONS.md @@ -24,3 +24,15 @@ if changes are not reflected in the report then run `cargo clean` and run the a If you are using stable version of Rust that doesn't enable code coverage instrumentation by default then add `-Z-Zinstrument-coverage` flag to `RUSTFLAGS` env variable specified above. + +pre-commit hooks +---------------- + +A configuration for `pre-commit` is provided in the repository. It allows automatically checking every git commit you make to ensure it compiles, and passes `clippy` and `rustfmt` without warnings. + +To use the provided hook: + +1. [Install `pre-commit`](https://pre-commit.com/#install) +2. Run `pre-commit install` while in the repository directory + +Your git commits will then automatically be checked. If a check fails, an error message will explain why, and your commit will be canceled. You can then make the suggested changes, and run `git commit ...` again. From a57f17ac5b7d66f7b2800adbda58f3bdfae6e24b Mon Sep 17 00:00:00 2001 From: Mikadore Date: Wed, 31 Mar 2021 11:25:23 +0200 Subject: [PATCH 050/132] Expand `CmdResult`'s API (#1977) --- tests/by-util/test_wc.rs | 2 +- tests/common/util.rs | 208 ++++++++++++++++++++++++++++++++------- 2 files changed, 171 insertions(+), 39 deletions(-) diff --git a/tests/by-util/test_wc.rs b/tests/by-util/test_wc.rs index fd1143f05..fc1665efc 100644 --- a/tests/by-util/test_wc.rs +++ b/tests/by-util/test_wc.rs @@ -14,7 +14,7 @@ fn test_utf8() { .args(&["-lwmcL"]) .pipe_in_fixture("UTF_8_test.txt") .run() - .stdout_is(" 0 0 0 0 0\n"); + .stdout_is(" 300 4969 22781 22213 79\n"); // GNU returns " 300 2086 22219 22781 79" // TODO: we should fix that to match GNU's behavior } diff --git a/tests/common/util.rs b/tests/common/util.rs index d33b1943d..2cee36267 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -53,9 +53,10 @@ pub fn is_wsl() -> bool { false } -fn read_scenario_fixture>(tmpd: &Option>, file_rel_path: S) -> String { +/// Read a test scenario fixture, returning its bytes +fn read_scenario_fixture>(tmpd: &Option>, file_rel_path: S) -> Vec { let tmpdir_path = tmpd.as_ref().unwrap().as_ref().path(); - AtPath::new(tmpdir_path).read(file_rel_path.as_ref().to_str().unwrap()) + AtPath::new(tmpdir_path).read_bytes(file_rel_path.as_ref().to_str().unwrap()) } /// A command result is the outputs of a command (streams and status code) @@ -69,29 +70,95 @@ pub struct CmdResult { /// zero-exit from running the Command? /// see [`success`] pub success: bool, - /// captured utf-8 standard output after running the Command + /// captured standard output after running the Command pub stdout: String, - /// captured utf-8 standard error after running the Command + /// captured standard error after running the Command pub stderr: String, } impl CmdResult { + /// Returns a reference to the program's standard output as a slice of bytes + pub fn stdout(&self) -> &[u8] { + &self.stdout.as_bytes() + } + + /// Returns the program's standard output as a string slice + pub fn stdout_str(&self) -> &str { + &self.stdout + } + + /// Returns the program's standard output as a string + /// consumes self + pub fn stdout_move_str(self) -> String { + self.stdout + } + + /// Returns the program's standard output as a vec of bytes + /// consumes self + pub fn stdout_move_bytes(self) -> Vec { + Vec::from(self.stdout) + } + + /// Returns a reference to the program's standard error as a slice of bytes + pub fn stderr(&self) -> &[u8] { + &self.stderr.as_bytes() + } + + /// Returns the program's standard error as a string slice + pub fn stderr_str(&self) -> &str { + &self.stderr + } + + /// Returns the program's standard error as a string + /// consumes self + pub fn stderr_move_str(self) -> String { + self.stderr + } + + /// Returns the program's standard error as a vec of bytes + /// consumes self + pub fn stderr_move_bytes(self) -> Vec { + Vec::from(self.stderr) + } + + /// Returns the program's exit code + /// Panics if not run + pub fn code(&self) -> i32 { + self.code.expect("Program must be run first") + } + + /// Returns the program's TempDir + /// Panics if not present + pub fn tmpd(&self) -> Rc { + match &self.tmpd { + Some(ptr) => ptr.clone(), + None => { + panic!("Command not associated with a TempDir") + } + } + } + + /// Returns whether the program succeeded + pub fn succeeded(&self) -> bool { + self.success + } + /// asserts that the command resulted in a success (zero) status code - pub fn success(&self) -> Box<&CmdResult> { + pub fn success(&self) -> &CmdResult { assert!(self.success); - Box::new(self) + self } /// asserts that the command resulted in a failure (non-zero) status code - pub fn failure(&self) -> Box<&CmdResult> { + pub fn failure(&self) -> &CmdResult { assert!(!self.success); - Box::new(self) + self } /// asserts that the command's exit code is the same as the given one - pub fn status_code(&self, code: i32) -> Box<&CmdResult> { + pub fn status_code(&self, code: i32) -> &CmdResult { assert!(self.code == Some(code)); - Box::new(self) + self } /// asserts that the command resulted in empty (zero-length) stderr stream output @@ -99,9 +166,9 @@ impl CmdResult { /// but you might find yourself using this function if /// 1. you can not know exactly what stdout will be /// or 2. you know that stdout will also be empty - pub fn no_stderr(&self) -> Box<&CmdResult> { - assert_eq!(self.stderr, ""); - Box::new(self) + pub fn no_stderr(&self) -> &CmdResult { + assert!(self.stderr.is_empty()); + self } /// asserts that the command resulted in empty (zero-length) stderr stream output @@ -110,62 +177,102 @@ impl CmdResult { /// but you might find yourself using this function if /// 1. you can not know exactly what stderr will be /// or 2. you know that stderr will also be empty - pub fn no_stdout(&self) -> Box<&CmdResult> { - assert_eq!(self.stdout, ""); - Box::new(self) + pub fn no_stdout(&self) -> &CmdResult { + assert!(self.stdout.is_empty()); + self } /// asserts that the command resulted in stdout stream output that equals the /// passed in value, trailing whitespace are kept to force strict comparison (#1235) /// stdout_only is a better choice unless stderr may or will be non-empty - pub fn stdout_is>(&self, msg: T) -> Box<&CmdResult> { + pub fn stdout_is>(&self, msg: T) -> &CmdResult { assert_eq!(self.stdout, String::from(msg.as_ref())); - Box::new(self) + self + } + + /// asserts that the command resulted in stdout stream output, + /// whose bytes equal those of the passed in slice + pub fn stdout_is_bytes>(&self, msg: T) -> &CmdResult { + assert_eq!(self.stdout.as_bytes(), msg.as_ref()); + self } /// like stdout_is(...), but expects the contents of the file at the provided relative path - pub fn stdout_is_fixture>(&self, file_rel_path: T) -> Box<&CmdResult> { + pub fn stdout_is_fixture>(&self, file_rel_path: T) -> &CmdResult { let contents = read_scenario_fixture(&self.tmpd, file_rel_path); - self.stdout_is(contents) + self.stdout_is_bytes(contents) } /// asserts that the command resulted in stderr stream output that equals the /// passed in value, when both are trimmed of trailing whitespace /// stderr_only is a better choice unless stdout may or will be non-empty - pub fn stderr_is>(&self, msg: T) -> Box<&CmdResult> { + pub fn stderr_is>(&self, msg: T) -> &CmdResult { assert_eq!( self.stderr.trim_end(), String::from(msg.as_ref()).trim_end() ); - Box::new(self) + self + } + + /// asserts that the command resulted in stderr stream output, + /// whose bytes equal those of the passed in slice + pub fn stderr_is_bytes>(&self, msg: T) -> &CmdResult { + assert_eq!(self.stderr.as_bytes(), msg.as_ref()); + self } /// asserts that /// 1. the command resulted in stdout stream output that equals the /// passed in value, when both are trimmed of trailing whitespace /// and 2. the command resulted in empty (zero-length) stderr stream output - pub fn stdout_only>(&self, msg: T) -> Box<&CmdResult> { + pub fn stdout_only>(&self, msg: T) -> &CmdResult { self.no_stderr().stdout_is(msg) } + /// asserts that + /// 1. the command resulted in a stdout stream whose bytes + /// equal those of the passed in value + /// 2. the command resulted in an empty stderr stream + pub fn stdout_only_bytes>(&self, msg: T) -> &CmdResult { + self.no_stderr().stdout_is_bytes(msg) + } + /// like stdout_only(...), but expects the contents of the file at the provided relative path - pub fn stdout_only_fixture>(&self, file_rel_path: T) -> Box<&CmdResult> { + pub fn stdout_only_fixture>(&self, file_rel_path: T) -> &CmdResult { let contents = read_scenario_fixture(&self.tmpd, file_rel_path); - self.stdout_only(contents) + self.stdout_only_bytes(contents) } /// asserts that /// 1. the command resulted in stderr stream output that equals the /// passed in value, when both are trimmed of trailing whitespace /// and 2. the command resulted in empty (zero-length) stdout stream output - pub fn stderr_only>(&self, msg: T) -> Box<&CmdResult> { + pub fn stderr_only>(&self, msg: T) -> &CmdResult { self.no_stdout().stderr_is(msg) } - pub fn fails_silently(&self) -> Box<&CmdResult> { + /// asserts that + /// 1. the command resulted in a stderr stream whose bytes equal the ones + /// of the passed value + /// 2. the command resulted in an empty stdout stream + pub fn stderr_only_bytes>(&self, msg: T) -> &CmdResult { + self.no_stderr().stderr_is_bytes(msg) + } + + pub fn fails_silently(&self) -> &CmdResult { assert!(!self.success); - assert_eq!(self.stderr, ""); - Box::new(self) + assert!(self.stderr.is_empty()); + self + } + + pub fn stdout_contains>(&self, cmp: T) -> &CmdResult { + assert!(self.stdout_str().contains(cmp.as_ref())); + self + } + + pub fn stderr_contains>(&self, cmp: &T) -> &CmdResult { + assert!(self.stderr_str().contains(cmp.as_ref())); + self } } @@ -255,11 +362,25 @@ impl AtPath { contents } + pub fn read_bytes(&self, name: &str) -> Vec { + let mut f = self.open(name); + let mut contents = Vec::new(); + f.read_to_end(&mut contents) + .unwrap_or_else(|e| panic!("Couldn't read {}: {}", name, e)); + contents + } + pub fn write(&self, name: &str, contents: &str) { log_info("open(write)", self.plus_as_string(name)); let _ = std::fs::write(self.plus(name), contents); } + pub fn write_bytes(&self, name: &str, contents: &[u8]) { + log_info("open(write)", self.plus_as_string(name)); + std::fs::write(self.plus(name), contents) + .unwrap_or_else(|e| panic!("Couldn't write {}: {}", name, e)); + } + pub fn append(&self, name: &str, contents: &str) { log_info("open(append)", self.plus_as_string(name)); let mut f = OpenOptions::new() @@ -270,6 +391,17 @@ impl AtPath { let _ = f.write(contents.as_bytes()); } + pub fn append_bytes(&self, name: &str, contents: &[u8]) { + log_info("open(append)", self.plus_as_string(name)); + let mut f = OpenOptions::new() + .write(true) + .append(true) + .open(self.plus(name)) + .unwrap(); + f.write_all(contents) + .unwrap_or_else(|e| panic!("Couldn't append to {}: {}", name, e)); + } + pub fn mkdir(&self, dir: &str) { log_info("mkdir", self.plus_as_string(dir)); fs::create_dir(&self.plus(dir)).unwrap(); @@ -521,19 +653,19 @@ impl UCommand { /// Add a parameter to the invocation. Path arguments are treated relative /// to the test environment directory. - pub fn arg>(&mut self, arg: S) -> Box<&mut UCommand> { + pub fn arg>(&mut self, arg: S) -> &mut UCommand { if self.has_run { panic!(ALREADY_RUN); } self.comm_string.push_str(" "); self.comm_string.push_str(arg.as_ref().to_str().unwrap()); self.raw.arg(arg.as_ref()); - Box::new(self) + self } /// Add multiple parameters to the invocation. Path arguments are treated relative /// to the test environment directory. - pub fn args>(&mut self, args: &[S]) -> Box<&mut UCommand> { + pub fn args>(&mut self, args: &[S]) -> &mut UCommand { if self.has_run { panic!(MULTIPLE_STDIN_MEANINGLESS); } @@ -543,25 +675,25 @@ impl UCommand { } self.raw.args(args.as_ref()); - Box::new(self) + self } /// provides stdinput to feed in to the command when spawned - pub fn pipe_in>>(&mut self, input: T) -> Box<&mut UCommand> { + pub fn pipe_in>>(&mut self, input: T) -> &mut UCommand { if self.stdin.is_some() { panic!(MULTIPLE_STDIN_MEANINGLESS); } self.stdin = Some(input.into()); - Box::new(self) + self } /// like pipe_in(...), but uses the contents of the file at the provided relative path as the piped in data - pub fn pipe_in_fixture>(&mut self, file_rel_path: S) -> Box<&mut UCommand> { + pub fn pipe_in_fixture>(&mut self, file_rel_path: S) -> &mut UCommand { let contents = read_scenario_fixture(&self.tmpd, file_rel_path); self.pipe_in(contents) } - pub fn env(&mut self, key: K, val: V) -> Box<&mut UCommand> + pub fn env(&mut self, key: K, val: V) -> &mut UCommand where K: AsRef, V: AsRef, @@ -570,7 +702,7 @@ impl UCommand { panic!(ALREADY_RUN); } self.raw.env(key, val); - Box::new(self) + self } /// Spawns the command, feeds the stdin if any, and returns the From 96643d6f918529891c1b8d43e000ea24a1bcd3ed Mon Sep 17 00:00:00 2001 From: Mikadore Date: Wed, 31 Mar 2021 12:54:16 +0200 Subject: [PATCH 051/132] fix #1970 (#1980) --- tests/common/util.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/common/util.rs b/tests/common/util.rs index 2cee36267..e13bdd3e6 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -358,7 +358,8 @@ impl AtPath { pub fn read(&self, name: &str) -> String { let mut f = self.open(name); let mut contents = String::new(); - let _ = f.read_to_string(&mut contents); + f.read_to_string(&mut contents) + .unwrap_or_else(|e| panic!("Couldn't read {}: {}", name, e)); contents } @@ -372,7 +373,8 @@ impl AtPath { pub fn write(&self, name: &str, contents: &str) { log_info("open(write)", self.plus_as_string(name)); - let _ = std::fs::write(self.plus(name), contents); + std::fs::write(self.plus(name), contents) + .unwrap_or_else(|e| panic!("Couldn't write {}: {}", name, e)); } pub fn write_bytes(&self, name: &str, contents: &[u8]) { @@ -388,7 +390,8 @@ impl AtPath { .append(true) .open(self.plus(name)) .unwrap(); - let _ = f.write(contents.as_bytes()); + f.write(contents.as_bytes()) + .unwrap_or_else(|e| panic!("Couldn't write {}: {}", name, e)); } pub fn append_bytes(&self, name: &str, contents: &[u8]) { @@ -781,7 +784,7 @@ pub fn read_size(child: &mut Child, size: usize) -> String { .stdout .as_mut() .unwrap() - .read(output.as_mut_slice()) + .read_exact(output.as_mut_slice()) .unwrap(); String::from_utf8(output).unwrap() } From b8079098f2824036bd683645a99354c3a7ec5e5f Mon Sep 17 00:00:00 2001 From: Mikadore Date: Wed, 31 Mar 2021 13:30:06 +0200 Subject: [PATCH 052/132] fixed panic! formatting --- tests/by-util/test_chmod.rs | 10 +++++----- tests/by-util/test_cp.rs | 4 ++-- tests/by-util/test_shuf.rs | 15 +++++++-------- tests/common/macros.rs | 6 +++--- tests/common/util.rs | 10 +++++----- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/tests/by-util/test_chmod.rs b/tests/by-util/test_chmod.rs index 78fee462d..b85567166 100644 --- a/tests/by-util/test_chmod.rs +++ b/tests/by-util/test_chmod.rs @@ -37,10 +37,10 @@ fn run_single_test(test: &TestCase, at: AtPath, mut ucmd: UCommand) { mkfile(&at.plus_as_string(TEST_FILE), test.before); let perms = at.metadata(TEST_FILE).permissions().mode(); if perms != test.before { - panic!(format!( + panic!( "{}: expected: {:o} got: {:o}", "setting permissions on test files before actual test run failed", test.after, perms - )); + ); } for arg in &test.args { @@ -49,15 +49,15 @@ fn run_single_test(test: &TestCase, at: AtPath, mut ucmd: UCommand) { let r = ucmd.run(); if !r.success { println!("{}", r.stderr); - panic!(format!("{:?}: failed", ucmd.raw)); + panic!("{:?}: failed", ucmd.raw); } let perms = at.metadata(TEST_FILE).permissions().mode(); if perms != test.after { - panic!(format!( + panic!( "{:?}: expected: {:o} got: {:o}", ucmd.raw, test.after, perms - )); + ); } } diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index a00ed2fd2..1fa8212ca 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1038,7 +1038,7 @@ fn test_cp_one_file_system() { .arg("tmpfs") .arg(mountpoint_path) .run(); - assert!(_r.code == Some(0), _r.stderr); + assert!(_r.code == Some(0), "{}", _r.stderr); at_src.touch(TEST_MOUNT_OTHER_FILESYSTEM_FILE); @@ -1052,7 +1052,7 @@ fn test_cp_one_file_system() { // Ditch the mount before the asserts let _r = scene.cmd("umount").arg(mountpoint_path).run(); - assert!(_r.code == Some(0), _r.stderr); + assert!(_r.code == Some(0), "{}", _r.stderr); assert!(result.success); assert!(!at_dst.file_exists(TEST_MOUNT_OTHER_FILESYSTEM_FILE)); diff --git a/tests/by-util/test_shuf.rs b/tests/by-util/test_shuf.rs index 065cef804..717971bd4 100644 --- a/tests/by-util/test_shuf.rs +++ b/tests/by-util/test_shuf.rs @@ -98,7 +98,8 @@ fn test_head_count() { assert_eq!(result_seq.len(), repeat_limit, "Output is not limited"); assert!( result_seq.iter().all(|x| input_seq.contains(x)), - format!("Output includes element not from input: {}", result) + "Output includes element not from input: {}", + result ) } @@ -133,13 +134,11 @@ fn test_repeat() { ); assert!( result_seq.iter().all(|x| input_seq.contains(x)), - format!( - "Output includes element not from input: {:?}", - result_seq - .iter() - .filter(|x| !input_seq.contains(x)) - .collect::>() - ) + "Output includes element not from input: {:?}", + result_seq + .iter() + .filter(|x| !input_seq.contains(x)) + .collect::>() ) } diff --git a/tests/common/macros.rs b/tests/common/macros.rs index 32ff7cbe8..e8b9c9d5d 100644 --- a/tests/common/macros.rs +++ b/tests/common/macros.rs @@ -5,7 +5,7 @@ macro_rules! assert_empty_stderr( ($cond:expr) => ( if $cond.stderr.len() > 0 { - panic!(format!("stderr: {}", $cond.stderr)) + panic!("stderr: {}", $cond.stderr_str()) } ); ); @@ -17,7 +17,7 @@ macro_rules! assert_empty_stderr( macro_rules! assert_empty_stdout( ($cond:expr) => ( if $cond.stdout.len() > 0 { - panic!(format!("stdout: {}", $cond.stdout)) + panic!("stdout: {}", $cond.stdout_str()) } ); ); @@ -30,7 +30,7 @@ macro_rules! assert_no_error( ($cond:expr) => ( assert!($cond.success); if $cond.stderr.len() > 0 { - panic!(format!("stderr: {}", $cond.stderr)) + panic!("stderr: {}", $cond.stderr_str()) } ); ); diff --git a/tests/common/util.rs b/tests/common/util.rs index e13bdd3e6..e4b452289 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -658,7 +658,7 @@ impl UCommand { /// to the test environment directory. pub fn arg>(&mut self, arg: S) -> &mut UCommand { if self.has_run { - panic!(ALREADY_RUN); + panic!("{}", ALREADY_RUN); } self.comm_string.push_str(" "); self.comm_string.push_str(arg.as_ref().to_str().unwrap()); @@ -670,7 +670,7 @@ impl UCommand { /// to the test environment directory. pub fn args>(&mut self, args: &[S]) -> &mut UCommand { if self.has_run { - panic!(MULTIPLE_STDIN_MEANINGLESS); + panic!("{}", MULTIPLE_STDIN_MEANINGLESS); } for s in args { self.comm_string.push_str(" "); @@ -684,7 +684,7 @@ impl UCommand { /// provides stdinput to feed in to the command when spawned pub fn pipe_in>>(&mut self, input: T) -> &mut UCommand { if self.stdin.is_some() { - panic!(MULTIPLE_STDIN_MEANINGLESS); + panic!("{}", MULTIPLE_STDIN_MEANINGLESS); } self.stdin = Some(input.into()); self @@ -702,7 +702,7 @@ impl UCommand { V: AsRef, { if self.has_run { - panic!(ALREADY_RUN); + panic!("{}", ALREADY_RUN); } self.raw.env(key, val); self @@ -712,7 +712,7 @@ impl UCommand { /// child process immediately. pub fn run_no_wait(&mut self) -> Child { if self.has_run { - panic!(ALREADY_RUN); + panic!("{}", ALREADY_RUN); } self.has_run = true; log_info("run", &self.comm_string); From 751ae6a8f857c6fd00eed5b571f6e3e36bbb360d Mon Sep 17 00:00:00 2001 From: Aleksandar Janicijevic Date: Wed, 31 Mar 2021 15:19:04 -0400 Subject: [PATCH 053/132] shred: use clap for argument management (#1961) --- Cargo.lock | 2 +- src/uu/shred/Cargo.toml | 2 +- src/uu/shred/src/shred.rs | 275 +++++++++++++++++++++----------------- 3 files changed, 158 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab8e59352..1caa4750d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2217,8 +2217,8 @@ dependencies = [ name = "uu_shred" version = "0.0.4" dependencies = [ + "clap", "filetime", - "getopts", "libc", "rand 0.5.6", "time", diff --git a/src/uu/shred/Cargo.toml b/src/uu/shred/Cargo.toml index 72e6119a8..6ff6e23ec 100644 --- a/src/uu/shred/Cargo.toml +++ b/src/uu/shred/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/shred.rs" [dependencies] +clap = "2.33" filetime = "0.2.1" -getopts = "0.2.18" libc = "0.2.42" rand = "0.5" time = "0.1.40" diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 4946ed35d..b54d3db45 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -8,6 +8,7 @@ // spell-checker:ignore (ToDO) NAMESET FILESIZE fstab coeff journaling writeback REiser journaled +use clap::{App, Arg}; use rand::{Rng, ThreadRng}; use std::cell::{Cell, RefCell}; use std::fs; @@ -212,138 +213,174 @@ impl<'a> BytesGenerator<'a> { } } +static ABOUT: &str = "Overwrite the specified FILE(s) repeatedly, in order to make it harder\n\ +for even very expensive hardware probing to recover the data. +"; + +fn get_usage() -> String { + format!("{} [OPTION]... FILE...", executable!()) +} + +static AFTER_HELP: &str = + "Delete FILE(s) if --remove (-u) is specified. The default is not to remove\n\ +the files because it is common to operate on device files like /dev/hda,\n\ +and those files usually should not be removed.\n\ +\n\ +CAUTION: Note that shred relies on a very important assumption:\n\ +that the file system overwrites data in place. This is the traditional\n\ +way to do things, but many modern file system designs do not satisfy this\n\ +assumption. The following are examples of file systems on which shred is\n\ +not effective, or is not guaranteed to be effective in all file system modes:\n\ +\n\ +* log-structured or journaled file systems, such as those supplied with\n\ +AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.)\n\ +\n\ +* file systems that write redundant data and carry on even if some writes\n\ +fail, such as RAID-based file systems\n\ +\n\ +* file systems that make snapshots, such as Network Appliance's NFS server\n\ +\n\ +* file systems that cache in temporary locations, such as NFS\n\ +version 3 clients\n\ +\n\ +* compressed file systems\n\ +\n\ +In the case of ext3 file systems, the above disclaimer applies\n\ +and shred is thus of limited effectiveness) only in data=journal mode,\n\ +which journals file data in addition to just metadata. In both the\n\ +data=ordered (default) and data=writeback modes, shred works as usual.\n\ +Ext3 journaling modes can be changed by adding the data=something option\n\ +to the mount options for a particular file system in the /etc/fstab file,\n\ +as documented in the mount man page (man mount).\n\ +\n\ +In addition, file system backups and remote mirrors may contain copies\n\ +of the file that cannot be removed, and that will allow a shredded file\n\ +to be recovered later.\n\ +"; + +pub mod options { + pub const FILE: &str = "file"; + pub const ITERATIONS: &str = "iterations"; + pub const SIZE: &str = "size"; + pub const REMOVE: &str = "remove"; + pub const VERBOSE: &str = "verbose"; + pub const EXACT: &str = "exact"; + pub const ZERO: &str = "zero"; +} + pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); - let mut opts = getopts::Options::new(); + let usage = get_usage(); - // TODO: Add force option - opts.optopt( - "n", - "iterations", - "overwrite N times instead of the default (3)", - "N", - ); - opts.optopt( - "s", - "size", - "shred this many bytes (suffixes like K, M, G accepted)", - "FILESIZE", - ); - opts.optflag( - "u", - "remove", - "truncate and remove the file after overwriting; See below", - ); - opts.optflag("v", "verbose", "show progress"); - opts.optflag( - "x", - "exact", - "do not round file sizes up to the next full block; \ - this is the default for non-regular files", - ); - opts.optflag( - "z", - "zero", - "add a final overwrite with zeros to hide shredding", - ); - opts.optflag("", "help", "display this help and exit"); - opts.optflag("", "version", "output version information and exit"); + let app = App::new(executable!()) + .version(VERSION_STR) + .about(ABOUT) + .after_help(AFTER_HELP) + .usage(&usage[..]) + .arg( + Arg::with_name(options::ITERATIONS) + .long(options::ITERATIONS) + .short("n") + .help("overwrite N times instead of the default (3)") + .value_name("NUMBER") + .default_value("3"), + ) + .arg( + Arg::with_name(options::SIZE) + .long(options::SIZE) + .short("s") + .takes_value(true) + .value_name("N") + .help("shred this many bytes (suffixes like K, M, G accepted)"), + ) + .arg( + Arg::with_name(options::REMOVE) + .short("u") + .long(options::REMOVE) + .help("truncate and remove file after overwriting; See below"), + ) + .arg( + Arg::with_name(options::VERBOSE) + .long(options::VERBOSE) + .short("v") + .help("show progress"), + ) + .arg( + Arg::with_name(options::EXACT) + .long(options::EXACT) + .short("x") + .help( + "do not round file sizes up to the next full block;\n\ +this is the default for non-regular files", + ), + ) + .arg( + Arg::with_name(options::ZERO) + .long(options::ZERO) + .short("z") + .help("add a final overwrite with zeros to hide shredding"), + ) + // Positional arguments + .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)); - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(e) => panic!("Invalid options\n{}", e), + let matches = app.get_matches_from(args); + + let mut errs: Vec = vec![]; + + if !matches.is_present(options::FILE) { + eprintln!("{}: Missing an argument", NAME); + eprintln!("For help, try '{} --help'", NAME); + return 0; + } + + let iterations = match matches.value_of(options::ITERATIONS) { + Some(s) => match s.parse::() { + Ok(u) => u, + Err(_) => { + errs.push(String::from(format!("invalid number of passes: '{}'", s))); + 0 + } + }, + None => unreachable!(), }; - if matches.opt_present("help") { - show_help(&opts); - return 0; - } else if matches.opt_present("version") { - println!("{} {}", NAME, VERSION_STR); - return 0; - } else if matches.free.is_empty() { - println!("{}: Missing an argument", NAME); - println!("For help, try '{} --help'", NAME); - return 0; - } else { - let iterations = match matches.opt_str("iterations") { - Some(s) => match s.parse::() { - Ok(u) => u, - Err(_) => { - println!("{}: Invalid number of passes", NAME); - return 1; - } - }, - None => 3, - }; - let remove = matches.opt_present("remove"); - let size = get_size(matches.opt_str("size")); - let exact = matches.opt_present("exact") && size.is_none(); // if -s is given, ignore -x - let zero = matches.opt_present("zero"); - let verbose = matches.opt_present("verbose"); - for path_str in matches.free.into_iter() { - wipe_file(&path_str, iterations, remove, size, exact, zero, verbose); + // TODO: implement --remove HOW + // The optional HOW parameter indicates how to remove a directory entry: + // - 'unlink' => use a standard unlink call. + // - 'wipe' => also first obfuscate bytes in the name. + // - 'wipesync' => also sync each obfuscated byte to disk. + // The default mode is 'wipesync', but note it can be expensive. + + // TODO: implement --random-source + + // TODO: implement --force + + let remove = matches.is_present(options::REMOVE); + let size_arg = match matches.value_of(options::SIZE) { + Some(s) => Some(s.to_string()), + None => None, + }; + let size = get_size(size_arg); + let exact = matches.is_present(options::EXACT) && size.is_none(); // if -s is given, ignore -x + let zero = matches.is_present(options::ZERO); + let verbose = matches.is_present(options::VERBOSE); + + if !errs.is_empty() { + eprintln!("Invalid arguments supplied."); + for message in errs { + eprintln!("{}", message); } + return 1; + } + + for path_str in matches.values_of(options::FILE).unwrap() { + wipe_file(&path_str, iterations, remove, size, exact, zero, verbose); } 0 } -fn show_help(opts: &getopts::Options) { - println!("Usage: {} [OPTION]... FILE...", NAME); - println!( - "Overwrite the specified FILE(s) repeatedly, in order to make it harder \ - for even very expensive hardware probing to recover the data." - ); - println!("{}", opts.usage("")); - println!("Delete FILE(s) if --remove (-u) is specified. The default is not to remove"); - println!("the files because it is common to operate on device files like /dev/hda,"); - println!("and those files usually should not be removed."); - println!(); - println!( - "CAUTION: Note that {} relies on a very important assumption:", - NAME - ); - println!("that the file system overwrites data in place. This is the traditional"); - println!("way to do things, but many modern file system designs do not satisfy this"); - println!( - "assumption. The following are examples of file systems on which {} is", - NAME - ); - println!("not effective, or is not guaranteed to be effective in all file system modes:"); - println!(); - println!("* log-structured or journaled file systems, such as those supplied with"); - println!("AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.)"); - println!(); - println!("* file systems that write redundant data and carry on even if some writes"); - println!("fail, such as RAID-based file systems"); - println!(); - println!("* file systems that make snapshots, such as Network Appliance's NFS server"); - println!(); - println!("* file systems that cache in temporary locations, such as NFS"); - println!("version 3 clients"); - println!(); - println!("* compressed file systems"); - println!(); - println!("In the case of ext3 file systems, the above disclaimer applies"); - println!( - "(and {} is thus of limited effectiveness) only in data=journal mode,", - NAME - ); - println!("which journals file data in addition to just metadata. In both the"); - println!( - "data=ordered (default) and data=writeback modes, {} works as usual.", - NAME - ); - println!("Ext3 journaling modes can be changed by adding the data=something option"); - println!("to the mount options for a particular file system in the /etc/fstab file,"); - println!("as documented in the mount man page (man mount)."); - println!(); - println!("In addition, file system backups and remote mirrors may contain copies"); - println!("of the file that cannot be removed, and that will allow a shredded file"); - println!("to be recovered later."); -} - // TODO: Add support for all postfixes here up to and including EiB // http://www.gnu.org/software/coreutils/manual/coreutils.html#Block-size fn get_size(size_str_opt: Option) -> Option { From e958864bd9aaf2f90f8d78f09f8281b47519150a Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Wed, 31 Mar 2021 22:21:10 +0300 Subject: [PATCH 054/132] tac: exit with proper code, move from getopts to clap, add test for invalid inputs (#1957) --- Cargo.lock | 6 +- src/uu/tac/Cargo.toml | 2 +- src/uu/tac/src/tac.rs | 136 ++++++++++++++++++++------------------ tests/by-util/test_tac.rs | 18 +++++ 4 files changed, 95 insertions(+), 67 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1caa4750d..08a7bad43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2323,9 +2323,9 @@ dependencies = [ name = "uu_tac" version = "0.0.4" dependencies = [ - "getopts", - "uucore", - "uucore_procs", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.7", + "uucore_procs 0.0.5", ] [[package]] diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index 15e743006..2e54c129e 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/tac.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/tac/src/tac.rs b/src/uu/tac/src/tac.rs index 843babac9..68dae94e2 100644 --- a/src/uu/tac/src/tac.rs +++ b/src/uu/tac/src/tac.rs @@ -10,79 +10,77 @@ #[macro_use] extern crate uucore; -use std::fs::File; +use clap::{App, Arg}; use std::io::{stdin, stdout, BufReader, Read, Stdout, Write}; +use std::{fs::File, path::Path}; static NAME: &str = "tac"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static USAGE: &str = "[OPTION]... [FILE]..."; +static SUMMARY: &str = "Write each file to standard output, last line first."; + +mod options { + pub static BEFORE: &str = "before"; + pub static REGEX: &str = "regex"; + pub static SEPARATOR: &str = "separator"; + pub static FILE: &str = "file"; +} pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); - let mut opts = getopts::Options::new(); + let matches = App::new(executable!()) + .name(NAME) + .version(VERSION) + .usage(USAGE) + .about(SUMMARY) + .arg( + Arg::with_name(options::BEFORE) + .short("b") + .long(options::BEFORE) + .help("attach the separator before instead of after") + .takes_value(false), + ) + .arg( + Arg::with_name(options::REGEX) + .short("r") + .long(options::REGEX) + .help("interpret the sequence as a regular expression (NOT IMPLEMENTED)") + .takes_value(false), + ) + .arg( + Arg::with_name(options::SEPARATOR) + .short("s") + .long(options::SEPARATOR) + .help("use STRING as the separator instead of newline") + .takes_value(true), + ) + .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) + .get_matches_from(args); - opts.optflag( - "b", - "before", - "attach the separator before instead of after", - ); - opts.optflag( - "r", - "regex", - "interpret the sequence as a regular expression (NOT IMPLEMENTED)", - ); - opts.optopt( - "s", - "separator", - "use STRING as the separator instead of newline", - "STRING", - ); - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("V", "version", "output version information and exit"); - - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => crash!(1, "{}", f), - }; - if matches.opt_present("help") { - let msg = format!( - "{0} {1} - -Usage: - {0} [OPTION]... [FILE]... - -Write each file to standard output, last line first.", - NAME, VERSION - ); - - print!("{}", opts.usage(&msg)); - } else if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - } else { - let before = matches.opt_present("b"); - let regex = matches.opt_present("r"); - let separator = match matches.opt_str("s") { - Some(m) => { - if m.is_empty() { - crash!(1, "separator cannot be empty") - } else { - m - } + let before = matches.is_present(options::BEFORE); + let regex = matches.is_present(options::REGEX); + let separator = match matches.value_of(options::SEPARATOR) { + Some(m) => { + if m.is_empty() { + crash!(1, "separator cannot be empty") + } else { + m.to_owned() } - None => "\n".to_owned(), - }; - let files = if matches.free.is_empty() { - vec!["-".to_owned()] - } else { - matches.free - }; - tac(files, before, regex, &separator[..]); - } + } + None => "\n".to_owned(), + }; - 0 + let files: Vec = match matches.values_of(options::FILE) { + Some(v) => v.map(|v| v.to_owned()).collect(), + None => vec!["-".to_owned()], + }; + + tac(files, before, regex, &separator[..]) } -fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { +fn tac(filenames: Vec, before: bool, _: bool, separator: &str) -> i32 { + let mut exit_code = 0; let mut out = stdout(); let sbytes = separator.as_bytes(); let slen = sbytes.len(); @@ -91,10 +89,19 @@ fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { let mut file = BufReader::new(if filename == "-" { Box::new(stdin()) as Box } else { - match File::open(filename) { + let path = Path::new(filename); + if path.is_dir() || !path.metadata().is_ok() { + show_error!( + "failed to open '{}' for reading: No such file or directory", + filename + ); + continue; + } + match File::open(path) { Ok(f) => Box::new(f) as Box, Err(e) => { - show_warning!("failed to open '{}' for reading: {}", filename, e); + show_error!("failed to open '{}' for reading: {}", filename, e); + exit_code = 1; continue; } } @@ -102,7 +109,8 @@ fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { let mut data = Vec::new(); if let Err(e) = file.read_to_end(&mut data) { - show_warning!("failed to read '{}': {}", filename, e); + show_error!("failed to read '{}': {}", filename, e); + exit_code = 1; continue; }; @@ -141,6 +149,8 @@ fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { } show_line(&mut out, sbytes, &data[0..prev], before); } + + exit_code } fn show_line(out: &mut Stdout, sep: &[u8], dat: &[u8], before: bool) { diff --git a/tests/by-util/test_tac.rs b/tests/by-util/test_tac.rs index d46f9aec6..3733adbec 100644 --- a/tests/by-util/test_tac.rs +++ b/tests/by-util/test_tac.rs @@ -49,3 +49,21 @@ fn test_single_non_newline_separator_before() { .run() .stdout_is_fixture("delimited_primes_before.expected"); } + +#[test] +fn test_invalid_input() { + let (_, mut ucmd) = at_and_ucmd!(); + + ucmd.arg("b") + .run() + .stderr + .contains("tac: error: failed to open 'b' for reading"); + + let (at, mut ucmd) = at_and_ucmd!(); + + at.mkdir("a"); + ucmd.arg("a") + .run() + .stderr + .contains("tac: error: failed to read 'a'"); +} From 7669a4387af52d0a4f979618ef7ce7eb98af5113 Mon Sep 17 00:00:00 2001 From: Alessandro Stoltenberg Date: Wed, 31 Mar 2021 22:27:24 +0200 Subject: [PATCH 055/132] echo: Some minor changes to options (#1960) --- src/uu/echo/src/echo.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/uu/echo/src/echo.rs b/src/uu/echo/src/echo.rs index c991f5d3f..1e0c04d1d 100644 --- a/src/uu/echo/src/echo.rs +++ b/src/uu/echo/src/echo.rs @@ -14,10 +14,10 @@ use std::io::{self, Write}; use std::iter::Peekable; use std::str::Chars; -static NAME: &str = "echo"; -static USAGE: &str = "[OPTIONS]... [STRING]..."; -static SUMMARY: &str = "display a line of text"; -static AFTER_HELP: &str = r#" +const NAME: &str = "echo"; +const SUMMARY: &str = "display a line of text"; +const USAGE: &str = "[OPTIONS]... [STRING]..."; +const AFTER_HELP: &str = r#" Echo the STRING(s) to standard output. If -e is in effect, the following sequences are recognized: @@ -36,11 +36,12 @@ static AFTER_HELP: &str = r#" \\xHH byte with hexadecimal value HH (1 to 2 digits) "#; + mod options { - pub static STRING: &str = "STRING"; - pub static NO_NEWLINE: &str = "no_newline"; - pub static ENABLE_BACKSLASH_ESCAPE: &str = "enable_backslash_escape"; - pub static DISABLE_BACKSLASH_ESCAPE: &str = "disable_backslash_escape"; + pub const STRING: &str = "STRING"; + pub const NO_NEWLINE: &str = "no_newline"; + pub const ENABLE_BACKSLASH_ESCAPE: &str = "enable_backslash_escape"; + pub const DISABLE_BACKSLASH_ESCAPE: &str = "disable_backslash_escape"; } fn parse_code( @@ -113,8 +114,6 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result { } pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); - let matches = App::new(executable!()) .name(NAME) // TrailingVarArg specifies the final positional argument is a VarArg @@ -123,9 +122,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .setting(clap::AppSettings::TrailingVarArg) .setting(clap::AppSettings::AllowLeadingHyphen) .version(crate_version!()) - .usage(USAGE) .about(SUMMARY) .after_help(AFTER_HELP) + .usage(USAGE) .arg( Arg::with_name(options::NO_NEWLINE) .short("n") @@ -149,7 +148,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 { ) .arg( Arg::with_name(options::STRING) - .hidden(true) .multiple(true) .allow_hyphen_values(true), ) From bb3e93372f82b85f9fcc26e485892dab32b96ec5 Mon Sep 17 00:00:00 2001 From: Mikadore Date: Thu, 1 Apr 2021 02:16:15 +0200 Subject: [PATCH 056/132] od: refactor tests for #1982 --- tests/by-util/test_od.rs | 484 +++++++++++++++++---------------------- 1 file changed, 209 insertions(+), 275 deletions(-) diff --git a/tests/by-util/test_od.rs b/tests/by-util/test_od.rs index f3b766c26..b49e6f0ca 100644 --- a/tests/by-util/test_od.rs +++ b/tests/by-util/test_od.rs @@ -21,6 +21,7 @@ static ALPHA_OUT: &'static str = " // Test that od can read one file and dump with default format #[test] fn test_file() { + // TODO: Can this be replaced by AtPath? use std::env; let temp = env::temp_dir(); let tmpdir = Path::new(&temp); @@ -33,15 +34,12 @@ fn test_file() { } } - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg(file.as_os_str()) - .run(); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, unindent(ALPHA_OUT)); - + .succeeds() + .no_stderr() + .stdout_is(unindent(ALPHA_OUT)); let _ = remove_file(file); } @@ -64,16 +62,14 @@ fn test_2files() { } } - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg(file1.as_os_str()) .arg(file2.as_os_str()) - .run(); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, unindent(ALPHA_OUT)); - + .succeeds() + .no_stderr() + .stdout_is(unindent(ALPHA_OUT)); + // TODO: Handle errors? let _ = remove_file(file1); let _ = remove_file(file2); } @@ -85,22 +81,19 @@ fn test_no_file() { let tmpdir = Path::new(&temp); let file = tmpdir.join("}surely'none'would'thus'a'file'name"); - let result = new_ucmd!().arg(file.as_os_str()).run(); - - assert!(!result.success); + new_ucmd!().arg(file.as_os_str()).fails(); } // Test that od reads from stdin instead of a file #[test] fn test_from_stdin() { let input = "abcdefghijklmnopqrstuvwxyz\n"; - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") - .run_piped_stdin(input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, unindent(ALPHA_OUT)); + .run_piped_stdin(input.as_bytes()) + .success() + .no_stderr() + .stdout_is(unindent(ALPHA_OUT)); } // Test that od reads from stdin and also from files @@ -119,40 +112,35 @@ fn test_from_mixed() { } } - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg(file1.as_os_str()) .arg("-") .arg(file3.as_os_str()) - .run_piped_stdin(data2.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, unindent(ALPHA_OUT)); + .run_piped_stdin(data2.as_bytes()) + .success() + .no_stderr() + .stdout_is(unindent(ALPHA_OUT)); } #[test] fn test_multiple_formats() { let input = "abcdefghijklmnopqrstuvwxyz\n"; - let result = new_ucmd!() + new_ucmd!() .arg("-c") .arg("-b") - .run_piped_stdin(input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + .run_piped_stdin(input.as_bytes()) + .success() + .no_stderr() + .stdout_is(unindent( " 0000000 a b c d e f g h i j k l m n o p 141 142 143 144 145 146 147 150 151 152 153 154 155 156 157 160 0000020 q r s t u v w x y z \\n 161 162 163 164 165 166 167 170 171 172 012 0000033 - " - ) - ); + ", + )); } #[test] @@ -166,14 +154,13 @@ fn test_dec() { 0000016 ", ); - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg("-s") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .success() + .no_stderr() + .stdout_is(expected_output); } #[test] @@ -185,14 +172,13 @@ fn test_hex16() { 0000011 ", ); - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg("-x") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .success() + .no_stderr() + .stdout_is(expected_output); } #[test] @@ -204,14 +190,13 @@ fn test_hex32() { 0000011 ", ); - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg("-X") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .success() + .no_stderr() + .stdout_is(expected_output); } #[test] @@ -232,15 +217,14 @@ fn test_f16() { 0000016 ", ); - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg("-tf2") .arg("-w8") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .success() + .no_stderr() + .stdout_is(expected_output); } #[test] @@ -261,14 +245,13 @@ fn test_f32() { 0000034 ", ); - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg("-f") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .success() + .no_stderr() + .stdout_is(expected_output); } #[test] @@ -291,36 +274,31 @@ fn test_f64() { 0000050 ", ); - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg("-F") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .success() + .no_stderr() + .stdout_is(expected_output); } #[test] fn test_multibyte() { - let result = new_ucmd!() + new_ucmd!() .arg("-c") .arg("-w12") - .run_piped_stdin("Universität Tübingen \u{1B000}".as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + .run_piped_stdin("Universität Tübingen \u{1B000}".as_bytes()) + .success() + .no_stderr() + .stdout_is(unindent( " 0000000 U n i v e r s i t ä ** t 0000014 T ü ** b i n g e n \u{1B000} 0000030 ** ** ** 0000033 - " - ) - ); + ", + )); } #[test] @@ -334,11 +312,13 @@ fn test_width() { ", ); - let result = new_ucmd!().arg("-w4").arg("-v").run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + new_ucmd!() + .arg("-w4") + .arg("-v") + .run_piped_stdin(&input[..]) + .success() + .no_stderr() + .stdout_is(expected_output); } #[test] @@ -352,14 +332,13 @@ fn test_invalid_width() { ", ); - let result = new_ucmd!().arg("-w5").arg("-v").run_piped_stdin(&input[..]); - - assert_eq!( - result.stderr, - "od: warning: invalid width 5; using 2 instead\n" - ); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + new_ucmd!() + .arg("-w5") + .arg("-v") + .run_piped_stdin(&input[..]) + .success() + .stderr_is_bytes("od: warning: invalid width 5; using 2 instead\n".as_bytes()) + .stdout_is(expected_output); } #[test] @@ -373,14 +352,13 @@ fn test_zero_width() { ", ); - let result = new_ucmd!().arg("-w0").arg("-v").run_piped_stdin(&input[..]); - - assert_eq!( - result.stderr, - "od: warning: invalid width 0; using 2 instead\n" - ); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + new_ucmd!() + .arg("-w0") + .arg("-v") + .run_piped_stdin(&input[..]) + .success() + .stderr_is_bytes("od: warning: invalid width 0; using 2 instead\n".as_bytes()) + .stdout_is(expected_output); } #[test] @@ -392,11 +370,12 @@ fn test_width_without_value() { 0000050 "); - let result = new_ucmd!().arg("-w").run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + new_ucmd!() + .arg("-w") + .run_piped_stdin(&input[..]) + .success() + .no_stderr() + .stdout_is(expected_output); } #[test] @@ -421,15 +400,14 @@ fn test_suppress_duplicates() { ", ); - let result = new_ucmd!() + new_ucmd!() .arg("-w4") .arg("-O") .arg("-x") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .no_stderr() + .success() + .stdout_is(expected_output); } #[test] @@ -446,17 +424,16 @@ fn test_big_endian() { ", ); - let result = new_ucmd!() + new_ucmd!() .arg("--endian=big") .arg("-F") .arg("-f") .arg("-X") .arg("-x") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .no_stderr() + .success() + .stdout_is(expected_output); } #[test] @@ -474,16 +451,15 @@ fn test_alignment_Xxa() { ); // in this case the width of the -a (8-bit) determines the alignment for the other fields - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg("-X") .arg("-x") .arg("-a") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .no_stderr() + .success() + .stdout_is(expected_output); } #[test] @@ -500,15 +476,14 @@ fn test_alignment_Fx() { ); // in this case the width of the -F (64-bit) determines the alignment for the other field - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg("-F") .arg("-x") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .no_stderr() + .success() + .stdout_is(expected_output); } #[test] @@ -528,16 +503,15 @@ fn test_maxuint() { ", ); - let result = new_ucmd!() + new_ucmd!() .arg("--format=o8") .arg("-Oobtu8") .arg("-Dd") .arg("--format=u1") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .no_stderr() + .success() + .stdout_is(expected_output); } #[test] @@ -553,15 +527,14 @@ fn test_hex_offset() { ", ); - let result = new_ucmd!() + new_ucmd!() .arg("-Ax") .arg("-X") .arg("-X") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .no_stderr() + .success() + .stdout_is(expected_output); } #[test] @@ -577,15 +550,14 @@ fn test_dec_offset() { ", ); - let result = new_ucmd!() + new_ucmd!() .arg("-Ad") .arg("-X") .arg("-X") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .no_stderr() + .success() + .stdout_is(expected_output); } #[test] @@ -594,66 +566,57 @@ fn test_no_offset() { const LINE: &'static str = " 00000000 00000000 00000000 00000000\n"; let expected_output = [LINE, LINE, LINE, LINE].join(""); - let result = new_ucmd!() + new_ucmd!() .arg("-An") .arg("-X") .arg("-X") - .run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, expected_output); + .run_piped_stdin(&input[..]) + .no_stderr() + .success() + .stdout_is(expected_output); } #[test] fn test_invalid_offset() { - let result = new_ucmd!().arg("-Ab").run(); - - assert!(!result.success); + new_ucmd!().arg("-Ab").fails(); } #[test] fn test_skip_bytes() { let input = "abcdefghijklmnopq"; - let result = new_ucmd!() + new_ucmd!() .arg("-c") .arg("--skip-bytes=5") - .run_piped_stdin(input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + .run_piped_stdin(input.as_bytes()) + .no_stderr() + .success() + .stdout_is(unindent( " 0000005 f g h i j k l m n o p q 0000021 - " - ) - ); + ", + )); } #[test] fn test_skip_bytes_error() { let input = "12345"; - let result = new_ucmd!() + new_ucmd!() .arg("--skip-bytes=10") - .run_piped_stdin(input.as_bytes()); - - assert!(!result.success); + .run_piped_stdin(input.as_bytes()) + .failure(); } #[test] fn test_read_bytes() { let input = "abcdefghijklmnopqrstuvwxyz\n12345678"; - let result = new_ucmd!() + new_ucmd!() .arg("--endian=little") .arg("--read-bytes=27") - .run_piped_stdin(input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, unindent(ALPHA_OUT)); + .run_piped_stdin(input.as_bytes()) + .no_stderr() + .success() + .stdout_is(unindent(ALPHA_OUT)); } #[test] @@ -662,13 +625,12 @@ fn test_ascii_dump() { 0x00, 0x01, 0x0a, 0x0d, 0x10, 0x1f, 0x20, 0x61, 0x62, 0x63, 0x7d, 0x7e, 0x7f, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff, ]; - let result = new_ucmd!().arg("-tx1zacz").run_piped_stdin(&input[..]); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + new_ucmd!() + .arg("-tx1zacz") + .run_piped_stdin(&input[..]) + .no_stderr() + .success() + .stdout_is(unindent( r" 0000000 00 01 0a 0d 10 1f 20 61 62 63 7d 7e 7f 80 90 a0 >...... abc}~....< nul soh nl cr dle us sp a b c } ~ del nul dle sp @@ -677,9 +639,8 @@ fn test_ascii_dump() { 0 @ P ` p del ** 300 320 340 360 377 >......< 0000026 - " - ) - ); + ", + )); } #[test] @@ -687,159 +648,136 @@ fn test_filename_parsing() { // files "a" and "x" both exists, but are no filenames in the commandline below // "-f" must be treated as a filename, it contains the text: minus lowercase f // so "-f" should not be interpreted as a formatting option. - let result = new_ucmd!() + new_ucmd!() .arg("--format") .arg("a") .arg("-A") .arg("x") .arg("--") .arg("-f") - .run(); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + .succeeds() + .no_stderr() + .stdout_is(unindent( " 000000 m i n u s sp l o w e r c a s e sp 000010 f nl 000012 - " - ) - ); + ", + )); } #[test] fn test_stdin_offset() { let input = "abcdefghijklmnopq"; - let result = new_ucmd!() + new_ucmd!() .arg("-c") .arg("+5") - .run_piped_stdin(input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + .run_piped_stdin(input.as_bytes()) + .no_stderr() + .success() + .stdout_is(unindent( " 0000005 f g h i j k l m n o p q 0000021 - " - ) - ); + ", + )); } #[test] fn test_file_offset() { - let result = new_ucmd!().arg("-c").arg("--").arg("-f").arg("10").run(); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + new_ucmd!() + .arg("-c") + .arg("--") + .arg("-f") + .arg("10") + .succeeds() + .no_stderr() + .stdout_is(unindent( r" 0000010 w e r c a s e f \n 0000022 - " - ) - ); + ", + )); } #[test] fn test_traditional() { // note gnu od does not align both lines let input = "abcdefghijklmnopq"; - let result = new_ucmd!() + new_ucmd!() .arg("--traditional") .arg("-a") .arg("-c") .arg("-") .arg("10") .arg("0") - .run_piped_stdin(input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + .run_piped_stdin(input.as_bytes()) + .no_stderr() + .success() + .stdout_is(unindent( r" 0000010 (0000000) i j k l m n o p q i j k l m n o p q 0000021 (0000011) - " - ) - ); + ", + )); } #[test] fn test_traditional_with_skip_bytes_override() { // --skip-bytes is ignored in this case let input = "abcdefghijklmnop"; - let result = new_ucmd!() + new_ucmd!() .arg("--traditional") .arg("--skip-bytes=10") .arg("-c") .arg("0") - .run_piped_stdin(input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + .run_piped_stdin(input.as_bytes()) + .no_stderr() + .success() + .stdout_is(unindent( r" 0000000 a b c d e f g h i j k l m n o p 0000020 - " - ) - ); + ", + )); } #[test] fn test_traditional_with_skip_bytes_non_override() { // no offset specified in the traditional way, so --skip-bytes is used let input = "abcdefghijklmnop"; - let result = new_ucmd!() + new_ucmd!() .arg("--traditional") .arg("--skip-bytes=10") .arg("-c") - .run_piped_stdin(input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + .run_piped_stdin(input.as_bytes()) + .no_stderr() + .success() + .stdout_is(unindent( r" 0000012 k l m n o p 0000020 - " - ) - ); + ", + )); } #[test] fn test_traditional_error() { // file "0" exists - don't fail on that, but --traditional only accepts a single input - let result = new_ucmd!() + new_ucmd!() .arg("--traditional") .arg("0") .arg("0") .arg("0") .arg("0") - .run(); - - assert!(!result.success); + .fails(); } #[test] fn test_traditional_only_label() { let input = "abcdefghijklmnopqrstuvwxyz"; - let result = new_ucmd!() + new_ucmd!() .arg("-An") .arg("--traditional") .arg("-a") @@ -847,20 +785,16 @@ fn test_traditional_only_label() { .arg("-") .arg("10") .arg("0x10") - .run_piped_stdin(input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!( - result.stdout, - unindent( + .run_piped_stdin(input.as_bytes()) + .no_stderr() + .success() + .stdout_is(unindent( r" (0000020) i j k l m n o p q r s t u v w x i j k l m n o p q r s t u v w x (0000040) y z y z (0000042) - " - ) - ); + ", + )); } From cf4970f083d13887c49625acbece22eb761c0181 Mon Sep 17 00:00:00 2001 From: Aleksandar Janicijevic Date: Thu, 1 Apr 2021 02:53:48 -0400 Subject: [PATCH 057/132] shred: Replaced eprintln with show_error (#1992) --- Cargo.lock | 6 +++--- src/uu/shred/src/shred.rs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08a7bad43..e273f776c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2323,9 +2323,9 @@ dependencies = [ name = "uu_tac" version = "0.0.4" dependencies = [ - "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.7", - "uucore_procs 0.0.5", + "clap", + "uucore", + "uucore_procs", ] [[package]] diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index b54d3db45..f9d8b9c73 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -329,8 +329,8 @@ this is the default for non-regular files", let mut errs: Vec = vec![]; if !matches.is_present(options::FILE) { - eprintln!("{}: Missing an argument", NAME); - eprintln!("For help, try '{} --help'", NAME); + show_error!("Missing an argument"); + show_error!("For help, try '{} --help'", NAME); return 0; } @@ -367,9 +367,9 @@ this is the default for non-regular files", let verbose = matches.is_present(options::VERBOSE); if !errs.is_empty() { - eprintln!("Invalid arguments supplied."); + show_error!("Invalid arguments supplied."); for message in errs { - eprintln!("{}", message); + show_error!("{}", message); } return 1; } From 2941dfd698d19095da56f73f7052a9790d39bd82 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Thu, 1 Apr 2021 22:50:13 +0200 Subject: [PATCH 058/132] ls: quoting style (#1989) --- src/uu/ls/src/ls.rs | 110 ++++++- src/uu/ls/src/quoting_style.rs | 542 +++++++++++++++++++++++++++++++++ tests/by-util/test_ls.rs | 87 ++++++ 3 files changed, 737 insertions(+), 2 deletions(-) create mode 100644 src/uu/ls/src/quoting_style.rs diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 80a7bf328..9633acf43 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -13,10 +13,12 @@ extern crate lazy_static; #[macro_use] extern crate uucore; +mod quoting_style; mod version_cmp; use clap::{App, Arg}; use number_prefix::NumberPrefix; +use quoting_style::{escape_name, QuotingStyle}; #[cfg(unix)] use std::collections::HashMap; use std::fs; @@ -104,6 +106,12 @@ pub mod options { pub static HUMAN_READABLE: &str = "human-readable"; pub static SI: &str = "si"; } + pub mod quoting { + pub static ESCAPE: &str = "escape"; + pub static LITERAL: &str = "literal"; + pub static C: &str = "quote-name"; + } + pub static QUOTING_STYLE: &str = "quoting-style"; pub mod indicator_style { pub static NONE: &str = "none"; @@ -193,6 +201,7 @@ struct Config { color: bool, long: LongFormat, width: Option, + quoting_style: QuotingStyle, indicator_style: IndicatorStyle, } @@ -359,6 +368,51 @@ impl Config { }) .or_else(|| termsize::get().map(|s| s.cols)); + let quoting_style = if let Some(style) = options.value_of(options::QUOTING_STYLE) { + match style { + "literal" => QuotingStyle::Literal, + "shell" => QuotingStyle::Shell { + escape: false, + always_quote: false, + }, + "shell-always" => QuotingStyle::Shell { + escape: false, + always_quote: true, + }, + "shell-escape" => QuotingStyle::Shell { + escape: true, + always_quote: false, + }, + "shell-escape-always" => QuotingStyle::Shell { + escape: true, + always_quote: true, + }, + "c" => QuotingStyle::C { + quotes: quoting_style::Quotes::Double, + }, + "escape" => QuotingStyle::C { + quotes: quoting_style::Quotes::None, + }, + _ => unreachable!("Should have been caught by Clap"), + } + } else if options.is_present(options::quoting::LITERAL) { + QuotingStyle::Literal + } else if options.is_present(options::quoting::ESCAPE) { + QuotingStyle::C { + quotes: quoting_style::Quotes::None, + } + } else if options.is_present(options::quoting::C) { + QuotingStyle::C { + quotes: quoting_style::Quotes::Double, + } + } else { + // TODO: use environment variable if available + QuotingStyle::Shell { + escape: true, + always_quote: false, + } + }; + let indicator_style = if let Some(field) = options.value_of(options::INDICATOR_STYLE) { match field { "none" => IndicatorStyle::None, @@ -402,6 +456,7 @@ impl Config { inode: options.is_present(options::INODE), long, width, + quoting_style, indicator_style, } } @@ -515,6 +570,57 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .multiple(true) ) + // Quoting style + .arg( + Arg::with_name(options::QUOTING_STYLE) + .long(options::QUOTING_STYLE) + .takes_value(true) + .help("Set quoting style.") + .possible_values(&["literal", "shell", "shell-always", "shell-escape", "shell-escape-always", "c", "escape"]) + .overrides_with_all(&[ + options::QUOTING_STYLE, + options::quoting::LITERAL, + options::quoting::ESCAPE, + options::quoting::C, + ]) + ) + .arg( + Arg::with_name(options::quoting::LITERAL) + .short("N") + .long(options::quoting::LITERAL) + .help("Use literal quoting style. Equivalent to `--quoting-style=literal`") + .overrides_with_all(&[ + options::QUOTING_STYLE, + options::quoting::LITERAL, + options::quoting::ESCAPE, + options::quoting::C, + ]) + ) + .arg( + Arg::with_name(options::quoting::ESCAPE) + .short("b") + .long(options::quoting::ESCAPE) + .help("Use escape quoting style. Equivalent to `--quoting-style=escape`") + .overrides_with_all(&[ + options::QUOTING_STYLE, + options::quoting::LITERAL, + options::quoting::ESCAPE, + options::quoting::C, + ]) + ) + .arg( + Arg::with_name(options::quoting::C) + .short("Q") + .long(options::quoting::C) + .help("Use C quoting style. Equivalent to `--quoting-style=c`") + .overrides_with_all(&[ + options::QUOTING_STYLE, + options::quoting::LITERAL, + options::quoting::ESCAPE, + options::quoting::C, + ]) + ) + // Time arguments .arg( Arg::with_name(options::TIME) @@ -1206,7 +1312,7 @@ fn display_file_name( metadata: &Metadata, config: &Config, ) -> Cell { - let mut name = get_file_name(path, strip); + let mut name = escape_name(get_file_name(path, strip), &config.quoting_style); let file_type = metadata.file_type(); match config.indicator_style { @@ -1273,7 +1379,7 @@ fn display_file_name( metadata: &Metadata, config: &Config, ) -> Cell { - let mut name = get_file_name(path, strip); + let mut name = escape_name(get_file_name(path, strip), &config.quoting_style); if config.format != Format::Long && config.inode { name = get_inode(metadata) + " " + &name; } diff --git a/src/uu/ls/src/quoting_style.rs b/src/uu/ls/src/quoting_style.rs new file mode 100644 index 000000000..74108094a --- /dev/null +++ b/src/uu/ls/src/quoting_style.rs @@ -0,0 +1,542 @@ +use std::char::from_digit; + +const SPECIAL_SHELL_CHARS: &str = "~`#$&*()\\|[]{};'\"<>?! "; + +pub(crate) enum QuotingStyle { + Shell { escape: bool, always_quote: bool }, + C { quotes: Quotes }, + Literal, +} + +#[derive(Clone, Copy)] +pub(crate) enum Quotes { + None, + Single, + Double, + // TODO: Locale +} + +// This implementation is heavily inspired by the std::char::EscapeDefault implementation +// in the Rust standard library. This custom implementation is needed because the +// characters \a, \b, \e, \f & \v are not recognized by Rust. +#[derive(Clone, Debug)] +struct EscapedChar { + state: EscapeState, +} + +#[derive(Clone, Debug)] +enum EscapeState { + Done, + Char(char), + Backslash(char), + ForceQuote(char), + Octal(EscapeOctal), +} + +#[derive(Clone, Debug)] +struct EscapeOctal { + c: char, + state: EscapeOctalState, + idx: usize, +} + +#[derive(Clone, Debug)] +enum EscapeOctalState { + Done, + Backslash, + Value, +} + +impl Iterator for EscapeOctal { + type Item = char; + + fn next(&mut self) -> Option { + match self.state { + EscapeOctalState::Done => None, + EscapeOctalState::Backslash => { + self.state = EscapeOctalState::Value; + Some('\\') + } + EscapeOctalState::Value => { + let octal_digit = ((self.c as u32) >> (self.idx * 3)) & 0o7; + if self.idx == 0 { + self.state = EscapeOctalState::Done; + } else { + self.idx -= 1; + } + Some(from_digit(octal_digit, 8).unwrap()) + } + } + } +} + +impl EscapeOctal { + fn from(c: char) -> EscapeOctal { + EscapeOctal { + c, + idx: 2, + state: EscapeOctalState::Backslash, + } + } +} + +impl EscapedChar { + fn new_c(c: char, quotes: Quotes) -> Self { + use EscapeState::*; + let init_state = match c { + '\x07' => Backslash('a'), + '\x08' => Backslash('b'), + '\t' => Backslash('t'), + '\n' => Backslash('n'), + '\x0B' => Backslash('v'), + '\x0C' => Backslash('f'), + '\r' => Backslash('r'), + '\\' => Backslash('\\'), + '\'' => match quotes { + Quotes::Single => Backslash('\''), + _ => Char('\''), + }, + '"' => match quotes { + Quotes::Double => Backslash('"'), + _ => Char('"'), + }, + ' ' => match quotes { + Quotes::None => Backslash(' '), + _ => Char(' '), + }, + _ if c.is_ascii_control() => Octal(EscapeOctal::from(c)), + _ => Char(c), + }; + Self { state: init_state } + } + + // fn new_shell(c: char, quotes: Quotes) -> Self { + // use EscapeState::*; + // let init_state = match c { + // // If the string is single quoted, the single quote should be escaped + // '\'' => match quotes { + // Quotes::Single => Backslash('\''), + // _ => Char('\''), + // }, + // // All control characters should be rendered as ?: + // _ if c.is_ascii_control() => Char('?'), + // // Special shell characters must be escaped: + // _ if SPECIAL_SHELL_CHARS.contains(c) => ForceQuote(c), + // _ => Char(c), + // }; + // Self { state: init_state } + // } + + fn new_shell(c: char, escape: bool, quotes: Quotes) -> Self { + use EscapeState::*; + let init_state = match c { + _ if !escape && c.is_control() => Char('?'), + '\x07' => Backslash('a'), + '\x08' => Backslash('b'), + '\t' => Backslash('t'), + '\n' => Backslash('n'), + '\x0B' => Backslash('v'), + '\x0C' => Backslash('f'), + '\r' => Backslash('r'), + '\\' => Backslash('\\'), + '\x00'..='\x1F' | '\x7F' => Octal(EscapeOctal::from(c)), + '\'' => match quotes { + Quotes::Single => Backslash('\''), + _ => Char('\''), + }, + _ if SPECIAL_SHELL_CHARS.contains(c) => ForceQuote(c), + _ => Char(c), + }; + Self { state: init_state } + } +} + +impl Iterator for EscapedChar { + type Item = char; + + fn next(&mut self) -> Option { + match self.state { + EscapeState::Backslash(c) => { + self.state = EscapeState::Char(c); + Some('\\') + } + EscapeState::Char(c) | EscapeState::ForceQuote(c) => { + self.state = EscapeState::Done; + Some(c) + } + EscapeState::Done => None, + EscapeState::Octal(ref mut iter) => iter.next(), + } + } +} + +fn shell_without_escape(name: String, quotes: Quotes) -> (String, bool) { + let mut must_quote = false; + let mut escaped_str = String::with_capacity(name.len()); + + for c in name.chars() { + let escaped = EscapedChar::new_shell(c, false, quotes); + match escaped.state { + EscapeState::Backslash('\'') => escaped_str.push_str("'\\''"), + EscapeState::ForceQuote(x) => { + must_quote = true; + escaped_str.push(x); + } + _ => { + for char in escaped { + escaped_str.push(char); + } + } + } + } + (escaped_str, must_quote) +} + +fn shell_with_escape(name: String, quotes: Quotes) -> (String, bool) { + // We need to keep track of whether we are in a dollar expression + // because e.g. \b\n is escaped as $'\b\n' and not like $'b'$'n' + let mut in_dollar = false; + let mut must_quote = false; + let mut escaped_str = String::with_capacity(name.len()); + + for c in name.chars() { + let escaped = EscapedChar::new_shell(c, true, quotes); + match escaped.state { + EscapeState::Char(x) => { + if in_dollar { + escaped_str.push_str("''"); + in_dollar = false; + } + escaped_str.push(x); + } + EscapeState::ForceQuote(x) => { + if in_dollar { + escaped_str.push_str("''"); + in_dollar = false; + } + must_quote = true; + escaped_str.push(x); + } + // Single quotes are not put in dollar expressions, but are escaped + // if the string also contains double quotes. In that case, they must + // be handled separately. + EscapeState::Backslash('\'') => { + must_quote = true; + in_dollar = false; + escaped_str.push_str("'\\''"); + } + _ => { + if !in_dollar { + escaped_str.push_str("'$'"); + in_dollar = true; + } + must_quote = true; + for char in escaped { + escaped_str.push(char); + } + } + } + } + (escaped_str, must_quote) +} + +pub(super) fn escape_name(name: String, style: &QuotingStyle) -> String { + match style { + QuotingStyle::Literal => name, + QuotingStyle::C { quotes } => { + let escaped_str: String = name + .chars() + .flat_map(|c| EscapedChar::new_c(c, *quotes)) + .collect(); + + match quotes { + Quotes::Single => format!("'{}'", escaped_str), + Quotes::Double => format!("\"{}\"", escaped_str), + _ => escaped_str, + } + } + QuotingStyle::Shell { + escape, + always_quote, + } => { + let (quotes, must_quote) = if name.contains('"') { + (Quotes::Single, true) + } else if name.contains('\'') { + (Quotes::Double, true) + } else if *always_quote { + (Quotes::Single, true) + } else { + (Quotes::Single, false) + }; + + let (escaped_str, contains_quote_chars) = if *escape { + shell_with_escape(name, quotes) + } else { + shell_without_escape(name, quotes) + }; + + match (must_quote | contains_quote_chars, quotes) { + (true, Quotes::Single) => format!("'{}'", escaped_str), + (true, Quotes::Double) => format!("\"{}\"", escaped_str), + _ => escaped_str, + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::quoting_style::{escape_name, Quotes, QuotingStyle}; + fn get_style(s: &str) -> QuotingStyle { + match s { + "literal" => QuotingStyle::Literal, + "escape" => QuotingStyle::C { + quotes: Quotes::None, + }, + "c" => QuotingStyle::C { + quotes: Quotes::Double, + }, + "shell" => QuotingStyle::Shell { + escape: false, + always_quote: false, + }, + "shell-always" => QuotingStyle::Shell { + escape: false, + always_quote: true, + }, + "shell-escape" => QuotingStyle::Shell { + escape: true, + always_quote: false, + }, + "shell-escape-always" => QuotingStyle::Shell { + escape: true, + always_quote: true, + }, + _ => panic!("Invalid name!"), + } + } + + fn check_names(name: &str, map: Vec<(&str, &str)>) { + assert_eq!( + map.iter() + .map(|(_, style)| escape_name(name.to_string(), &get_style(style))) + .collect::>(), + map.iter() + .map(|(correct, _)| correct.to_string()) + .collect::>() + ); + } + + #[test] + fn test_simple_names() { + check_names( + "one_two", + vec![ + ("one_two", "literal"), + ("one_two", "escape"), + ("\"one_two\"", "c"), + ("one_two", "shell"), + ("\'one_two\'", "shell-always"), + ("one_two", "shell-escape"), + ("\'one_two\'", "shell-escape-always"), + ], + ); + } + + #[test] + fn test_spaces() { + check_names( + "one two", + vec![ + ("one two", "literal"), + ("one\\ two", "escape"), + ("\"one two\"", "c"), + ("\'one two\'", "shell"), + ("\'one two\'", "shell-always"), + ("\'one two\'", "shell-escape"), + ("\'one two\'", "shell-escape-always"), + ], + ); + + check_names( + " one", + vec![ + (" one", "literal"), + ("\\ one", "escape"), + ("\" one\"", "c"), + ("' one'", "shell"), + ("' one'", "shell-always"), + ("' one'", "shell-escape"), + ("' one'", "shell-escape-always"), + ], + ); + } + + #[test] + fn test_quotes() { + // One double quote + check_names( + "one\"two", + vec![ + ("one\"two", "literal"), + ("one\"two", "escape"), + ("\"one\\\"two\"", "c"), + ("'one\"two'", "shell"), + ("'one\"two'", "shell-always"), + ("'one\"two'", "shell-escape"), + ("'one\"two'", "shell-escape-always"), + ], + ); + + // One single quote + check_names( + "one\'two", + vec![ + ("one'two", "literal"), + ("one'two", "escape"), + ("\"one'two\"", "c"), + ("\"one'two\"", "shell"), + ("\"one'two\"", "shell-always"), + ("\"one'two\"", "shell-escape"), + ("\"one'two\"", "shell-escape-always"), + ], + ); + + // One single quote and one double quote + check_names( + "one'two\"three", + vec![ + ("one'two\"three", "literal"), + ("one'two\"three", "escape"), + ("\"one'two\\\"three\"", "c"), + ("'one'\\''two\"three'", "shell"), + ("'one'\\''two\"three'", "shell-always"), + ("'one'\\''two\"three'", "shell-escape"), + ("'one'\\''two\"three'", "shell-escape-always"), + ], + ); + + // Consecutive quotes + check_names( + "one''two\"\"three", + vec![ + ("one''two\"\"three", "literal"), + ("one''two\"\"three", "escape"), + ("\"one''two\\\"\\\"three\"", "c"), + ("'one'\\'''\\''two\"\"three'", "shell"), + ("'one'\\'''\\''two\"\"three'", "shell-always"), + ("'one'\\'''\\''two\"\"three'", "shell-escape"), + ("'one'\\'''\\''two\"\"three'", "shell-escape-always"), + ], + ); + } + + #[test] + fn test_control_chars() { + // A simple newline + check_names( + "one\ntwo", + vec![ + ("one\ntwo", "literal"), + ("one\\ntwo", "escape"), + ("\"one\\ntwo\"", "c"), + ("one?two", "shell"), + ("'one?two'", "shell-always"), + ("'one'$'\\n''two'", "shell-escape"), + ("'one'$'\\n''two'", "shell-escape-always"), + ], + ); + + // The first 16 control characters. NUL is also included, even though it is of + // no importance for file names. + check_names( + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + vec![ + ( + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + "literal", + ), + ( + "\\000\\001\\002\\003\\004\\005\\006\\a\\b\\t\\n\\v\\f\\r\\016\\017", + "escape", + ), + ( + "\"\\000\\001\\002\\003\\004\\005\\006\\a\\b\\t\\n\\v\\f\\r\\016\\017\"", + "c", + ), + ("????????????????", "shell"), + ("'????????????????'", "shell-always"), + ( + "''$'\\000\\001\\002\\003\\004\\005\\006\\a\\b\\t\\n\\v\\f\\r\\016\\017'", + "shell-escape", + ), + ( + "''$'\\000\\001\\002\\003\\004\\005\\006\\a\\b\\t\\n\\v\\f\\r\\016\\017'", + "shell-escape-always", + ), + ], + ); + + // The last 16 control characters. + check_names( + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", + vec![ + ( + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", + "literal", + ), + ( + "\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037", + "escape", + ), + ( + "\"\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\"", + "c", + ), + ("????????????????", "shell"), + ("'????????????????'", "shell-always"), + ( + "''$'\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037'", + "shell-escape", + ), + ( + "''$'\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037'", + "shell-escape-always", + ), + ], + ); + + // DEL + check_names( + "\x7F", + vec![ + ("\x7F", "literal"), + ("\\177", "escape"), + ("\"\\177\"", "c"), + ("?", "shell"), + ("'?'", "shell-always"), + ("''$'\\177'", "shell-escape"), + ("''$'\\177'", "shell-escape-always"), + ], + ); + } + + #[test] + fn test_question_mark() { + // A question mark must force quotes in shell and shell-always, unless + // it is in place of a control character (that case is already covered + // in other tests) + check_names( + "one?two", + vec![ + ("one?two", "literal"), + ("one?two", "escape"), + ("\"one?two\"", "c"), + ("'one?two'", "shell"), + ("'one?two'", "shell-always"), + ("'one?two'", "shell-escape"), + ("'one?two'", "shell-escape-always"), + ], + ); + } +} diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 638102cc7..d403e5577 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -765,6 +765,8 @@ fn test_ls_ls_color() { .arg("--color=always") .arg("a/nested_file") .succeeds(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); assert!(result.stdout.contains("a/nested_file\n")); // No output @@ -1122,3 +1124,88 @@ fn test_ls_version_sort() { expected.insert(0, "."); assert_eq!(result.stdout.split('\n').collect::>(), expected,) } + +#[test] +fn test_ls_quoting_style() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.touch("one two"); + at.touch("one"); + + // It seems that windows doesn't allow \n in filenames. + #[cfg(unix)] + { + at.touch("one\ntwo"); + // Default is shell-escape + let result = scene.ucmd().arg("one\ntwo").succeeds(); + assert_eq!(result.stdout, "'one'$'\\n''two'\n"); + + for (arg, correct) in &[ + ("--quoting-style=literal", "one\ntwo"), + ("-N", "one\ntwo"), + ("--literal", "one\ntwo"), + ("--quoting-style=c", "\"one\\ntwo\""), + ("-Q", "\"one\\ntwo\""), + ("--quote-name", "\"one\\ntwo\""), + ("--quoting-style=escape", "one\\ntwo"), + ("-b", "one\\ntwo"), + ("--escape", "one\\ntwo"), + ("--quoting-style=shell-escape", "'one'$'\\n''two'"), + ("--quoting-style=shell-escape-always", "'one'$'\\n''two'"), + ("--quoting-style=shell", "one?two"), + ("--quoting-style=shell-always", "'one?two'"), + ] { + let result = scene.ucmd().arg(arg).arg("one\ntwo").run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert_eq!(result.stdout, format!("{}\n", correct)); + } + } + + let result = scene.ucmd().arg("one two").succeeds(); + assert_eq!(result.stdout, "'one two'\n"); + + for (arg, correct) in &[ + ("--quoting-style=literal", "one two"), + ("-N", "one two"), + ("--literal", "one two"), + ("--quoting-style=c", "\"one two\""), + ("-Q", "\"one two\""), + ("--quote-name", "\"one two\""), + ("--quoting-style=escape", "one\\ two"), + ("-b", "one\\ two"), + ("--escape", "one\\ two"), + ("--quoting-style=shell-escape", "'one two'"), + ("--quoting-style=shell-escape-always", "'one two'"), + ("--quoting-style=shell", "'one two'"), + ("--quoting-style=shell-always", "'one two'"), + ] { + let result = scene.ucmd().arg(arg).arg("one two").run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert_eq!(result.stdout, format!("{}\n", correct)); + } + + let result = scene.ucmd().arg("one").succeeds(); + assert_eq!(result.stdout, "one\n"); + + for (arg, correct) in &[ + ("--quoting-style=literal", "one"), + ("-N", "one"), + ("--quoting-style=c", "\"one\""), + ("-Q", "\"one\""), + ("--quote-name", "\"one\""), + ("--quoting-style=escape", "one"), + ("-b", "one"), + ("--quoting-style=shell-escape", "one"), + ("--quoting-style=shell-escape-always", "'one'"), + ("--quoting-style=shell", "one"), + ("--quoting-style=shell-always", "'one'"), + ] { + let result = scene.ucmd().arg(arg).arg("one").run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert_eq!(result.stdout, format!("{}\n", correct)); + } +} From 7a947cfe46b694f61a5a7d840d622ce292da457c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81rni=20Dagur?= Date: Thu, 1 Apr 2021 21:08:48 +0000 Subject: [PATCH 059/132] cat: Improve performance on Linux (#1978) * cat: Improve performance, especially on Linux * cat: Don't use io::copy for splice fallback On my MacBook Pro 2020, it is around 25% faster to not use io::copy. * cat: Only fall back to generic copy if first splice fails * cat: Don't double buffer stdout * cat: Don't use experimental or-pattern syntax * cat: Remove nix symbol use from non-Linux --- Cargo.lock | 5 +- src/uu/cat/Cargo.toml | 5 +- src/uu/cat/src/cat.rs | 420 +++++++++++++++++++++++++----------------- 3 files changed, 255 insertions(+), 175 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e273f776c..f7e1187b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "advapi32-sys" version = "0.2.0" @@ -1581,7 +1583,8 @@ name = "uu_cat" version = "0.0.4" dependencies = [ "clap", - "quick-error", + "nix 0.20.0", + "thiserror", "unix_socket", "uucore", "uucore_procs", diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index b6254cf6b..3878aee96 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -16,13 +16,16 @@ path = "src/cat.rs" [dependencies] clap = "2.33" -quick-error = "1.2.3" +thiserror = "1.0" uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(unix)'.dependencies] unix_socket = "0.5.0" +[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] +nix = "0.20" + [[bin]] name = "cat" path = "src/main.rs" diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index cf5a384a4..f39708fd8 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -3,14 +3,13 @@ // (c) Jordi Boggiano // (c) Evgeniy Klyuchikov // (c) Joshua S. Miller +// (c) Árni Dagur // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // spell-checker:ignore (ToDO) nonprint nonblank nonprinting -#[macro_use] -extern crate quick_error; #[cfg(unix)] extern crate unix_socket; #[macro_use] @@ -18,9 +17,9 @@ extern crate uucore; // last synced with: cat (GNU coreutils) 8.13 use clap::{App, Arg}; -use quick_error::ResultExt; use std::fs::{metadata, File}; -use std::io::{self, stderr, stdin, stdout, BufWriter, Read, Write}; +use std::io::{self, Read, Write}; +use thiserror::Error; use uucore::fs::is_stdin_interactive; /// Unix domain socket support @@ -31,12 +30,44 @@ use std::os::unix::fs::FileTypeExt; #[cfg(unix)] use unix_socket::UnixStream; +#[cfg(any(target_os = "linux", target_os = "android"))] +use nix::errno::Errno; +/// Linux splice support +#[cfg(any(target_os = "linux", target_os = "android"))] +use nix::fcntl::{splice, SpliceFFlags}; +#[cfg(any(target_os = "linux", target_os = "android"))] +use nix::unistd::pipe; +#[cfg(any(target_os = "linux", target_os = "android"))] +use std::os::unix::io::{AsRawFd, RawFd}; + static NAME: &str = "cat"; static VERSION: &str = env!("CARGO_PKG_VERSION"); static SYNTAX: &str = "[OPTION]... [FILE]..."; static SUMMARY: &str = "Concatenate FILE(s), or standard input, to standard output With no FILE, or when FILE is -, read standard input."; +#[derive(Error, Debug)] +enum CatError { + /// Wrapper around `io::Error` + #[error("{0}")] + Io(#[from] io::Error), + /// Wrapper around `nix::Error` + #[cfg(any(target_os = "linux", target_os = "android"))] + #[error("{0}")] + Nix(#[from] nix::Error), + /// Unknown file type; it's not a regular file, socket, etc. + #[error("{}: unknown filetype: {}", path, ft_debug)] + UnknownFiletype { + path: String, + /// A debug print of the file type + ft_debug: String, + }, + #[error("{0}: Expected a file, found directory")] + IsDirectory(String), +} + +type CatResult = Result; + #[derive(PartialEq)] enum NumberingMode { None, @@ -44,39 +75,6 @@ enum NumberingMode { All, } -quick_error! { - #[derive(Debug)] - enum CatError { - /// Wrapper for io::Error with path context - Input(err: io::Error, path: String) { - display("cat: {0}: {1}", path, err) - context(path: &'a str, err: io::Error) -> (err, path.to_owned()) - cause(err) - } - - /// Wrapper for io::Error with no context - Output(err: io::Error) { - display("cat: {0}", err) from() - cause(err) - } - - /// Unknown Filetype classification - UnknownFiletype(path: String) { - display("cat: {0}: unknown filetype", path) - } - - /// At least one error was encountered in reading or writing - EncounteredErrors(count: usize) { - display("cat: encountered {0} errors", count) - } - - /// Denotes an error caused by trying to `cat` a directory - IsDirectory(path: String) { - display("cat: {0}: Is a directory", path) - } - } -} - struct OutputOptions { /// Line numbering mode number: NumberingMode, @@ -87,21 +85,56 @@ struct OutputOptions { /// display TAB characters as `tab` show_tabs: bool, - /// If `show_tabs == true`, this string will be printed in the - /// place of tabs - tab: String, - - /// Can be set to show characters other than '\n' a the end of - /// each line, e.g. $ - end_of_line: String, + /// Show end of lines + show_ends: bool, /// use ^ and M- notation, except for LF (\\n) and TAB (\\t) show_nonprint: bool, } +impl OutputOptions { + fn tab(&self) -> &'static str { + if self.show_tabs { + "^I" + } else { + "\t" + } + } + + fn end_of_line(&self) -> &'static str { + if self.show_ends { + "$\n" + } else { + "\n" + } + } + + /// We can write fast if we can simply copy the contents of the file to + /// stdout, without augmenting the output with e.g. line numbers. + fn can_write_fast(&self) -> bool { + !(self.show_tabs + || self.show_nonprint + || self.show_ends + || self.squeeze_blank + || self.number != NumberingMode::None) + } +} + +/// State that persists between output of each file. This struct is only used +/// when we can't write fast. +struct OutputState { + /// The current line number + line_number: usize, + + /// Whether the output cursor is at the beginning of a new line + at_line_start: bool, +} + /// Represents an open file handle, stream, or other device -struct InputHandle { - reader: Box, +struct InputHandle { + #[cfg(any(target_os = "linux", target_os = "android"))] + file_descriptor: RawFd, + reader: R, is_interactive: bool, } @@ -124,8 +157,6 @@ enum InputType { Socket, } -type CatResult = Result; - mod options { pub static FILE: &str = "file"; pub static SHOW_ALL: &str = "show-all"; @@ -243,30 +274,14 @@ pub fn uumain(args: impl uucore::Args) -> i32 { None => vec!["-".to_owned()], }; - let can_write_fast = !(show_tabs - || show_nonprint - || show_ends - || squeeze_blank - || number_mode != NumberingMode::None); - - let success = if can_write_fast { - write_fast(files).is_ok() - } else { - let tab = if show_tabs { "^I" } else { "\t" }.to_owned(); - - let end_of_line = if show_ends { "$\n" } else { "\n" }.to_owned(); - - let options = OutputOptions { - end_of_line, - number: number_mode, - show_nonprint, - show_tabs, - squeeze_blank, - tab, - }; - - write_lines(files, &options).is_ok() + let options = OutputOptions { + show_ends, + number: number_mode, + show_nonprint, + show_tabs, + squeeze_blank, }; + let success = cat_files(files, &options).is_ok(); if success { 0 @@ -275,6 +290,76 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } } +fn cat_handle( + handle: &mut InputHandle, + options: &OutputOptions, + state: &mut OutputState, +) -> CatResult<()> { + if options.can_write_fast() { + write_fast(handle) + } else { + write_lines(handle, &options, state) + } +} + +fn cat_path(path: &str, options: &OutputOptions, state: &mut OutputState) -> CatResult<()> { + if path == "-" { + let stdin = io::stdin(); + let mut handle = InputHandle { + #[cfg(any(target_os = "linux", target_os = "android"))] + file_descriptor: stdin.as_raw_fd(), + reader: stdin, + is_interactive: is_stdin_interactive(), + }; + return cat_handle(&mut handle, &options, state); + } + match get_input_type(path)? { + InputType::Directory => Err(CatError::IsDirectory(path.to_owned())), + #[cfg(unix)] + InputType::Socket => { + let socket = UnixStream::connect(path)?; + socket.shutdown(Shutdown::Write)?; + let mut handle = InputHandle { + #[cfg(any(target_os = "linux", target_os = "android"))] + file_descriptor: socket.as_raw_fd(), + reader: socket, + is_interactive: false, + }; + cat_handle(&mut handle, &options, state) + } + _ => { + let file = File::open(path)?; + let mut handle = InputHandle { + #[cfg(any(target_os = "linux", target_os = "android"))] + file_descriptor: file.as_raw_fd(), + reader: file, + is_interactive: false, + }; + cat_handle(&mut handle, &options, state) + } + } +} + +fn cat_files(files: Vec, options: &OutputOptions) -> Result<(), u32> { + let mut error_count = 0; + let mut state = OutputState { + line_number: 1, + at_line_start: true, + }; + + for path in &files { + if let Err(err) = cat_path(path, &options, &mut state) { + show_error!("{}", err); + error_count += 1; + } + } + if error_count == 0 { + Ok(()) + } else { + Err(error_count) + } +} + /// Classifies the `InputType` of file at `path` if possible /// /// # Arguments @@ -285,7 +370,8 @@ fn get_input_type(path: &str) -> CatResult { return Ok(InputType::StdIn); } - match metadata(path).context(path)?.file_type() { + let ft = metadata(path)?.file_type(); + match ft { #[cfg(unix)] ft if ft.is_block_device() => Ok(InputType::BlockDevice), #[cfg(unix)] @@ -297,125 +383,113 @@ fn get_input_type(path: &str) -> CatResult { ft if ft.is_dir() => Ok(InputType::Directory), ft if ft.is_file() => Ok(InputType::File), ft if ft.is_symlink() => Ok(InputType::SymLink), - _ => Err(CatError::UnknownFiletype(path.to_owned())), + _ => Err(CatError::UnknownFiletype { + path: path.to_owned(), + ft_debug: format!("{:?}", ft), + }), } } -/// Returns an InputHandle from which a Reader can be accessed or an -/// error -/// -/// # Arguments -/// -/// * `path` - `InputHandler` will wrap a reader from this file path -fn open(path: &str) -> CatResult { - if path == "-" { - let stdin = stdin(); - return Ok(InputHandle { - reader: Box::new(stdin) as Box, - is_interactive: is_stdin_interactive(), - }); - } - - match get_input_type(path)? { - InputType::Directory => Err(CatError::IsDirectory(path.to_owned())), - #[cfg(unix)] - InputType::Socket => { - let socket = UnixStream::connect(path).context(path)?; - socket.shutdown(Shutdown::Write).context(path)?; - Ok(InputHandle { - reader: Box::new(socket) as Box, - is_interactive: false, - }) - } - _ => { - let file = File::open(path).context(path)?; - Ok(InputHandle { - reader: Box::new(file) as Box, - is_interactive: false, - }) +/// Writes handle to stdout with no configuration. This allows a +/// simple memory copy. +fn write_fast(handle: &mut InputHandle) -> CatResult<()> { + let stdout = io::stdout(); + let mut stdout_lock = stdout.lock(); + #[cfg(any(target_os = "linux", target_os = "android"))] + { + // If we're on Linux or Android, try to use the splice() system call + // for faster writing. If it works, we're done. + if !write_fast_using_splice(handle, stdout.as_raw_fd())? { + return Ok(()); } } + // If we're not on Linux or Android, or the splice() call failed, + // fall back on slower writing. + let mut buf = [0; 1024 * 64]; + while let Ok(n) = handle.reader.read(&mut buf) { + if n == 0 { + break; + } + stdout_lock.write_all(&buf[..n])?; + } + Ok(()) } -/// Writes files to stdout with no configuration. This allows a -/// simple memory copy. Returns `Ok(())` if no errors were -/// encountered, or an error with the number of errors encountered. +/// This function is called from `write_fast()` on Linux and Android. The +/// function `splice()` is used to move data between two file descriptors +/// without copying between kernel- and userspace. This results in a large +/// speedup. /// -/// # Arguments -/// -/// * `files` - There is no short circuit when encountering an error -/// reading a file in this vector -fn write_fast(files: Vec) -> CatResult<()> { - let mut writer = stdout(); - let mut in_buf = [0; 1024 * 64]; - let mut error_count = 0; +/// The `bool` in the result value indicates if we need to fall back to normal +/// copying or not. False means we don't have to. +#[cfg(any(target_os = "linux", target_os = "android"))] +#[inline] +fn write_fast_using_splice(handle: &mut InputHandle, writer: RawFd) -> CatResult { + const BUF_SIZE: usize = 1024 * 16; - for file in files { - match open(&file[..]) { - Ok(mut handle) => { - while let Ok(n) = handle.reader.read(&mut in_buf) { - if n == 0 { - break; - } - writer.write_all(&in_buf[..n]).context(&file[..])?; + let (pipe_rd, pipe_wr) = pipe()?; + + // We only fall back if splice fails on the first call. + match splice( + handle.file_descriptor, + None, + pipe_wr, + None, + BUF_SIZE, + SpliceFFlags::empty(), + ) { + Ok(n) => { + if n == 0 { + return Ok(false); + } + } + Err(err) => { + match err.as_errno() { + Some(Errno::EPERM) | Some(Errno::ENOSYS) | Some(Errno::EINVAL) => { + // EPERM indicates the call was blocked by seccomp. + // ENOSYS indicates we're running on an ancient Kernel. + // EINVAL indicates some other failure. + return Ok(true); + } + _ => { + // Other errors include running out of memory, etc. We + // don't attempt to fall back from these. + return Err(err)?; } } - Err(error) => { - writeln!(&mut stderr(), "{}", error)?; - error_count += 1; - } } } - match error_count { - 0 => Ok(()), - _ => Err(CatError::EncounteredErrors(error_count)), - } -} - -/// State that persists between output of each file -struct OutputState { - /// The current line number - line_number: usize, - - /// Whether the output cursor is at the beginning of a new line - at_line_start: bool, -} - -/// Writes files to stdout with `options` as configuration. Returns -/// `Ok(())` if no errors were encountered, or an error with the -/// number of errors encountered. -/// -/// # Arguments -/// -/// * `files` - There is no short circuit when encountering an error -/// reading a file in this vector -fn write_lines(files: Vec, options: &OutputOptions) -> CatResult<()> { - let mut error_count = 0; - let mut state = OutputState { - line_number: 1, - at_line_start: true, - }; - - for file in files { - if let Err(error) = write_file_lines(&file, options, &mut state) { - writeln!(&mut stderr(), "{}", error).context(&file[..])?; - error_count += 1; + loop { + let n = splice( + handle.file_descriptor, + None, + pipe_wr, + None, + BUF_SIZE, + SpliceFFlags::empty(), + )?; + if n == 0 { + // We read 0 bytes from the input, + // which means we're done copying. + break; } + splice(pipe_rd, None, writer, None, BUF_SIZE, SpliceFFlags::empty())?; } - match error_count { - 0 => Ok(()), - _ => Err(CatError::EncounteredErrors(error_count)), - } + Ok(false) } /// Outputs file contents to stdout in a line-by-line fashion, /// propagating any errors that might occur. -fn write_file_lines(file: &str, options: &OutputOptions, state: &mut OutputState) -> CatResult<()> { - let mut handle = open(file)?; +fn write_lines( + handle: &mut InputHandle, + options: &OutputOptions, + state: &mut OutputState, +) -> CatResult<()> { let mut in_buf = [0; 1024 * 31]; - let mut writer = BufWriter::with_capacity(1024 * 64, stdout()); + let stdout = io::stdout(); + let mut writer = stdout.lock(); let mut one_blank_kept = false; while let Ok(n) = handle.reader.read(&mut in_buf) { @@ -433,9 +507,9 @@ fn write_file_lines(file: &str, options: &OutputOptions, state: &mut OutputState write!(&mut writer, "{0:6}\t", state.line_number)?; state.line_number += 1; } - writer.write_all(options.end_of_line.as_bytes())?; + writer.write_all(options.end_of_line().as_bytes())?; if handle.is_interactive { - writer.flush().context(file)?; + writer.flush()?; } } state.at_line_start = true; @@ -450,7 +524,7 @@ fn write_file_lines(file: &str, options: &OutputOptions, state: &mut OutputState // print to end of line or end of buffer let offset = if options.show_nonprint { - write_nonprint_to_end(&in_buf[pos..], &mut writer, options.tab.as_bytes()) + write_nonprint_to_end(&in_buf[pos..], &mut writer, options.tab().as_bytes()) } else if options.show_tabs { write_tab_to_end(&in_buf[pos..], &mut writer) } else { @@ -462,7 +536,7 @@ fn write_file_lines(file: &str, options: &OutputOptions, state: &mut OutputState break; } // print suitable end of line - writer.write_all(options.end_of_line.as_bytes())?; + writer.write_all(options.end_of_line().as_bytes())?; if handle.is_interactive { writer.flush()?; } From 090d29496a016c81d437ecb61fa8e401c51d7856 Mon Sep 17 00:00:00 2001 From: paulotten Date: Thu, 1 Apr 2021 17:16:47 -0400 Subject: [PATCH 060/132] Issue #1622 port `du` to windows (#1788) * Issue #1622 port `du` to windows * Attempt to support Rust 1.32 Old version was getting "attributes are not yet allowed on `if` expressions" on Rust 1.32 * Less #[cfg] * Less duplicate code. I need the return and the semicolon after if otherwise the second #[cfg] leads to unexpected token complilation error * More accurate size on disk calculations for windows * Expect the same output on windows as with WSL * Better matches output from du on WSL * In the absence of feedback I'm disabling these tests on Windows. They require `ln`. Windows does not ship with this utility. * Use the coreutils version of `ln` to test `du` `fn ccmd` is courtesy of @Artoria2e5 * Look up inodes (file ids) on Windows * One more #[cfg(windows)] to prevent unreachable statement warning on linux --- Cargo.lock | 1 + Cargo.toml | 2 +- src/uu/du/Cargo.toml | 1 + src/uu/du/src/du.rs | 121 ++++++++++++++++++++++++++++++++++++--- tests/by-util/test_du.rs | 28 +++++++-- tests/common/util.rs | 8 +++ 6 files changed, 146 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7e1187b4..95635159c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1735,6 +1735,7 @@ dependencies = [ "time", "uucore", "uucore_procs", + "winapi 0.3.9", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 9136b5d64..1562fcfb0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ feat_common_core = [ "df", "dircolors", "dirname", + "du", "echo", "env", "expand", @@ -149,7 +150,6 @@ feat_require_unix = [ "chmod", "chown", "chroot", - "du", "groups", "hostid", "id", diff --git a/src/uu/du/Cargo.toml b/src/uu/du/Cargo.toml index 912eef17e..bb46c299c 100644 --- a/src/uu/du/Cargo.toml +++ b/src/uu/du/Cargo.toml @@ -18,6 +18,7 @@ path = "src/du.rs" time = "0.1.40" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } +winapi = { version="0.3", features=[] } [[bin]] name = "du" diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 4ed80f18b..2eb7bd658 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -15,9 +15,24 @@ use std::env; use std::fs; use std::io::{stderr, Result, Write}; use std::iter; +#[cfg(not(windows))] use std::os::unix::fs::MetadataExt; +#[cfg(windows)] +use std::os::windows::fs::MetadataExt; +#[cfg(windows)] +use std::os::windows::io::AsRawHandle; use std::path::PathBuf; use time::Timespec; +#[cfg(windows)] +use winapi::shared::minwindef::{DWORD, LPVOID}; +#[cfg(windows)] +use winapi::um::fileapi::{FILE_STANDARD_INFO, FILE_ID_INFO}; +#[cfg(windows)] +use winapi::um::minwinbase::{FileStandardInfo, FileIdInfo}; +#[cfg(windows)] +use winapi::um::winbase::GetFileInformationByHandleEx; +#[cfg(windows)] +use winapi::um::winnt::FILE_ID_128; const NAME: &str = "du"; const SUMMARY: &str = "estimate file space usage"; @@ -48,7 +63,7 @@ struct Stat { is_dir: bool, size: u64, blocks: u64, - inode: u64, + inode: Option, created: u64, accessed: u64, modified: u64, @@ -57,19 +72,106 @@ struct Stat { impl Stat { fn new(path: PathBuf) -> Result { let metadata = fs::symlink_metadata(&path)?; - Ok(Stat { + + #[cfg(not(windows))] + return Ok(Stat { path, is_dir: metadata.is_dir(), size: metadata.len(), blocks: metadata.blocks() as u64, - inode: metadata.ino() as u64, + inode: Some(metadata.ino() as u128), created: metadata.mtime() as u64, accessed: metadata.atime() as u64, modified: metadata.mtime() as u64, + }); + + #[cfg(windows)] + let size_on_disk = get_size_on_disk(&path); + #[cfg(windows)] + let inode = get_inode(&path); + #[cfg(windows)] + Ok(Stat { + path, + is_dir: metadata.is_dir(), + size: metadata.len(), + blocks: size_on_disk / 1024 * 2, + inode: inode, + created: windows_time_to_unix_time(metadata.creation_time()), + accessed: windows_time_to_unix_time(metadata.last_access_time()), + modified: windows_time_to_unix_time(metadata.last_write_time()), }) } } +#[cfg(windows)] +// https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html#tymethod.creation_time +// "The returned 64-bit value [...] which represents the number of 100-nanosecond intervals since January 1, 1601 (UTC)." +fn windows_time_to_unix_time(win_time: u64) -> u64 { + win_time / 10_000 - 11_644_473_600_000 +} + +#[cfg(windows)] +fn get_size_on_disk(path: &PathBuf) -> u64 { + let mut size_on_disk = 0; + + // bind file so it stays in scope until end of function + // if it goes out of scope the handle below becomes invalid + let file = match fs::File::open(path) { + Ok(file) => file, + Err(_) => return size_on_disk, // opening directories will fail + }; + + let handle = file.as_raw_handle(); + + unsafe { + let mut file_info: FILE_STANDARD_INFO = core::mem::zeroed(); + let file_info_ptr: *mut FILE_STANDARD_INFO = &mut file_info; + + let success = GetFileInformationByHandleEx( + handle, + FileStandardInfo, + file_info_ptr as LPVOID, + std::mem::size_of::() as DWORD, + ); + + if success != 0 { + size_on_disk = *file_info.AllocationSize.QuadPart() as u64; + } + } + + size_on_disk +} + +#[cfg(windows)] +fn get_inode(path: &PathBuf) -> Option { + let mut inode = None; + + let file = match fs::File::open(path) { + Ok(file) => file, + Err(_) => return inode, + }; + + let handle = file.as_raw_handle(); + + unsafe { + let mut file_info: FILE_ID_INFO = core::mem::zeroed(); + let file_info_ptr: *mut FILE_ID_INFO = &mut file_info; + + let success = GetFileInformationByHandleEx( + handle, + FileIdInfo, + file_info_ptr as LPVOID, + std::mem::size_of::() as DWORD, + ); + + if success != 0 { + inode = Some(std::mem::transmute::(file_info.FileId)); + } + } + + inode +} + fn unit_string_to_number(s: &str) -> Option { let mut offset = 0; let mut s_chars = s.chars().rev(); @@ -137,7 +239,7 @@ fn du( mut my_stat: Stat, options: &Options, depth: usize, - inodes: &mut HashSet, + inodes: &mut HashSet, ) -> Box> { let mut stats = vec![]; let mut futures = vec![]; @@ -164,10 +266,13 @@ fn du( if this_stat.is_dir { futures.push(du(this_stat, options, depth + 1, inodes)); } else { - if inodes.contains(&this_stat.inode) { - continue; + if this_stat.inode.is_some() { + let inode = this_stat.inode.unwrap(); + if inodes.contains(&inode) { + continue; + } + inodes.insert(inode); } - inodes.insert(this_stat.inode); my_stat.size += this_stat.size; my_stat.blocks += this_stat.blocks; if options.all { @@ -418,7 +523,7 @@ Try '{} --help' for more information.", let path = PathBuf::from(&path_str); match Stat::new(path) { Ok(stat) => { - let mut inodes: HashSet = HashSet::new(); + let mut inodes: HashSet = HashSet::new(); let iter = du(stat, &options, 0, &mut inodes); let (_, len) = iter.size_hint(); diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index a79f820fb..c810bd395 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -45,7 +45,11 @@ fn test_du_basics_subdir() { fn _du_basics_subdir(s: String) { assert_eq!(s, "4\tsubdir/deeper\n"); } -#[cfg(not(target_vendor = "apple"))] +#[cfg(target_os = "windows")] +fn _du_basics_subdir(s: String) { + assert_eq!(s, "0\tsubdir/deeper\n"); +} +#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))] fn _du_basics_subdir(s: String) { // MS-WSL linux has altered expected output if !is_wsl() { @@ -71,7 +75,7 @@ fn test_du_basics_bad_name() { fn test_du_soft_link() { let ts = TestScenario::new("du"); - let link = ts.cmd("ln").arg("-s").arg(SUB_FILE).arg(SUB_LINK).run(); + let link = ts.ccmd("ln").arg("-s").arg(SUB_FILE).arg(SUB_LINK).run(); assert!(link.success); let result = ts.ucmd().arg(SUB_DIR_LINKS).run(); @@ -85,7 +89,11 @@ fn _du_soft_link(s: String) { // 'macos' host variants may have `du` output variation for soft links assert!((s == "12\tsubdir/links\n") || (s == "16\tsubdir/links\n")); } -#[cfg(not(target_vendor = "apple"))] +#[cfg(target_os = "windows")] +fn _du_soft_link(s: String) { + assert_eq!(s, "8\tsubdir/links\n"); +} +#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))] fn _du_soft_link(s: String) { // MS-WSL linux has altered expected output if !is_wsl() { @@ -99,7 +107,7 @@ fn _du_soft_link(s: String) { fn test_du_hard_link() { let ts = TestScenario::new("du"); - let link = ts.cmd("ln").arg(SUB_FILE).arg(SUB_LINK).run(); + let link = ts.ccmd("ln").arg(SUB_FILE).arg(SUB_LINK).run(); assert!(link.success); let result = ts.ucmd().arg(SUB_DIR_LINKS).run(); @@ -113,7 +121,11 @@ fn test_du_hard_link() { fn _du_hard_link(s: String) { assert_eq!(s, "12\tsubdir/links\n") } -#[cfg(not(target_vendor = "apple"))] +#[cfg(target_os = "windows")] +fn _du_hard_link(s: String) { + assert_eq!(s, "8\tsubdir/links\n") +} +#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))] fn _du_hard_link(s: String) { // MS-WSL linux has altered expected output if !is_wsl() { @@ -137,7 +149,11 @@ fn test_du_d_flag() { fn _du_d_flag(s: String) { assert_eq!(s, "16\t./subdir\n20\t./\n"); } -#[cfg(not(target_vendor = "apple"))] +#[cfg(target_os = "windows")] +fn _du_d_flag(s: String) { + assert_eq!(s, "8\t./subdir\n8\t./\n"); +} +#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))] fn _du_d_flag(s: String) { // MS-WSL linux has altered expected output if !is_wsl() { diff --git a/tests/common/util.rs b/tests/common/util.rs index e4b452289..7aea8dc26 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -589,6 +589,14 @@ impl TestScenario { UCommand::new_from_tmp(bin, self.tmpd.clone(), true) } + /// Returns builder for invoking any uutils command. Paths given are treated + /// relative to the environment's unique temporary test directory. + pub fn ccmd>(&self, bin: S) -> UCommand { + let mut cmd = self.cmd(&self.bin_path); + cmd.arg(bin); + cmd + } + // different names are used rather than an argument // because the need to keep the environment is exceedingly rare. pub fn ucmd_keepenv(&self) -> UCommand { From 9c2cd81b111b028c07b6791568445acb18f30db0 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Apr 2021 23:18:57 +0200 Subject: [PATCH 061/132] refresh cargo.lock with recent updates --- Cargo.lock | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95635159c..f40d512ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,7 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - [[package]] name = "advapi32-sys" version = "0.2.0" @@ -982,9 +980,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ "unicode-xid 0.2.1", ] @@ -1356,9 +1354,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" +checksum = "3ce15dd3ed8aa2f8eeac4716d6ef5ab58b6b9256db41d7e1a0224c2788e8fd87" dependencies = [ "proc-macro2", "quote 1.0.9", From 6734ce785d5e17d8fb58dba29a94e3dfd06fb015 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Apr 2021 23:25:37 +0200 Subject: [PATCH 062/132] rustfmt the recent changes --- src/uu/du/src/du.rs | 4 ++-- src/uu/echo/src/echo.rs | 1 - src/uu/sort/src/sort.rs | 8 ++++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 2eb7bd658..a4852b21c 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -26,9 +26,9 @@ use time::Timespec; #[cfg(windows)] use winapi::shared::minwindef::{DWORD, LPVOID}; #[cfg(windows)] -use winapi::um::fileapi::{FILE_STANDARD_INFO, FILE_ID_INFO}; +use winapi::um::fileapi::{FILE_ID_INFO, FILE_STANDARD_INFO}; #[cfg(windows)] -use winapi::um::minwinbase::{FileStandardInfo, FileIdInfo}; +use winapi::um::minwinbase::{FileIdInfo, FileStandardInfo}; #[cfg(windows)] use winapi::um::winbase::GetFileInformationByHandleEx; #[cfg(windows)] diff --git a/src/uu/echo/src/echo.rs b/src/uu/echo/src/echo.rs index 1e0c04d1d..4d38d7748 100644 --- a/src/uu/echo/src/echo.rs +++ b/src/uu/echo/src/echo.rs @@ -36,7 +36,6 @@ const AFTER_HELP: &str = r#" \\xHH byte with hexadecimal value HH (1 to 2 digits) "#; - mod options { pub const STRING: &str = "STRING"; pub const NO_NEWLINE: &str = "no_newline"; diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index f8789835a..6c29ad98d 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -493,13 +493,13 @@ fn get_leading_number(a: &str) -> &str { fn num_sort_dedup(a: &str) -> &str { // Empty lines are dumped if a.is_empty() { - return "0" + return "0"; // And lines that don't begin numerically are dumped } else if !a.trim().chars().nth(0).unwrap_or('\0').is_numeric() { - return "0" + return "0"; } else { - // Prepare lines for comparison of only the numerical leading numbers - return get_leading_number(a) + // Prepare lines for comparison of only the numerical leading numbers + return get_leading_number(a); }; } From dcbcf016658cebb24325197ba484c66d88e7a213 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Apr 2021 23:37:22 +0200 Subject: [PATCH 063/132] Fix some clippy warnings --- src/uu/cksum/src/cksum.rs | 2 +- src/uu/fmt/src/linebreak.rs | 2 +- src/uu/ln/src/ln.rs | 2 +- src/uu/ls/src/ls.rs | 8 +++----- src/uu/nl/src/helper.rs | 2 +- .../num_format/formatters/cninetyninehexfloatf.rs | 2 +- .../src/tokenize/num_format/formatters/float_common.rs | 2 +- src/uu/shred/src/shred.rs | 2 +- tests/common/util.rs | 5 ++++- 9 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index b7659ea62..b6436de87 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -147,7 +147,7 @@ fn cksum(fname: &str) -> io::Result<(u32, usize)> { "Is a directory", )); }; - if !path.metadata().is_ok() { + if path.metadata().is_err() { return Err(std::io::Error::new( io::ErrorKind::NotFound, "No such file or directory", diff --git a/src/uu/fmt/src/linebreak.rs b/src/uu/fmt/src/linebreak.rs index c41fd41bd..50cb6f77f 100644 --- a/src/uu/fmt/src/linebreak.rs +++ b/src/uu/fmt/src/linebreak.rs @@ -81,7 +81,7 @@ pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut BufWriter< let mut break_args = BreakArgs { opts, init_len: p_init_len, - indent_str: &p_indent[..], + indent_str: p_indent, indent_len: p_indent_len, uniform, ostream, diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index ab07a2b08..394cf13af 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -223,7 +223,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } else if matches.is_present(OPT_BACKUP) { match matches.value_of(OPT_BACKUP) { None => BackupMode::ExistingBackup, - Some(mode) => match &mode[..] { + Some(mode) => match mode { "simple" | "never" => BackupMode::SimpleBackup, "numbered" | "t" => BackupMode::NumberedBackup, "existing" | "nil" => BackupMode::ExistingBackup, diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 9633acf43..ece497bdb 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -270,11 +270,9 @@ impl Config { .any(|i| i >= idx) { format = Format::Long; - } else { - if let Some(mut indices) = options.indices_of(options::format::ONELINE) { - if indices.any(|i| i > idx) { - format = Format::OneLine; - } + } else if let Some(mut indices) = options.indices_of(options::format::ONELINE) { + if indices.any(|i| i > idx) { + format = Format::OneLine; } } } diff --git a/src/uu/nl/src/helper.rs b/src/uu/nl/src/helper.rs index 94ff835d7..e31477c62 100644 --- a/src/uu/nl/src/helper.rs +++ b/src/uu/nl/src/helper.rs @@ -37,7 +37,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &clap::ArgMatches) -> } match opts.value_of(options::NUMBER_FORMAT) { None => {} - Some(val) => match val.as_ref() { + Some(val) => match val { "ln" => { settings.number_format = crate::NumberFormat::Left; } diff --git a/src/uu/printf/src/tokenize/num_format/formatters/cninetyninehexfloatf.rs b/src/uu/printf/src/tokenize/num_format/formatters/cninetyninehexfloatf.rs index bf21bf8f9..10e58cc32 100644 --- a/src/uu/printf/src/tokenize/num_format/formatters/cninetyninehexfloatf.rs +++ b/src/uu/printf/src/tokenize/num_format/formatters/cninetyninehexfloatf.rs @@ -59,7 +59,7 @@ fn get_primitive_hex( // assign 0 let (mut first_segment_raw, second_segment_raw) = match analysis.decimal_pos { Some(pos) => (&str_in[..pos], &str_in[pos + 1..]), - None => (&str_in[..], "0"), + None => (str_in, "0"), }; if first_segment_raw.is_empty() { first_segment_raw = "0"; diff --git a/src/uu/printf/src/tokenize/num_format/formatters/float_common.rs b/src/uu/printf/src/tokenize/num_format/formatters/float_common.rs index 65fe5b6ea..a107078ae 100644 --- a/src/uu/printf/src/tokenize/num_format/formatters/float_common.rs +++ b/src/uu/printf/src/tokenize/num_format/formatters/float_common.rs @@ -218,7 +218,7 @@ pub fn get_primitive_dec( // assign 0 let (mut first_segment_raw, second_segment_raw) = match analysis.decimal_pos { Some(pos) => (&str_in[..pos], &str_in[pos + 1..]), - None => (&str_in[..], "0"), + None => (str_in, "0"), }; if first_segment_raw.is_empty() { first_segment_raw = "0"; diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index f9d8b9c73..c5f4d6e57 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -338,7 +338,7 @@ this is the default for non-regular files", Some(s) => match s.parse::() { Ok(u) => u, Err(_) => { - errs.push(String::from(format!("invalid number of passes: '{}'", s))); + errs.push(format!("invalid number of passes: '{}'", s)); 0 } }, diff --git a/tests/common/util.rs b/tests/common/util.rs index 7aea8dc26..922525ed2 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -1,8 +1,11 @@ #![allow(dead_code)] +#[cfg(not(windows))] use libc; use std::env; -use std::ffi::{CString, OsStr}; +#[cfg(not(windows))] +use std::ffi::CString; +use std::ffi::OsStr; use std::fs::{self, File, OpenOptions}; use std::io::{Read, Result, Write}; #[cfg(unix)] From 7112182dbcbd55925df7d33d11d8090cd043d16f Mon Sep 17 00:00:00 2001 From: Paul Otten Date: Thu, 1 Apr 2021 18:37:20 -0400 Subject: [PATCH 064/132] Consider device id when comparing files --- src/uu/du/src/du.rs | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 2eb7bd658..c311f982e 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -32,7 +32,7 @@ use winapi::um::minwinbase::{FileStandardInfo, FileIdInfo}; #[cfg(windows)] use winapi::um::winbase::GetFileInformationByHandleEx; #[cfg(windows)] -use winapi::um::winnt::FILE_ID_128; +use winapi::um::winnt::{FILE_ID_128, ULONGLONG}; const NAME: &str = "du"; const SUMMARY: &str = "estimate file space usage"; @@ -58,12 +58,18 @@ struct Options { separate_dirs: bool, } +#[derive(PartialEq, Eq, Hash, Clone, Copy)] +struct FileInfo { + file_id: u128, + dev_id: u64, +} + struct Stat { path: PathBuf, is_dir: bool, size: u64, blocks: u64, - inode: Option, + inode: Option, created: u64, accessed: u64, modified: u64, @@ -73,13 +79,18 @@ impl Stat { fn new(path: PathBuf) -> Result { let metadata = fs::symlink_metadata(&path)?; + #[cfg(not(windows))] + let file_info = FileInfo { + file_id: metadata.ino() as u128, + dev_id: metadata.dev(), + }; #[cfg(not(windows))] return Ok(Stat { path, is_dir: metadata.is_dir(), size: metadata.len(), blocks: metadata.blocks() as u64, - inode: Some(metadata.ino() as u128), + inode: Some(file_info), created: metadata.mtime() as u64, accessed: metadata.atime() as u64, modified: metadata.mtime() as u64, @@ -88,14 +99,14 @@ impl Stat { #[cfg(windows)] let size_on_disk = get_size_on_disk(&path); #[cfg(windows)] - let inode = get_inode(&path); + let file_info = get_file_info(&path); #[cfg(windows)] Ok(Stat { path, is_dir: metadata.is_dir(), size: metadata.len(), blocks: size_on_disk / 1024 * 2, - inode: inode, + inode: file_info, created: windows_time_to_unix_time(metadata.creation_time()), accessed: windows_time_to_unix_time(metadata.last_access_time()), modified: windows_time_to_unix_time(metadata.last_write_time()), @@ -143,12 +154,12 @@ fn get_size_on_disk(path: &PathBuf) -> u64 { } #[cfg(windows)] -fn get_inode(path: &PathBuf) -> Option { - let mut inode = None; +fn get_file_info(path: &PathBuf) -> Option { + let mut result = None; let file = match fs::File::open(path) { Ok(file) => file, - Err(_) => return inode, + Err(_) => return result, }; let handle = file.as_raw_handle(); @@ -165,11 +176,14 @@ fn get_inode(path: &PathBuf) -> Option { ); if success != 0 { - inode = Some(std::mem::transmute::(file_info.FileId)); + result = Some(FileInfo { + file_id: std::mem::transmute::(file_info.FileId), + dev_id: std::mem::transmute::(file_info.VolumeSerialNumber), + }); } } - inode + result } fn unit_string_to_number(s: &str) -> Option { @@ -239,7 +253,7 @@ fn du( mut my_stat: Stat, options: &Options, depth: usize, - inodes: &mut HashSet, + inodes: &mut HashSet, ) -> Box> { let mut stats = vec![]; let mut futures = vec![]; @@ -523,7 +537,7 @@ Try '{} --help' for more information.", let path = PathBuf::from(&path_str); match Stat::new(path) { Ok(stat) => { - let mut inodes: HashSet = HashSet::new(); + let mut inodes: HashSet = HashSet::new(); let iter = du(stat, &options, 0, &mut inodes); let (_, len) = iter.size_hint(); From 7859bf885fa0c3ad666b2837174c592a84f62978 Mon Sep 17 00:00:00 2001 From: Paul Otten Date: Thu, 1 Apr 2021 19:42:43 -0400 Subject: [PATCH 065/132] Consistency with GNU version of `du` when doing `du -h` on an empty file --- src/uu/du/src/du.rs | 3 +++ tests/by-util/test_du.rs | 10 ++++++++++ tests/fixtures/du/empty.txt | 0 3 files changed, 13 insertions(+) create mode 100644 tests/fixtures/du/empty.txt diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 2eb7bd658..5ce193842 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -305,6 +305,9 @@ fn convert_size_human(size: u64, multiplier: u64, _block_size: u64) -> String { return format!("{:.1}{}", (size as f64) / (limit as f64), unit); } } + if size == 0 { + return format!("0"); + } format!("{}B", size) } diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index c810bd395..b3b1b3465 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -162,3 +162,13 @@ fn _du_d_flag(s: String) { assert_eq!(s, "8\t./subdir\n8\t./\n"); } } + +#[test] +fn test_du_h_flag_empty_file() { + let ts = TestScenario::new("du"); + + let result = ts.ucmd().arg("-h").arg("empty.txt").run(); + assert!(result.success); + assert_eq!(result.stderr, ""); + assert_eq!(result.stdout, "0\tempty.txt\n"); +} diff --git a/tests/fixtures/du/empty.txt b/tests/fixtures/du/empty.txt new file mode 100644 index 000000000..e69de29bb From 4a6176855a1911df37250557880a52ea1bf6542b Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Fri, 2 Apr 2021 09:55:57 +0200 Subject: [PATCH 066/132] relpath: move from getops to clap (#1939) (#1990) * relpath: add tests * relpath: move from getopts to clap --- src/uu/relpath/Cargo.toml | 2 +- src/uu/relpath/src/relpath.rs | 103 ++++++++------------- tests/by-util/test_relpath.rs | 166 +++++++++++++++++++++++++++++++++- 3 files changed, 206 insertions(+), 65 deletions(-) diff --git a/src/uu/relpath/Cargo.toml b/src/uu/relpath/Cargo.toml index 1dc296ec6..c923b42ac 100644 --- a/src/uu/relpath/Cargo.toml +++ b/src/uu/relpath/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/relpath.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33.3" uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/relpath/src/relpath.rs b/src/uu/relpath/src/relpath.rs index 4e165df1f..82779107a 100644 --- a/src/uu/relpath/src/relpath.rs +++ b/src/uu/relpath/src/relpath.rs @@ -10,62 +10,60 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::env; use std::path::{Path, PathBuf}; use uucore::fs::{canonicalize, CanonicalizeMode}; -static NAME: &str = "relpath"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static ABOUT: &str = "Convert TO destination to the relative path from the FROM dir. +If FROM path is omitted, current working dir will be used."; + +mod options { + pub const DIR: &str = "DIR"; + pub const TO: &str = "TO"; + pub const FROM: &str = "FROM"; +} + +fn get_usage() -> String { + format!("{} [-d DIR] TO [FROM]", executable!()) +} pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); + let usage = get_usage(); - let mut opts = getopts::Options::new(); + let matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .arg( + Arg::with_name(options::DIR) + .short("d") + .takes_value(true) + .help("If any of FROM and TO is not subpath of DIR, output absolute path instead of relative"), + ) + .arg( + Arg::with_name(options::TO) + .required(true) + .takes_value(true), + ) + .arg( + Arg::with_name(options::FROM) + .takes_value(true), + ) + .get_matches_from(args); - opts.optflag("h", "help", "Show help and exit"); - opts.optflag("V", "version", "Show version and exit"); - opts.optopt( - "d", - "", - "If any of FROM and TO is not subpath of DIR, output absolute path instead of relative", - "DIR", - ); - - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => { - show_error!("{}", f); - show_usage(&opts); - return 1; - } - }; - - if matches.opt_present("V") { - version(); - return 0; - } - if matches.opt_present("h") { - show_usage(&opts); - return 0; - } - - if matches.free.is_empty() { - show_error!("Missing operand: TO"); - println!("Try `{} --help` for more information.", NAME); - return 1; - } - - let to = Path::new(&matches.free[0]); - let from = if matches.free.len() > 1 { - Path::new(&matches.free[1]).to_path_buf() - } else { - env::current_dir().unwrap() + let to = Path::new(matches.value_of(options::TO).unwrap()).to_path_buf(); // required + let from = match matches.value_of(options::FROM) { + Some(p) => Path::new(p).to_path_buf(), + None => env::current_dir().unwrap(), }; let absto = canonicalize(to, CanonicalizeMode::Normal).unwrap(); let absfrom = canonicalize(from, CanonicalizeMode::Normal).unwrap(); - if matches.opt_present("d") { - let base = Path::new(&matches.opt_str("d").unwrap()).to_path_buf(); + if matches.is_present(options::DIR) { + let base = Path::new(&matches.value_of(options::DIR).unwrap()).to_path_buf(); let absbase = canonicalize(base, CanonicalizeMode::Normal).unwrap(); if !absto.as_path().starts_with(absbase.as_path()) || !absfrom.as_path().starts_with(absbase.as_path()) @@ -99,24 +97,3 @@ pub fn uumain(args: impl uucore::Args) -> i32 { println!("{}", result.display()); 0 } - -fn version() { - println!("{} {}", NAME, VERSION) -} - -fn show_usage(opts: &getopts::Options) { - version(); - println!(); - println!("Usage:"); - println!(" {} [-d DIR] TO [FROM]", NAME); - println!(" {} -V|--version", NAME); - println!(" {} -h|--help", NAME); - println!(); - print!( - "{}", - opts.usage( - "Convert TO destination to the relative path from the FROM dir.\n\ - If FROM path is omitted, current working dir will be used." - ) - ); -} diff --git a/tests/by-util/test_relpath.rs b/tests/by-util/test_relpath.rs index 651491045..690531896 100644 --- a/tests/by-util/test_relpath.rs +++ b/tests/by-util/test_relpath.rs @@ -1 +1,165 @@ -// ToDO: add tests +use crate::common::util::*; +use std::borrow::Cow; +use std::path::Path; + +struct TestCase<'a> { + from: &'a str, + to: &'a str, + expected: &'a str, +} + +const TESTS: [TestCase; 10] = [ + TestCase { + from: "A/B/C", + to: "A", + expected: "../..", + }, + TestCase { + from: "A/B/C", + to: "A/B", + expected: "..", + }, + TestCase { + from: "A/B/C", + to: "A/B/C", + expected: "", + }, + TestCase { + from: "A/B/C", + to: "A/B/C/D", + expected: "D", + }, + TestCase { + from: "A/B/C", + to: "A/B/C/D/E", + expected: "D/E", + }, + TestCase { + from: "A/B/C", + to: "A/B/D", + expected: "../D", + }, + TestCase { + from: "A/B/C", + to: "A/B/D/E", + expected: "../D/E", + }, + TestCase { + from: "A/B/C", + to: "A/D", + expected: "../../D", + }, + TestCase { + from: "A/B/C", + to: "D/E/F", + expected: "../../../D/E/F", + }, + TestCase { + from: "A/B/C", + to: "A/D/E", + expected: "../../D/E", + }, +]; + +fn convert_path<'a>(path: &'a str) -> Cow<'a, str> { + #[cfg(windows)] + return path.replace("/", "\\").into(); + #[cfg(not(windows))] + return path.into(); +} + +#[test] +fn test_relpath_with_from_no_d() { + for test in TESTS.iter() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let from: &str = &convert_path(test.from); + let to: &str = &convert_path(test.to); + let expected: &str = &convert_path(test.expected); + + at.mkdir_all(to); + at.mkdir_all(from); + + scene + .ucmd() + .arg(to) + .arg(from) + .succeeds() + .stdout_only(&format!("{}\n", expected)); + } +} + +#[test] +fn test_relpath_with_from_with_d() { + for test in TESTS.iter() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let from: &str = &convert_path(test.from); + let to: &str = &convert_path(test.to); + let pwd = at.as_string(); + at.mkdir_all(to); + at.mkdir_all(from); + + // d is part of subpath -> expect relative path + let mut result = scene + .ucmd() + .arg(to) + .arg(from) + .arg(&format!("-d{}", pwd)) + .run(); + assert!(result.success); + // relax rules for windows test environment + #[cfg(not(windows))] + assert!(Path::new(&result.stdout).is_relative()); + + // d is not part of subpath -> expect absolut path + result = scene.ucmd().arg(to).arg(from).arg("-dnon_existing").run(); + assert!(result.success); + assert!(Path::new(&result.stdout).is_absolute()); + } +} + +#[test] +fn test_relpath_no_from_no_d() { + for test in TESTS.iter() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let to: &str = &convert_path(test.to); + at.mkdir_all(to); + + let result = scene.ucmd().arg(to).run(); + assert!(result.success); + #[cfg(not(windows))] + assert_eq!(result.stdout, format!("{}\n", to)); + // relax rules for windows test environment + #[cfg(windows)] + assert!(result.stdout.ends_with(&format!("{}\n", to))); + } +} + +#[test] +fn test_relpath_no_from_with_d() { + for test in TESTS.iter() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let to: &str = &convert_path(test.to); + let pwd = at.as_string(); + at.mkdir_all(to); + + // d is part of subpath -> expect relative path + let mut result = scene.ucmd().arg(to).arg(&format!("-d{}", pwd)).run(); + assert!(result.success); + // relax rules for windows test environment + #[cfg(not(windows))] + assert!(Path::new(&result.stdout).is_relative()); + + // d is not part of subpath -> expect absolut path + result = scene.ucmd().arg(to).arg("-dnon_existing").run(); + assert!(result.success); + assert!(Path::new(&result.stdout).is_absolute()); + } +} From 2eb32d845ec023ce4f1878e1b7a27d1206cee7fc Mon Sep 17 00:00:00 2001 From: ReggaeMuffin <644950+reggaemuffin@users.noreply.github.com> Date: Fri, 2 Apr 2021 10:56:49 +0100 Subject: [PATCH 067/132] chores: run `cargo +1.40.0 fmt` Apparently fmt from 1.40.0 is a bit more strict in some places Let me know if this is worthwhile merging :) --- Cargo.lock | 2 +- build.rs | 38 +++++++++--------- src/uu/chroot/src/chroot.rs | 4 +- src/uu/head/src/head.rs | 30 +++++++------- src/uu/hostname/src/hostname.rs | 2 +- src/uu/ln/src/ln.rs | 4 +- src/uu/mktemp/src/mktemp.rs | 10 ++--- src/uu/numfmt/src/numfmt.rs | 8 ++-- src/uu/readlink/src/readlink.rs | 6 +-- src/uu/shred/src/shred.rs | 70 ++++++++++++++++----------------- src/uu/stdbuf/src/stdbuf.rs | 3 +- src/uu/uptime/src/uptime.rs | 4 +- tests/common/util.rs | 8 ++-- 13 files changed, 94 insertions(+), 95 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f40d512ce..88984362b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2181,7 +2181,7 @@ dependencies = [ name = "uu_relpath" version = "0.0.4" dependencies = [ - "getopts", + "clap", "uucore", "uucore_procs", ] diff --git a/build.rs b/build.rs index 625a3ccc8..ae38177b0 100644 --- a/build.rs +++ b/build.rs @@ -44,10 +44,10 @@ pub fn main() { mf.write_all( "type UtilityMap = HashMap<&'static str, fn(T) -> i32>;\n\ - \n\ - fn util_map() -> UtilityMap {\n\ - \tlet mut map = UtilityMap::new();\n\ - " + \n\ + fn util_map() -> UtilityMap {\n\ + \tlet mut map = UtilityMap::new();\n\ + " .as_bytes(), ) .unwrap(); @@ -97,21 +97,21 @@ pub fn main() { mf.write_all( format!( "\ - \tmap.insert(\"{krate}\", {krate}::uumain);\n\ - \t\tmap.insert(\"md5sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha1sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha224sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha256sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha384sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha512sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha3sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha3-224sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha3-256sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha3-384sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"sha3-512sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"shake128sum\", {krate}::uumain);\n\ - \t\tmap.insert(\"shake256sum\", {krate}::uumain);\n\ - ", + \tmap.insert(\"{krate}\", {krate}::uumain);\n\ + \t\tmap.insert(\"md5sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha1sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha224sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha256sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha384sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha512sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha3sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha3-224sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha3-256sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha3-384sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"sha3-512sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"shake128sum\", {krate}::uumain);\n\ + \t\tmap.insert(\"shake256sum\", {krate}::uumain);\n\ + ", krate = krate ) .as_bytes(), diff --git a/src/uu/chroot/src/chroot.rs b/src/uu/chroot/src/chroot.rs index 2c3bcbca4..44c5dfa02 100644 --- a/src/uu/chroot/src/chroot.rs +++ b/src/uu/chroot/src/chroot.rs @@ -65,8 +65,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(options::USERSPEC) .help( "Colon-separated user and group to switch to. \ - Same as -u USER -g GROUP. \ - Userspec has higher preference than -u and/or -g", + Same as -u USER -g GROUP. \ + Userspec has higher preference than -u and/or -g", ) .value_name("USER:GROUP"), ) diff --git a/src/uu/head/src/head.rs b/src/uu/head/src/head.rs index a8f519f6b..3500af544 100644 --- a/src/uu/head/src/head.rs +++ b/src/uu/head/src/head.rs @@ -10,13 +10,13 @@ const BUF_SIZE: usize = 65536; const VERSION: &str = env!("CARGO_PKG_VERSION"); const ABOUT: &str = "\ - Print the first 10 lines of each FILE to standard output.\n\ - With more than one FILE, precede each with a header giving the file name.\n\ - \n\ - With no FILE, or when FILE is -, read standard input.\n\ - \n\ - Mandatory arguments to long flags are mandatory for short flags too.\ - "; + Print the first 10 lines of each FILE to standard output.\n\ + With more than one FILE, precede each with a header giving the file name.\n\ + \n\ + With no FILE, or when FILE is -, read standard input.\n\ + \n\ + Mandatory arguments to long flags are mandatory for short flags too.\ + "; const USAGE: &str = "head [FLAG]... [FILE]..."; mod options { @@ -43,10 +43,10 @@ fn app<'a>() -> App<'a, 'a> { .takes_value(true) .help( "\ - print the first NUM bytes of each file;\n\ - with the leading '-', print all but the last\n\ - NUM bytes of each file\ - ", + print the first NUM bytes of each file;\n\ + with the leading '-', print all but the last\n\ + NUM bytes of each file\ + ", ) .overrides_with_all(&[options::BYTES_NAME, options::LINES_NAME]) .allow_hyphen_values(true), @@ -59,10 +59,10 @@ fn app<'a>() -> App<'a, 'a> { .takes_value(true) .help( "\ - print the first NUM lines instead of the first 10;\n\ - with the leading '-', print all but the last\n\ - NUM lines of each file\ - ", + print the first NUM lines instead of the first 10;\n\ + with the leading '-', print all but the last\n\ + NUM lines of each file\ + ", ) .overrides_with_all(&[options::LINES_NAME, options::BYTES_NAME]) .allow_hyphen_values(true), diff --git a/src/uu/hostname/src/hostname.rs b/src/uu/hostname/src/hostname.rs index f37b6a74d..d6f70be16 100644 --- a/src/uu/hostname/src/hostname.rs +++ b/src/uu/hostname/src/hostname.rs @@ -78,7 +78,7 @@ fn execute(args: impl uucore::Args) -> i32 { ) .arg(Arg::with_name(OPT_SHORT).short("s").long("short").help( "Display the short hostname (the portion before the first dot) if \ - possible", + possible", )) .arg(Arg::with_name(OPT_HOST)) .get_matches_from(args); diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index 394cf13af..96a0df813 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -111,7 +111,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_BACKUP) .help( "make a backup of each file that would otherwise be overwritten \ - or removed", + or removed", ) .takes_value(true) .possible_value("simple") @@ -145,7 +145,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_NO_DEREFERENCE) .help( "treat LINK_executable!() as a normal file if it is a \ - symbolic link to a directory", + symbolic link to a directory", ), ) // TODO: opts.arg( diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 194b6625f..ed767ffe0 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -71,7 +71,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_SUFFIX) .help( "append SUFF to TEMPLATE; SUFF must not contain a path separator. \ - This option is implied if TEMPLATE does not end with X.", + This option is implied if TEMPLATE does not end with X.", ) .value_name("SUFF"), ) @@ -81,15 +81,15 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_TMPDIR) .help( "interpret TEMPLATE relative to DIR; if DIR is not specified, use \ - $TMPDIR if set, else /tmp. With this option, TEMPLATE must not \ - be an absolute name; unlike with -t, TEMPLATE may contain \ - slashes, but mktemp creates only the final component", + $TMPDIR if set, else /tmp. With this option, TEMPLATE must not \ + be an absolute name; unlike with -t, TEMPLATE may contain \ + slashes, but mktemp creates only the final component", ) .value_name("DIR"), ) .arg(Arg::with_name(OPT_T).short(OPT_T).help( "Generate a template (using the supplied prefix and TMPDIR if set) \ - to create a filename template [deprecated]", + to create a filename template [deprecated]", )) .arg( Arg::with_name(ARG_TEMPLATE) diff --git a/src/uu/numfmt/src/numfmt.rs b/src/uu/numfmt/src/numfmt.rs index 29c422a89..e9a476956 100644 --- a/src/uu/numfmt/src/numfmt.rs +++ b/src/uu/numfmt/src/numfmt.rs @@ -187,9 +187,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(options::PADDING) .help( "pad the output to N characters; positive N will \ - right-align; negative N will left-align; padding is \ - ignored if the output is wider than N; the default is \ - to automatically pad if a whitespace is found", + right-align; negative N will left-align; padding is \ + ignored if the output is wider than N; the default is \ + to automatically pad if a whitespace is found", ) .value_name("N"), ) @@ -198,7 +198,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(options::HEADER) .help( "print (without converting) the first N header lines; \ - N defaults to 1 if not specified", + N defaults to 1 if not specified", ) .value_name("N") .default_value(options::HEADER_DEFAULT) diff --git a/src/uu/readlink/src/readlink.rs b/src/uu/readlink/src/readlink.rs index 8bc9a2aeb..727c2cce5 100644 --- a/src/uu/readlink/src/readlink.rs +++ b/src/uu/readlink/src/readlink.rs @@ -46,7 +46,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_CANONICALIZE) .help( "canonicalize by following every symlink in every component of the \ - given name recursively; all but the last component must exist", + given name recursively; all but the last component must exist", ), ) .arg( @@ -55,7 +55,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long("canonicalize-existing") .help( "canonicalize by following every symlink in every component of the \ - given name recursively, all components must exist", + given name recursively, all components must exist", ), ) .arg( @@ -64,7 +64,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_CANONICALIZE_MISSING) .help( "canonicalize by following every symlink in every component of the \ - given name recursively, without requirements on components existence", + given name recursively, without requirements on components existence", ), ) .arg( diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index c5f4d6e57..d5f910297 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -223,40 +223,40 @@ fn get_usage() -> String { static AFTER_HELP: &str = "Delete FILE(s) if --remove (-u) is specified. The default is not to remove\n\ -the files because it is common to operate on device files like /dev/hda,\n\ -and those files usually should not be removed.\n\ -\n\ -CAUTION: Note that shred relies on a very important assumption:\n\ -that the file system overwrites data in place. This is the traditional\n\ -way to do things, but many modern file system designs do not satisfy this\n\ -assumption. The following are examples of file systems on which shred is\n\ -not effective, or is not guaranteed to be effective in all file system modes:\n\ -\n\ -* log-structured or journaled file systems, such as those supplied with\n\ -AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.)\n\ -\n\ -* file systems that write redundant data and carry on even if some writes\n\ -fail, such as RAID-based file systems\n\ -\n\ -* file systems that make snapshots, such as Network Appliance's NFS server\n\ -\n\ -* file systems that cache in temporary locations, such as NFS\n\ -version 3 clients\n\ -\n\ -* compressed file systems\n\ -\n\ -In the case of ext3 file systems, the above disclaimer applies\n\ -and shred is thus of limited effectiveness) only in data=journal mode,\n\ -which journals file data in addition to just metadata. In both the\n\ -data=ordered (default) and data=writeback modes, shred works as usual.\n\ -Ext3 journaling modes can be changed by adding the data=something option\n\ -to the mount options for a particular file system in the /etc/fstab file,\n\ -as documented in the mount man page (man mount).\n\ -\n\ -In addition, file system backups and remote mirrors may contain copies\n\ -of the file that cannot be removed, and that will allow a shredded file\n\ -to be recovered later.\n\ -"; + the files because it is common to operate on device files like /dev/hda,\n\ + and those files usually should not be removed.\n\ + \n\ + CAUTION: Note that shred relies on a very important assumption:\n\ + that the file system overwrites data in place. This is the traditional\n\ + way to do things, but many modern file system designs do not satisfy this\n\ + assumption. The following are examples of file systems on which shred is\n\ + not effective, or is not guaranteed to be effective in all file system modes:\n\ + \n\ + * log-structured or journaled file systems, such as those supplied with\n\ + AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.)\n\ + \n\ + * file systems that write redundant data and carry on even if some writes\n\ + fail, such as RAID-based file systems\n\ + \n\ + * file systems that make snapshots, such as Network Appliance's NFS server\n\ + \n\ + * file systems that cache in temporary locations, such as NFS\n\ + version 3 clients\n\ + \n\ + * compressed file systems\n\ + \n\ + In the case of ext3 file systems, the above disclaimer applies\n\ + and shred is thus of limited effectiveness) only in data=journal mode,\n\ + which journals file data in addition to just metadata. In both the\n\ + data=ordered (default) and data=writeback modes, shred works as usual.\n\ + Ext3 journaling modes can be changed by adding the data=something option\n\ + to the mount options for a particular file system in the /etc/fstab file,\n\ + as documented in the mount man page (man mount).\n\ + \n\ + In addition, file system backups and remote mirrors may contain copies\n\ + of the file that cannot be removed, and that will allow a shredded file\n\ + to be recovered later.\n\ + "; pub mod options { pub const FILE: &str = "file"; @@ -312,7 +312,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .short("x") .help( "do not round file sizes up to the next full block;\n\ -this is the default for non-regular files", + this is the default for non-regular files", ), ) .arg( diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index 67ed9a838..a61ba967b 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -80,7 +80,8 @@ fn print_version() { fn print_usage(opts: &Options) { let brief = "Run COMMAND, with modified buffering operations for its standard streams\n \ Mandatory arguments to long options are mandatory for short options too."; - let explanation = "If MODE is 'L' the corresponding stream will be line buffered.\n \ + let explanation = + "If MODE is 'L' the corresponding stream will be line buffered.\n \ This option is invalid with standard input.\n\n \ If MODE is '0' the corresponding stream will be unbuffered.\n\n \ Otherwise MODE is a number which may be followed by one of the following:\n\n \ diff --git a/src/uu/uptime/src/uptime.rs b/src/uu/uptime/src/uptime.rs index 670d7845b..418b8317f 100644 --- a/src/uu/uptime/src/uptime.rs +++ b/src/uu/uptime/src/uptime.rs @@ -19,8 +19,8 @@ use uucore::libc::time_t; static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Display the current time, the length of time the system has been up,\n\ -the number of users on the system, and the average number of jobs\n\ -in the run queue over the last 1, 5 and 15 minutes."; + the number of users on the system, and the average number of jobs\n\ + in the run queue over the last 1, 5 and 15 minutes."; pub mod options { pub static SINCE: &str = "since"; } diff --git a/tests/common/util.rs b/tests/common/util.rs index 922525ed2..708b8dbba 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -29,8 +29,8 @@ static TESTS_DIR: &str = "tests"; static FIXTURES_DIR: &str = "fixtures"; static ALREADY_RUN: &str = " you have already run this UCommand, if you want to run \ - another command in the same test, use TestScenario::new instead of \ - testing();"; + another command in the same test, use TestScenario::new instead of \ + testing();"; static MULTIPLE_STDIN_MEANINGLESS: &str = "Ucommand is designed around a typical use case of: provide args and input stream -> spawn process -> block until completion -> return output streams. For verifying that a particular section of the input stream is what causes a particular behavior, use the Command type directly."; /// Test if the program is running under CI @@ -135,9 +135,7 @@ impl CmdResult { pub fn tmpd(&self) -> Rc { match &self.tmpd { Some(ptr) => ptr.clone(), - None => { - panic!("Command not associated with a TempDir") - } + None => panic!("Command not associated with a TempDir"), } } From d12f96d9ca5c72f573782b252e64aa43f9b82a4d Mon Sep 17 00:00:00 2001 From: Daniel Rocco Date: Fri, 2 Apr 2021 09:13:25 -0400 Subject: [PATCH 068/132] fold: preserve blank lines --- src/uu/fold/src/fold.rs | 5 ++++- tests/by-util/test_fold.rs | 28 +++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 05f0725ef..27ab319d0 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -100,7 +100,10 @@ fn fold(filenames: Vec, bytes: bool, spaces: bool, width: usize) { fn fold_file(file: BufReader, bytes: bool, spaces: bool, width: usize) { for line_result in file.lines() { let mut line = safe_unwrap!(line_result); - if bytes { + + if line.is_empty() { + println!(); + } else if bytes { let len = line.len(); let mut i = 0; while i < len { diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index c17f300d2..64d77cd2b 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -25,9 +25,35 @@ fn test_40_column_word_boundary() { } #[test] -fn test_default_warp_with_newlines() { +fn test_default_wrap_with_newlines() { new_ucmd!() .arg("lorem_ipsum_new_line.txt") .run() .stdout_is_fixture("lorem_ipsum_new_line_80_column.expected"); } + +#[test] +fn test_should_preserve_empty_lines() { + new_ucmd!().pipe_in("\n").succeeds().stdout_is("\n"); + + new_ucmd!() + .arg("-w1") + .pipe_in("0\n1\n\n2\n\n\n") + .succeeds() + .stdout_is("0\n1\n\n2\n\n\n"); +} + +#[test] +fn test_word_boundary_split_should_preserve_empty_lines() { + new_ucmd!() + .arg("-s") + .pipe_in("\n") + .succeeds() + .stdout_is("\n"); + + new_ucmd!() + .args(&["-w1", "-s"]) + .pipe_in("0\n1\n\n2\n\n\n") + .succeeds() + .stdout_is("0\n1\n\n2\n\n\n"); +} From 349c4f7af66d5c4baa9ee806e7a327e35114fa94 Mon Sep 17 00:00:00 2001 From: Juliana Rodrigueiro Date: Fri, 2 Apr 2021 19:04:14 +0100 Subject: [PATCH 069/132] install: Make log message identical to GNU install $ install -v -d dir1 install: creating directory 'dir1' --- src/uu/install/src/install.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index b4f98ec1a..35097da09 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -372,7 +372,7 @@ fn directory(paths: Vec, b: Behavior) -> i32 { } if b.verbose { - show_info!("created directory '{}'", path.display()); + show_info!("creating directory '{}'", path.display()); } } if all_successful { From 2a02f01fc2ac3b5e86f56543cd6daf396ea70c07 Mon Sep 17 00:00:00 2001 From: Juliana Rodrigueiro Date: Fri, 2 Apr 2021 19:13:56 +0100 Subject: [PATCH 070/132] install: Don't display success message when the dir was not created Also don't run chmod when we just failed to create the directory. Behaviour before this patch: $ ./target/release/install -v -d dir1/dir2 install: dir1/dir2: Permission denied (os error 13) install: dir1/dir2: chmod failed with error No such file or directory (os error 2) install: created directory 'dir1/dir2' --- src/uu/install/src/install.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 35097da09..6267ed94f 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -364,15 +364,17 @@ fn directory(paths: Vec, b: Behavior) -> i32 { if let Err(e) = fs::create_dir(directory) { show_info!("{}: {}", path.display(), e.to_string()); all_successful = false; + continue; + } + + if b.verbose { + show_info!("creating directory '{}'", path.display()); } } if mode::chmod(&path, b.mode()).is_err() { all_successful = false; - } - - if b.verbose { - show_info!("creating directory '{}'", path.display()); + continue; } } if all_successful { From 97da14fcb20a13912ae177b5a781c2cde9d1c3f7 Mon Sep 17 00:00:00 2001 From: Juliana Rodrigueiro Date: Fri, 2 Apr 2021 20:04:25 +0100 Subject: [PATCH 071/132] install: Fix behaviour of the -d flag The '-d' flag should create all ancestors (or components) of a directory regardless of the presence of the "-D" flag. From the man page: -d, --directory treat all arguments as directory names; create all components of the specified directories With GNU: $ install -v -d dir1/di2 install: creating directory 'dir1' install: creating directory 'dir1/di2' With this version: $ ./target/release/install -v -d dir3/di4 install: dir3/di4: No such file or directory (os error 2) install: dir3/di4: chmod failed with error No such file or directory (os error 2) install: created directory 'dir3/di4' Also, one of the unit tests misinterprets what a "component" is, and hence was fixed. --- src/uu/install/src/install.rs | 14 ++++--- tests/by-util/test_install.rs | 77 +++++++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 6267ed94f..a4f1ca6e6 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -356,13 +356,17 @@ fn directory(paths: Vec, b: Behavior) -> i32 { } else { let mut all_successful = true; - for directory in paths.iter() { - let path = Path::new(directory); - + for path in paths.iter().map(Path::new) { // if the path already exist, don't try to create it again if !path.exists() { - if let Err(e) = fs::create_dir(directory) { - show_info!("{}: {}", path.display(), e.to_string()); + // Differently than the primary functionality (MainFunction::Standard), the directory + // functionality should create all ancestors (or components) of a directory regardless + // of the presence of the "-D" flag. + // NOTE: the GNU "install" sets the expected mode only for the target directory. All + // created ancestor directories will have the default mode. Hence it is safe to use + // fs::create_dir_all and then only modify the target's dir mode. + if let Err(e) = fs::create_dir_all(path) { + show_info!("{}: {}", path.display(), e); all_successful = false; continue; } diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index af48a0e66..8ac6396fd 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -87,20 +87,81 @@ fn test_install_unimplemented_arg() { } #[test] -fn test_install_component_directories() { +fn test_install_ancestors_directories() { let (at, mut ucmd) = at_and_ucmd!(); - let component1 = "component1"; - let component2 = "component2"; - let component3 = "component3"; + let ancestor1 = "ancestor1"; + let ancestor2 = "ancestor1/ancestor2"; + let target_dir = "ancestor1/ancestor2/target_dir"; let directories_arg = "-d"; - ucmd.args(&[directories_arg, component1, component2, component3]) + ucmd.args(&[directories_arg, target_dir]) .succeeds() .no_stderr(); - assert!(at.dir_exists(component1)); - assert!(at.dir_exists(component2)); - assert!(at.dir_exists(component3)); + assert!(at.dir_exists(ancestor1)); + assert!(at.dir_exists(ancestor2)); + assert!(at.dir_exists(target_dir)); +} + +#[test] +fn test_install_ancestors_mode_directories() { + let (at, mut ucmd) = at_and_ucmd!(); + let ancestor1 = "ancestor1"; + let ancestor2 = "ancestor1/ancestor2"; + let target_dir = "ancestor1/ancestor2/target_dir"; + let directories_arg = "-d"; + let mode_arg = "--mode=700"; + + ucmd.args(&[mode_arg, directories_arg, target_dir]) + .succeeds() + .no_stderr(); + + assert!(at.dir_exists(ancestor1)); + assert!(at.dir_exists(ancestor2)); + assert!(at.dir_exists(target_dir)); + + assert_ne!(0o40700 as u32, at.metadata(ancestor1).permissions().mode()); + assert_ne!(0o40700 as u32, at.metadata(ancestor2).permissions().mode()); + + // Expected mode only on the target_dir. + assert_eq!(0o40700 as u32, at.metadata(target_dir).permissions().mode()); +} + +#[test] +fn test_install_parent_directories() { + let (at, mut ucmd) = at_and_ucmd!(); + let ancestor1 = "ancestor1"; + let ancestor2 = "ancestor1/ancestor2"; + let target_dir = "ancestor1/ancestor2/target_dir"; + let directories_arg = "-d"; + + // Here one of the ancestors already exist and only the target_dir and + // its parent must be created. + at.mkdir(ancestor1); + + ucmd.args(&[directories_arg, target_dir]) + .succeeds() + .no_stderr(); + + assert!(at.dir_exists(ancestor2)); + assert!(at.dir_exists(target_dir)); +} + +#[test] +fn test_install_several_directories() { + let (at, mut ucmd) = at_and_ucmd!(); + let dir1 = "dir1"; + let dir2 = "dir2"; + let dir3 = "dir3"; + let directories_arg = "-d"; + + ucmd.args(&[directories_arg, dir1, dir2, dir3]) + .succeeds() + .no_stderr(); + + assert!(at.dir_exists(dir1)); + assert!(at.dir_exists(dir2)); + assert!(at.dir_exists(dir3)); } #[test] From 9151410d08bdf332a7edca93518810278aad5568 Mon Sep 17 00:00:00 2001 From: Sivachandran Date: Sat, 3 Apr 2021 01:44:56 +0530 Subject: [PATCH 072/132] csplit: move from getopts to clap (#1995) --- src/uu/csplit/Cargo.toml | 2 +- src/uu/csplit/src/csplit.rs | 139 +++++++++++++++++++++++------------- 2 files changed, 91 insertions(+), 50 deletions(-) diff --git a/src/uu/csplit/Cargo.toml b/src/uu/csplit/Cargo.toml index 68c6e2322..7cec4564b 100644 --- a/src/uu/csplit/Cargo.toml +++ b/src/uu/csplit/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/csplit.rs" [dependencies] -getopts = "0.2.17" +clap = "2.33" thiserror = "1.0" regex = "1.0.0" glob = "0.2.11" diff --git a/src/uu/csplit/src/csplit.rs b/src/uu/csplit/src/csplit.rs index 7eb287522..ce11ba49a 100644 --- a/src/uu/csplit/src/csplit.rs +++ b/src/uu/csplit/src/csplit.rs @@ -2,7 +2,7 @@ #[macro_use] extern crate uucore; -use getopts::Matches; +use clap::{App, Arg, ArgMatches}; use regex::Regex; use std::cmp::Ordering; use std::io::{self, BufReader}; @@ -18,17 +18,25 @@ mod splitname; use crate::csplit_error::CsplitError; use crate::splitname::SplitName; -static SYNTAX: &str = "[OPTION]... FILE PATTERN..."; +static VERSION: &str = env!("CARGO_PKG_VERSION"); static SUMMARY: &str = "split a file into sections determined by context lines"; static LONG_HELP: &str = "Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output."; -static SUFFIX_FORMAT_OPT: &str = "suffix-format"; -static SUPPRESS_MATCHED_OPT: &str = "suppress-matched"; -static DIGITS_OPT: &str = "digits"; -static PREFIX_OPT: &str = "prefix"; -static KEEP_FILES_OPT: &str = "keep-files"; -static QUIET_OPT: &str = "quiet"; -static ELIDE_EMPTY_FILES_OPT: &str = "elide-empty-files"; +mod options { + pub const SUFFIX_FORMAT: &str = "suffix-format"; + pub const SUPPRESS_MATCHED: &str = "suppress-matched"; + pub const DIGITS: &str = "digits"; + pub const PREFIX: &str = "prefix"; + pub const KEEP_FILES: &str = "keep-files"; + pub const QUIET: &str = "quiet"; + pub const ELIDE_EMPTY_FILES: &str = "elide-empty-files"; + pub const FILE: &str = "file"; + pub const PATTERN: &str = "pattern"; +} + +fn get_usage() -> String { + format!("{0} [OPTION]... FILE PATTERN...", executable!()) +} /// Command line options for csplit. pub struct CsplitOptions { @@ -40,19 +48,19 @@ pub struct CsplitOptions { } impl CsplitOptions { - fn new(matches: &Matches) -> CsplitOptions { - let keep_files = matches.opt_present(KEEP_FILES_OPT); - let quiet = matches.opt_present(QUIET_OPT); - let elide_empty_files = matches.opt_present(ELIDE_EMPTY_FILES_OPT); - let suppress_matched = matches.opt_present(SUPPRESS_MATCHED_OPT); + fn new(matches: &ArgMatches) -> CsplitOptions { + let keep_files = matches.is_present(options::KEEP_FILES); + let quiet = matches.is_present(options::QUIET); + let elide_empty_files = matches.is_present(options::ELIDE_EMPTY_FILES); + let suppress_matched = matches.is_present(options::SUPPRESS_MATCHED); CsplitOptions { split_name: crash_if_err!( 1, SplitName::new( - matches.opt_str(PREFIX_OPT), - matches.opt_str(SUFFIX_FORMAT_OPT), - matches.opt_str(DIGITS_OPT) + matches.value_of(options::PREFIX).map(str::to_string), + matches.value_of(options::SUFFIX_FORMAT).map(str::to_string), + matches.value_of(options::DIGITS).map(str::to_string) ) ), keep_files, @@ -702,45 +710,78 @@ mod tests { } pub fn uumain(args: impl uucore::Args) -> i32 { + let usage = get_usage(); let args = args.collect_str(); - let matches = app!(SYNTAX, SUMMARY, LONG_HELP) - .optopt( - "b", - SUFFIX_FORMAT_OPT, - "use sprintf FORMAT instead of %02d", - "FORMAT", + let matches = App::new(executable!()) + .version(VERSION) + .about(SUMMARY) + .usage(&usage[..]) + .arg( + Arg::with_name(options::SUFFIX_FORMAT) + .short("b") + .long(options::SUFFIX_FORMAT) + .value_name("FORMAT") + .help("use sprintf FORMAT instead of %02d"), ) - .optopt("f", PREFIX_OPT, "use PREFIX instead of 'xx'", "PREFIX") - .optflag("k", KEEP_FILES_OPT, "do not remove output files on errors") - .optflag( - "", - SUPPRESS_MATCHED_OPT, - "suppress the lines matching PATTERN", + .arg( + Arg::with_name(options::PREFIX) + .short("f") + .long(options::PREFIX) + .value_name("PREFIX") + .help("use PREFIX instead of 'xx'"), ) - .optopt( - "n", - DIGITS_OPT, - "use specified number of digits instead of 2", - "DIGITS", + .arg( + Arg::with_name(options::KEEP_FILES) + .short("k") + .long(options::KEEP_FILES) + .help("do not remove output files on errors"), ) - .optflag("s", QUIET_OPT, "do not print counts of output file sizes") - .optflag("z", ELIDE_EMPTY_FILES_OPT, "remove empty output files") - .parse(args); + .arg( + Arg::with_name(options::SUPPRESS_MATCHED) + .long(options::SUPPRESS_MATCHED) + .help("suppress the lines matching PATTERN"), + ) + .arg( + Arg::with_name(options::DIGITS) + .short("n") + .long(options::DIGITS) + .value_name("DIGITS") + .help("use specified number of digits instead of 2"), + ) + .arg( + Arg::with_name(options::QUIET) + .short("s") + .long(options::QUIET) + .visible_alias("silent") + .help("do not print counts of output file sizes"), + ) + .arg( + Arg::with_name(options::ELIDE_EMPTY_FILES) + .short("z") + .long(options::ELIDE_EMPTY_FILES) + .help("remove empty output files"), + ) + .arg(Arg::with_name(options::FILE).hidden(true).required(true)) + .arg( + Arg::with_name(options::PATTERN) + .hidden(true) + .multiple(true) + .required(true), + ) + .after_help(LONG_HELP) + .get_matches_from(args); - // check for mandatory arguments - if matches.free.is_empty() { - show_error!("missing operand"); - exit!(1); - } - if matches.free.len() == 1 { - show_error!("missing operand after '{}'", matches.free[0]); - exit!(1); - } - // get the patterns to split on - let patterns = return_if_err!(1, patterns::get_patterns(&matches.free[1..])); // get the file to split - let file_name: &str = &matches.free[0]; + let file_name = matches.value_of(options::FILE).unwrap(); + + // get the patterns to split on + let patterns: Vec = matches + .values_of(options::PATTERN) + .unwrap() + .map(str::to_string) + .collect(); + let patterns = return_if_err!(1, patterns::get_patterns(&patterns[..])); let options = CsplitOptions::new(&matches); if file_name == "-" { let stdin = io::stdin(); From 9fbed0b07ae171f2bdddc7cd0837ec2329ae0e3c Mon Sep 17 00:00:00 2001 From: Sandro Date: Fri, 2 Apr 2021 22:18:31 +0200 Subject: [PATCH 073/132] makefile: replace all uutils with coreutils (#1815) Co-authored-by: Sylvestre Ledru --- GNUmakefile | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index c4c9cbe8b..409a527cd 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -30,7 +30,7 @@ ifneq ($(.SHELLSTATUS),0) override INSTALLDIR_MAN=$(DESTDIR)$(PREFIX)$(MANDIR) endif -#prefix to apply to uutils binary and all tool binaries +#prefix to apply to coreutils binary and all tool binaries PROG_PREFIX ?= # This won't support any directory with spaces in its name, but you can just @@ -237,7 +237,7 @@ EXES := \ INSTALLEES := ${EXES} ifeq (${MULTICALL}, y) -INSTALLEES := ${INSTALLEES} uutils +INSTALLEES := ${INSTALLEES} coreutils endif all: build @@ -250,13 +250,13 @@ ifneq (${MULTICALL}, y) ${CARGO} build ${CARGOFLAGS} ${PROFILE_CMD} $(foreach pkg,$(EXES),-p uu_$(pkg)) endif -build-uutils: +build-coreutils: ${CARGO} build ${CARGOFLAGS} --features "${EXES}" ${PROFILE_CMD} --no-default-features build-manpages: cd $(DOCSDIR) && $(MAKE) man -build: build-uutils build-pkgs build-manpages +build: build-coreutils build-pkgs build-manpages $(foreach test,$(filter-out $(SKIP_UTILS),$(PROGS)),$(eval $(call TEST_BUSYBOX,$(test)))) @@ -275,7 +275,7 @@ $(BUILDDIR)/.config: $(BASEDIR)/.busybox-config cp $< $@ # Test under the busybox testsuite -$(BUILDDIR)/busybox: busybox-src build-uutils $(BUILDDIR)/.config +$(BUILDDIR)/busybox: busybox-src build-coreutils $(BUILDDIR)/.config cp $(BUILDDIR)/coreutils $(BUILDDIR)/busybox; \ chmod +x $@; @@ -298,10 +298,10 @@ install: build mkdir -p $(INSTALLDIR_BIN) mkdir -p $(INSTALLDIR_MAN) ifeq (${MULTICALL}, y) - $(INSTALL) $(BUILDDIR)/uutils $(INSTALLDIR_BIN)/$(PROG_PREFIX)uutils - cd $(INSTALLDIR_BIN) && $(foreach prog, $(filter-out uutils, $(INSTALLEES)), \ - ln -fs $(PROG_PREFIX)uutils $(PROG_PREFIX)$(prog) &&) : - cat $(DOCSDIR)/_build/man/uutils.1 | gzip > $(INSTALLDIR_MAN)/$(PROG_PREFIX)uutils.1.gz + $(INSTALL) $(BUILDDIR)/coreutils $(INSTALLDIR_BIN)/$(PROG_PREFIX)coreutils + cd $(INSTALLDIR_BIN) && $(foreach prog, $(filter-out coreutils, $(INSTALLEES)), \ + ln -fs $(PROG_PREFIX)coreutils $(PROG_PREFIX)$(prog) &&) : + cat $(DOCSDIR)/_build/man/coreutils.1 | gzip > $(INSTALLDIR_MAN)/$(PROG_PREFIX)coreutils.1.gz else $(foreach prog, $(INSTALLEES), \ $(INSTALL) $(BUILDDIR)/$(prog) $(INSTALLDIR_BIN)/$(PROG_PREFIX)$(prog);) @@ -311,10 +311,10 @@ endif uninstall: ifeq (${MULTICALL}, y) - rm -f $(addprefix $(INSTALLDIR_BIN)/,$(PROG_PREFIX)uutils) + rm -f $(addprefix $(INSTALLDIR_BIN)/,$(PROG_PREFIX)coreutils) endif - rm -f $(addprefix $(INSTALLDIR_MAN)/,$(PROG_PREFIX)uutils.1.gz) + rm -f $(addprefix $(INSTALLDIR_MAN)/,$(PROG_PREFIX)coreutils.1.gz) rm -f $(addprefix $(INSTALLDIR_BIN)/$(PROG_PREFIX),$(PROGS)) rm -f $(addprefix $(INSTALLDIR_MAN)/$(PROG_PREFIX),$(addsuffix .1.gz,$(PROGS))) -.PHONY: all build build-uutils build-pkgs build-docs test distclean clean busytest install uninstall +.PHONY: all build build-coreutils build-pkgs build-docs test distclean clean busytest install uninstall From 31f566672768d941a74169a90476400a8d1cd212 Mon Sep 17 00:00:00 2001 From: Jamie Quigley Date: Fri, 2 Apr 2021 21:34:02 +0100 Subject: [PATCH 074/132] more: add error message if the argument is a directory (#1983) --- src/uu/more/src/more.rs | 12 ++++++++++-- tests/by-util/test_more.rs | 11 +++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 981b5f502..59e7d0faa 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -41,7 +41,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .version(VERSION) - .usage(&usage[..]) + .usage(usage.as_str()) .about(ABOUT) .arg( Arg::with_name(options::FILE) @@ -52,10 +52,18 @@ pub fn uumain(args: impl uucore::Args) -> i32 { // FixME: fail without panic for now; but `more` should work with no arguments (ie, for piped input) if let None | Some("-") = matches.value_of(options::FILE) { - println!("{}: incorrect usage", executable!()); + show_usage_error!("Reading from stdin isn't supported yet."); return 1; } + if let Some(x) = matches.value_of(options::FILE) { + let path = std::path::Path::new(x); + if path.is_dir() { + show_usage_error!("'{}' is a directory.", x); + return 1; + } + } + more(matches); 0 diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index 3b7cfa9a8..736fb6956 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -6,3 +6,14 @@ fn test_more_no_arg() { let result = ucmd.run(); assert!(!result.success); } + +#[test] +fn test_more_dir_arg() { + let (_, mut ucmd) = at_and_ucmd!(); + ucmd.arg("."); + let result = ucmd.run(); + assert!(!result.success); + const EXPECTED_ERROR_MESSAGE: &str = + "more: '.' is a directory.\nTry 'more --help' for more information."; + assert_eq!(result.stderr.trim(), EXPECTED_ERROR_MESSAGE); +} From 14a49edd1cb9a841b390d796557e08d2b37d0039 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 2 Apr 2021 23:30:07 +0200 Subject: [PATCH 075/132] Use Iterator::copied() in sieve.rs (#1774) --- src/uu/factor/sieve.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/uu/factor/sieve.rs b/src/uu/factor/sieve.rs index c10321a7f..083efb3ef 100644 --- a/src/uu/factor/sieve.rs +++ b/src/uu/factor/sieve.rs @@ -7,7 +7,7 @@ // spell-checker:ignore (ToDO) filts, minidx, minkey paridx -use std::iter::{Chain, Cycle, Map}; +use std::iter::{Chain, Cycle, Copied}; use std::slice::Iter; /// A lazy Sieve of Eratosthenes. @@ -68,27 +68,17 @@ impl Sieve { #[allow(dead_code)] #[inline] pub fn primes() -> PrimeSieve { - #[allow(clippy::trivially_copy_pass_by_ref)] - fn deref(x: &u64) -> u64 { - *x - } - let deref = deref as fn(&u64) -> u64; - INIT_PRIMES.iter().map(deref).chain(Sieve::new()) + INIT_PRIMES.iter().copied().chain(Sieve::new()) } #[allow(dead_code)] #[inline] pub fn odd_primes() -> PrimeSieve { - #[allow(clippy::trivially_copy_pass_by_ref)] - fn deref(x: &u64) -> u64 { - *x - } - let deref = deref as fn(&u64) -> u64; - (&INIT_PRIMES[1..]).iter().map(deref).chain(Sieve::new()) + (&INIT_PRIMES[1..]).iter().copied().chain(Sieve::new()) } } -pub type PrimeSieve = Chain, fn(&u64) -> u64>, Sieve>; +pub type PrimeSieve = Chain>, Sieve>; /// An iterator that generates an infinite list of numbers that are /// not divisible by any of 2, 3, 5, or 7. From 2ef1b25d856774c553624d5ed909a2f300445054 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 2 Apr 2021 22:22:50 +0200 Subject: [PATCH 076/132] Create a new job to test make build --- .github/workflows/CICD.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index f1ddf9be1..a1683ab83 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -181,6 +181,28 @@ jobs: cd tmp/busybox-*/testsuite S=$(bindir=$bindir ./runtest) && printf "%s\n" "$S" || { printf "%s\n" "$S" | grep "FAIL:" | sed -e "s/FAIL: /::warning ::Test failure:/g" ; } + makefile_build: + name: Test the build target of the Makefile + runs-on: ${{ matrix.job.os }} + strategy: + fail-fast: false + matrix: + job: + - { os: ubuntu-latest } + steps: + - uses: actions/checkout@v1 + - name: Install `rust` toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + default: true + profile: minimal # minimal component installation (ie, no documentation) + - name: "Run make build" + shell: bash + run: | + sudo apt-get -y update ; sudo apt-get -y install python3-sphinx; + make build + build: name: Build runs-on: ${{ matrix.job.os }} From f10de40ab8fe7159392a358d2c67b8ac7dc49b63 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 2 Apr 2021 22:27:11 +0200 Subject: [PATCH 077/132] refresh cargo.lock with recent updates --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 88984362b..8806588ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1668,7 +1668,7 @@ dependencies = [ name = "uu_csplit" version = "0.0.4" dependencies = [ - "getopts", + "clap", "glob 0.2.11", "regex", "thiserror", From 4d7ad7743323dc5197866f2ae1f142cc6687fa98 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 2 Apr 2021 23:31:22 +0200 Subject: [PATCH 078/132] rustfmt the recent change --- src/uu/factor/sieve.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/factor/sieve.rs b/src/uu/factor/sieve.rs index 083efb3ef..41893699b 100644 --- a/src/uu/factor/sieve.rs +++ b/src/uu/factor/sieve.rs @@ -7,7 +7,7 @@ // spell-checker:ignore (ToDO) filts, minidx, minkey paridx -use std::iter::{Chain, Cycle, Copied}; +use std::iter::{Chain, Copied, Cycle}; use std::slice::Iter; /// A lazy Sieve of Eratosthenes. From ac031dffa45fc3c3ca26538109965b3389986191 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 3 Apr 2021 10:28:12 +0200 Subject: [PATCH 079/132] new release 0.0.5 --- Cargo.lock | 196 ++++++++++++------------- Cargo.toml | 196 ++++++++++++------------- src/uu/arch/Cargo.toml | 4 +- src/uu/base32/Cargo.toml | 4 +- src/uu/base64/Cargo.toml | 4 +- src/uu/basename/Cargo.toml | 4 +- src/uu/cat/Cargo.toml | 4 +- src/uu/chgrp/Cargo.toml | 4 +- src/uu/chmod/Cargo.toml | 4 +- src/uu/chown/Cargo.toml | 4 +- src/uu/chroot/Cargo.toml | 4 +- src/uu/cksum/Cargo.toml | 4 +- src/uu/comm/Cargo.toml | 4 +- src/uu/cp/Cargo.toml | 4 +- src/uu/csplit/Cargo.toml | 4 +- src/uu/cut/Cargo.toml | 4 +- src/uu/date/Cargo.toml | 4 +- src/uu/df/Cargo.toml | 4 +- src/uu/dircolors/Cargo.toml | 4 +- src/uu/dirname/Cargo.toml | 4 +- src/uu/du/Cargo.toml | 4 +- src/uu/echo/Cargo.toml | 4 +- src/uu/env/Cargo.toml | 4 +- src/uu/expand/Cargo.toml | 4 +- src/uu/expr/Cargo.toml | 4 +- src/uu/factor/Cargo.toml | 4 +- src/uu/false/Cargo.toml | 4 +- src/uu/fmt/Cargo.toml | 4 +- src/uu/fold/Cargo.toml | 4 +- src/uu/groups/Cargo.toml | 4 +- src/uu/hashsum/Cargo.toml | 4 +- src/uu/head/Cargo.toml | 4 +- src/uu/hostid/Cargo.toml | 4 +- src/uu/hostname/Cargo.toml | 4 +- src/uu/id/Cargo.toml | 4 +- src/uu/install/Cargo.toml | 4 +- src/uu/join/Cargo.toml | 4 +- src/uu/kill/Cargo.toml | 4 +- src/uu/link/Cargo.toml | 4 +- src/uu/ln/Cargo.toml | 4 +- src/uu/logname/Cargo.toml | 4 +- src/uu/ls/Cargo.toml | 4 +- src/uu/mkdir/Cargo.toml | 4 +- src/uu/mkfifo/Cargo.toml | 4 +- src/uu/mknod/Cargo.toml | 4 +- src/uu/mktemp/Cargo.toml | 4 +- src/uu/more/Cargo.toml | 2 +- src/uu/mv/Cargo.toml | 4 +- src/uu/nice/Cargo.toml | 4 +- src/uu/nl/Cargo.toml | 4 +- src/uu/nohup/Cargo.toml | 4 +- src/uu/nproc/Cargo.toml | 4 +- src/uu/numfmt/Cargo.toml | 4 +- src/uu/od/Cargo.toml | 4 +- src/uu/paste/Cargo.toml | 4 +- src/uu/pathchk/Cargo.toml | 4 +- src/uu/pinky/Cargo.toml | 4 +- src/uu/printenv/Cargo.toml | 4 +- src/uu/printf/Cargo.toml | 4 +- src/uu/ptx/Cargo.toml | 4 +- src/uu/pwd/Cargo.toml | 4 +- src/uu/readlink/Cargo.toml | 4 +- src/uu/realpath/Cargo.toml | 4 +- src/uu/relpath/Cargo.toml | 4 +- src/uu/rm/Cargo.toml | 4 +- src/uu/rmdir/Cargo.toml | 4 +- src/uu/seq/Cargo.toml | 4 +- src/uu/shred/Cargo.toml | 4 +- src/uu/shuf/Cargo.toml | 4 +- src/uu/sleep/Cargo.toml | 4 +- src/uu/sort/Cargo.toml | 4 +- src/uu/split/Cargo.toml | 4 +- src/uu/stat/Cargo.toml | 4 +- src/uu/stdbuf/Cargo.toml | 6 +- src/uu/stdbuf/src/libstdbuf/Cargo.toml | 4 +- src/uu/sum/Cargo.toml | 4 +- src/uu/sync/Cargo.toml | 4 +- src/uu/tac/Cargo.toml | 4 +- src/uu/tail/Cargo.toml | 4 +- src/uu/tee/Cargo.toml | 4 +- src/uu/test/Cargo.toml | 4 +- src/uu/timeout/Cargo.toml | 4 +- src/uu/touch/Cargo.toml | 4 +- src/uu/tr/Cargo.toml | 4 +- src/uu/true/Cargo.toml | 4 +- src/uu/truncate/Cargo.toml | 4 +- src/uu/tsort/Cargo.toml | 4 +- src/uu/tty/Cargo.toml | 4 +- src/uu/uname/Cargo.toml | 4 +- src/uu/unexpand/Cargo.toml | 4 +- src/uu/uniq/Cargo.toml | 4 +- src/uu/unlink/Cargo.toml | 4 +- src/uu/uptime/Cargo.toml | 4 +- src/uu/users/Cargo.toml | 4 +- src/uu/wc/Cargo.toml | 4 +- src/uu/who/Cargo.toml | 4 +- src/uu/whoami/Cargo.toml | 4 +- src/uu/yes/Cargo.toml | 4 +- src/uucore/Cargo.toml | 2 +- util/update-version.sh | 8 +- 100 files changed, 393 insertions(+), 393 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8806588ac..e5eb65a92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,7 +204,7 @@ dependencies = [ [[package]] name = "coreutils" -version = "0.0.4" +version = "0.0.5" dependencies = [ "conv", "filetime", @@ -1545,7 +1545,7 @@ dependencies = [ [[package]] name = "uu_arch" -version = "0.0.4" +version = "0.0.5" dependencies = [ "platform-info", "uucore", @@ -1554,7 +1554,7 @@ dependencies = [ [[package]] name = "uu_base32" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -1562,7 +1562,7 @@ dependencies = [ [[package]] name = "uu_base64" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -1570,7 +1570,7 @@ dependencies = [ [[package]] name = "uu_basename" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -1578,7 +1578,7 @@ dependencies = [ [[package]] name = "uu_cat" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "nix 0.20.0", @@ -1590,7 +1590,7 @@ dependencies = [ [[package]] name = "uu_chgrp" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -1599,7 +1599,7 @@ dependencies = [ [[package]] name = "uu_chmod" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -1610,7 +1610,7 @@ dependencies = [ [[package]] name = "uu_chown" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "glob 0.3.0", @@ -1621,7 +1621,7 @@ dependencies = [ [[package]] name = "uu_chroot" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -1630,7 +1630,7 @@ dependencies = [ [[package]] name = "uu_cksum" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "uu_comm" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -1650,7 +1650,7 @@ dependencies = [ [[package]] name = "uu_cp" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "filetime", @@ -1666,7 +1666,7 @@ dependencies = [ [[package]] name = "uu_csplit" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "glob 0.2.11", @@ -1678,7 +1678,7 @@ dependencies = [ [[package]] name = "uu_cut" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -1686,7 +1686,7 @@ dependencies = [ [[package]] name = "uu_date" -version = "0.0.4" +version = "0.0.5" dependencies = [ "chrono", "clap", @@ -1698,7 +1698,7 @@ dependencies = [ [[package]] name = "uu_df" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -1710,7 +1710,7 @@ dependencies = [ [[package]] name = "uu_dircolors" -version = "0.0.4" +version = "0.0.5" dependencies = [ "glob 0.3.0", "uucore", @@ -1719,7 +1719,7 @@ dependencies = [ [[package]] name = "uu_dirname" -version = "0.0.4" +version = "0.0.5" dependencies = [ "libc", "uucore", @@ -1728,7 +1728,7 @@ dependencies = [ [[package]] name = "uu_du" -version = "0.0.4" +version = "0.0.5" dependencies = [ "time", "uucore", @@ -1738,7 +1738,7 @@ dependencies = [ [[package]] name = "uu_echo" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -1747,7 +1747,7 @@ dependencies = [ [[package]] name = "uu_env" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -1758,7 +1758,7 @@ dependencies = [ [[package]] name = "uu_expand" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "unicode-width", @@ -1768,7 +1768,7 @@ dependencies = [ [[package]] name = "uu_expr" -version = "0.0.4" +version = "0.0.5" dependencies = [ "libc", "onig", @@ -1778,7 +1778,7 @@ dependencies = [ [[package]] name = "uu_factor" -version = "0.0.4" +version = "0.0.5" dependencies = [ "criterion", "num-traits", @@ -1793,7 +1793,7 @@ dependencies = [ [[package]] name = "uu_false" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -1801,7 +1801,7 @@ dependencies = [ [[package]] name = "uu_fmt" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -1812,7 +1812,7 @@ dependencies = [ [[package]] name = "uu_fold" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -1820,7 +1820,7 @@ dependencies = [ [[package]] name = "uu_groups" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -1829,7 +1829,7 @@ dependencies = [ [[package]] name = "uu_hashsum" -version = "0.0.4" +version = "0.0.5" dependencies = [ "blake2-rfc", "clap", @@ -1848,7 +1848,7 @@ dependencies = [ [[package]] name = "uu_head" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -1857,7 +1857,7 @@ dependencies = [ [[package]] name = "uu_hostid" -version = "0.0.4" +version = "0.0.5" dependencies = [ "libc", "uucore", @@ -1866,7 +1866,7 @@ dependencies = [ [[package]] name = "uu_hostname" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "hostname", @@ -1878,7 +1878,7 @@ dependencies = [ [[package]] name = "uu_id" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -1887,7 +1887,7 @@ dependencies = [ [[package]] name = "uu_install" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "file_diff", @@ -1900,7 +1900,7 @@ dependencies = [ [[package]] name = "uu_join" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -1909,7 +1909,7 @@ dependencies = [ [[package]] name = "uu_kill" -version = "0.0.4" +version = "0.0.5" dependencies = [ "libc", "uucore", @@ -1918,7 +1918,7 @@ dependencies = [ [[package]] name = "uu_link" -version = "0.0.4" +version = "0.0.5" dependencies = [ "libc", "uucore", @@ -1927,7 +1927,7 @@ dependencies = [ [[package]] name = "uu_ln" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -1937,7 +1937,7 @@ dependencies = [ [[package]] name = "uu_logname" -version = "0.0.4" +version = "0.0.5" dependencies = [ "libc", "uucore", @@ -1946,7 +1946,7 @@ dependencies = [ [[package]] name = "uu_ls" -version = "0.0.4" +version = "0.0.5" dependencies = [ "atty", "clap", @@ -1962,7 +1962,7 @@ dependencies = [ [[package]] name = "uu_mkdir" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -1972,7 +1972,7 @@ dependencies = [ [[package]] name = "uu_mkfifo" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -1982,7 +1982,7 @@ dependencies = [ [[package]] name = "uu_mknod" -version = "0.0.4" +version = "0.0.5" dependencies = [ "getopts", "libc", @@ -1992,7 +1992,7 @@ dependencies = [ [[package]] name = "uu_mktemp" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "rand 0.5.6", @@ -2003,7 +2003,7 @@ dependencies = [ [[package]] name = "uu_more" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "nix 0.13.1", @@ -2015,7 +2015,7 @@ dependencies = [ [[package]] name = "uu_mv" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "fs_extra", @@ -2025,7 +2025,7 @@ dependencies = [ [[package]] name = "uu_nice" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2036,7 +2036,7 @@ dependencies = [ [[package]] name = "uu_nl" -version = "0.0.4" +version = "0.0.5" dependencies = [ "aho-corasick", "clap", @@ -2050,7 +2050,7 @@ dependencies = [ [[package]] name = "uu_nohup" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2060,7 +2060,7 @@ dependencies = [ [[package]] name = "uu_nproc" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2071,7 +2071,7 @@ dependencies = [ [[package]] name = "uu_numfmt" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2080,7 +2080,7 @@ dependencies = [ [[package]] name = "uu_od" -version = "0.0.4" +version = "0.0.5" dependencies = [ "byteorder", "clap", @@ -2092,7 +2092,7 @@ dependencies = [ [[package]] name = "uu_paste" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2101,7 +2101,7 @@ dependencies = [ [[package]] name = "uu_pathchk" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2111,7 +2111,7 @@ dependencies = [ [[package]] name = "uu_pinky" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -2119,7 +2119,7 @@ dependencies = [ [[package]] name = "uu_printenv" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2128,7 +2128,7 @@ dependencies = [ [[package]] name = "uu_printf" -version = "0.0.4" +version = "0.0.5" dependencies = [ "itertools 0.8.2", "uucore", @@ -2137,7 +2137,7 @@ dependencies = [ [[package]] name = "uu_ptx" -version = "0.0.4" +version = "0.0.5" dependencies = [ "aho-corasick", "clap", @@ -2151,7 +2151,7 @@ dependencies = [ [[package]] name = "uu_pwd" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2160,7 +2160,7 @@ dependencies = [ [[package]] name = "uu_readlink" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2170,7 +2170,7 @@ dependencies = [ [[package]] name = "uu_realpath" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2179,7 +2179,7 @@ dependencies = [ [[package]] name = "uu_relpath" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2188,7 +2188,7 @@ dependencies = [ [[package]] name = "uu_rm" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "remove_dir_all", @@ -2199,7 +2199,7 @@ dependencies = [ [[package]] name = "uu_rmdir" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2208,7 +2208,7 @@ dependencies = [ [[package]] name = "uu_seq" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2217,7 +2217,7 @@ dependencies = [ [[package]] name = "uu_shred" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "filetime", @@ -2230,7 +2230,7 @@ dependencies = [ [[package]] name = "uu_shuf" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "rand 0.5.6", @@ -2240,7 +2240,7 @@ dependencies = [ [[package]] name = "uu_sleep" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2249,7 +2249,7 @@ dependencies = [ [[package]] name = "uu_sort" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "itertools 0.8.2", @@ -2262,7 +2262,7 @@ dependencies = [ [[package]] name = "uu_split" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2271,7 +2271,7 @@ dependencies = [ [[package]] name = "uu_stat" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "time", @@ -2281,7 +2281,7 @@ dependencies = [ [[package]] name = "uu_stdbuf" -version = "0.0.4" +version = "0.0.5" dependencies = [ "getopts", "tempfile", @@ -2292,7 +2292,7 @@ dependencies = [ [[package]] name = "uu_stdbuf_libstdbuf" -version = "0.0.4" +version = "0.0.5" dependencies = [ "cpp", "cpp_build", @@ -2303,7 +2303,7 @@ dependencies = [ [[package]] name = "uu_sum" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2312,7 +2312,7 @@ dependencies = [ [[package]] name = "uu_sync" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2323,7 +2323,7 @@ dependencies = [ [[package]] name = "uu_tac" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2332,7 +2332,7 @@ dependencies = [ [[package]] name = "uu_tail" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2344,7 +2344,7 @@ dependencies = [ [[package]] name = "uu_tee" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2355,7 +2355,7 @@ dependencies = [ [[package]] name = "uu_test" -version = "0.0.4" +version = "0.0.5" dependencies = [ "libc", "redox_syscall 0.1.57", @@ -2365,7 +2365,7 @@ dependencies = [ [[package]] name = "uu_timeout" -version = "0.0.4" +version = "0.0.5" dependencies = [ "getopts", "libc", @@ -2375,7 +2375,7 @@ dependencies = [ [[package]] name = "uu_touch" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "filetime", @@ -2386,7 +2386,7 @@ dependencies = [ [[package]] name = "uu_tr" -version = "0.0.4" +version = "0.0.5" dependencies = [ "bit-set", "clap", @@ -2397,7 +2397,7 @@ dependencies = [ [[package]] name = "uu_true" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -2405,7 +2405,7 @@ dependencies = [ [[package]] name = "uu_truncate" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2414,7 +2414,7 @@ dependencies = [ [[package]] name = "uu_tsort" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2423,7 +2423,7 @@ dependencies = [ [[package]] name = "uu_tty" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2433,7 +2433,7 @@ dependencies = [ [[package]] name = "uu_uname" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "platform-info", @@ -2443,7 +2443,7 @@ dependencies = [ [[package]] name = "uu_unexpand" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "unicode-width", @@ -2453,7 +2453,7 @@ dependencies = [ [[package]] name = "uu_uniq" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2462,7 +2462,7 @@ dependencies = [ [[package]] name = "uu_unlink" -version = "0.0.4" +version = "0.0.5" dependencies = [ "getopts", "libc", @@ -2472,7 +2472,7 @@ dependencies = [ [[package]] name = "uu_uptime" -version = "0.0.4" +version = "0.0.5" dependencies = [ "chrono", "clap", @@ -2482,7 +2482,7 @@ dependencies = [ [[package]] name = "uu_users" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2491,7 +2491,7 @@ dependencies = [ [[package]] name = "uu_wc" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "libc", @@ -2503,7 +2503,7 @@ dependencies = [ [[package]] name = "uu_who" -version = "0.0.4" +version = "0.0.5" dependencies = [ "uucore", "uucore_procs", @@ -2511,7 +2511,7 @@ dependencies = [ [[package]] name = "uu_whoami" -version = "0.0.4" +version = "0.0.5" dependencies = [ "advapi32-sys", "clap", @@ -2522,7 +2522,7 @@ dependencies = [ [[package]] name = "uu_yes" -version = "0.0.4" +version = "0.0.5" dependencies = [ "clap", "uucore", @@ -2531,7 +2531,7 @@ dependencies = [ [[package]] name = "uucore" -version = "0.0.7" +version = "0.0.8" dependencies = [ "data-encoding", "dunce", diff --git a/Cargo.toml b/Cargo.toml index 1562fcfb0..398791ca9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "coreutils" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "coreutils ~ GNU coreutils (updated); implemented as universal (cross-platform) utils, written in Rust" @@ -226,104 +226,104 @@ test = [ "uu_test" ] [dependencies] lazy_static = { version="1.3" } textwrap = { version="=0.11.0", features=["term_size"] } # !maint: [2020-05-10; rivy] unstable crate using undocumented features; pinned currently, will review -uucore = { version=">=0.0.7", package="uucore", path="src/uucore" } +uucore = { version=">=0.0.8", package="uucore", path="src/uucore" } # * uutils -uu_test = { optional=true, version="0.0.4", package="uu_test", path="src/uu/test" } +uu_test = { optional=true, version="0.0.5", package="uu_test", path="src/uu/test" } # -arch = { optional=true, version="0.0.4", package="uu_arch", path="src/uu/arch" } -base32 = { optional=true, version="0.0.4", package="uu_base32", path="src/uu/base32" } -base64 = { optional=true, version="0.0.4", package="uu_base64", path="src/uu/base64" } -basename = { optional=true, version="0.0.4", package="uu_basename", path="src/uu/basename" } -cat = { optional=true, version="0.0.4", package="uu_cat", path="src/uu/cat" } -chgrp = { optional=true, version="0.0.4", package="uu_chgrp", path="src/uu/chgrp" } -chmod = { optional=true, version="0.0.4", package="uu_chmod", path="src/uu/chmod" } -chown = { optional=true, version="0.0.4", package="uu_chown", path="src/uu/chown" } -chroot = { optional=true, version="0.0.4", package="uu_chroot", path="src/uu/chroot" } -cksum = { optional=true, version="0.0.4", package="uu_cksum", path="src/uu/cksum" } -comm = { optional=true, version="0.0.4", package="uu_comm", path="src/uu/comm" } -cp = { optional=true, version="0.0.4", package="uu_cp", path="src/uu/cp" } -csplit = { optional=true, version="0.0.4", package="uu_csplit", path="src/uu/csplit" } -cut = { optional=true, version="0.0.4", package="uu_cut", path="src/uu/cut" } -date = { optional=true, version="0.0.4", package="uu_date", path="src/uu/date" } -df = { optional=true, version="0.0.4", package="uu_df", path="src/uu/df" } -dircolors= { optional=true, version="0.0.4", package="uu_dircolors", path="src/uu/dircolors" } -dirname = { optional=true, version="0.0.4", package="uu_dirname", path="src/uu/dirname" } -du = { optional=true, version="0.0.4", package="uu_du", path="src/uu/du" } -echo = { optional=true, version="0.0.4", package="uu_echo", path="src/uu/echo" } -env = { optional=true, version="0.0.4", package="uu_env", path="src/uu/env" } -expand = { optional=true, version="0.0.4", package="uu_expand", path="src/uu/expand" } -expr = { optional=true, version="0.0.4", package="uu_expr", path="src/uu/expr" } -factor = { optional=true, version="0.0.4", package="uu_factor", path="src/uu/factor" } -false = { optional=true, version="0.0.4", package="uu_false", path="src/uu/false" } -fmt = { optional=true, version="0.0.4", package="uu_fmt", path="src/uu/fmt" } -fold = { optional=true, version="0.0.4", package="uu_fold", path="src/uu/fold" } -groups = { optional=true, version="0.0.4", package="uu_groups", path="src/uu/groups" } -hashsum = { optional=true, version="0.0.4", package="uu_hashsum", path="src/uu/hashsum" } -head = { optional=true, version="0.0.4", package="uu_head", path="src/uu/head" } -hostid = { optional=true, version="0.0.4", package="uu_hostid", path="src/uu/hostid" } -hostname = { optional=true, version="0.0.4", package="uu_hostname", path="src/uu/hostname" } -id = { optional=true, version="0.0.4", package="uu_id", path="src/uu/id" } -install = { optional=true, version="0.0.4", package="uu_install", path="src/uu/install" } -join = { optional=true, version="0.0.4", package="uu_join", path="src/uu/join" } -kill = { optional=true, version="0.0.4", package="uu_kill", path="src/uu/kill" } -link = { optional=true, version="0.0.4", package="uu_link", path="src/uu/link" } -ln = { optional=true, version="0.0.4", package="uu_ln", path="src/uu/ln" } -ls = { optional=true, version="0.0.4", package="uu_ls", path="src/uu/ls" } -logname = { optional=true, version="0.0.4", package="uu_logname", path="src/uu/logname" } -mkdir = { optional=true, version="0.0.4", package="uu_mkdir", path="src/uu/mkdir" } -mkfifo = { optional=true, version="0.0.4", package="uu_mkfifo", path="src/uu/mkfifo" } -mknod = { optional=true, version="0.0.4", package="uu_mknod", path="src/uu/mknod" } -mktemp = { optional=true, version="0.0.4", package="uu_mktemp", path="src/uu/mktemp" } -more = { optional=true, version="0.0.4", package="uu_more", path="src/uu/more" } -mv = { optional=true, version="0.0.4", package="uu_mv", path="src/uu/mv" } -nice = { optional=true, version="0.0.4", package="uu_nice", path="src/uu/nice" } -nl = { optional=true, version="0.0.4", package="uu_nl", path="src/uu/nl" } -nohup = { optional=true, version="0.0.4", package="uu_nohup", path="src/uu/nohup" } -nproc = { optional=true, version="0.0.4", package="uu_nproc", path="src/uu/nproc" } -numfmt = { optional=true, version="0.0.4", package="uu_numfmt", path="src/uu/numfmt" } -od = { optional=true, version="0.0.4", package="uu_od", path="src/uu/od" } -paste = { optional=true, version="0.0.4", package="uu_paste", path="src/uu/paste" } -pathchk = { optional=true, version="0.0.4", package="uu_pathchk", path="src/uu/pathchk" } -pinky = { optional=true, version="0.0.4", package="uu_pinky", path="src/uu/pinky" } -printenv = { optional=true, version="0.0.4", package="uu_printenv", path="src/uu/printenv" } -printf = { optional=true, version="0.0.4", package="uu_printf", path="src/uu/printf" } -ptx = { optional=true, version="0.0.4", package="uu_ptx", path="src/uu/ptx" } -pwd = { optional=true, version="0.0.4", package="uu_pwd", path="src/uu/pwd" } -readlink = { optional=true, version="0.0.4", package="uu_readlink", path="src/uu/readlink" } -realpath = { optional=true, version="0.0.4", package="uu_realpath", path="src/uu/realpath" } -relpath = { optional=true, version="0.0.4", package="uu_relpath", path="src/uu/relpath" } -rm = { optional=true, version="0.0.4", package="uu_rm", path="src/uu/rm" } -rmdir = { optional=true, version="0.0.4", package="uu_rmdir", path="src/uu/rmdir" } -seq = { optional=true, version="0.0.4", package="uu_seq", path="src/uu/seq" } -shred = { optional=true, version="0.0.4", package="uu_shred", path="src/uu/shred" } -shuf = { optional=true, version="0.0.4", package="uu_shuf", path="src/uu/shuf" } -sleep = { optional=true, version="0.0.4", package="uu_sleep", path="src/uu/sleep" } -sort = { optional=true, version="0.0.4", package="uu_sort", path="src/uu/sort" } -split = { optional=true, version="0.0.4", package="uu_split", path="src/uu/split" } -stat = { optional=true, version="0.0.4", package="uu_stat", path="src/uu/stat" } -stdbuf = { optional=true, version="0.0.4", package="uu_stdbuf", path="src/uu/stdbuf" } -sum = { optional=true, version="0.0.4", package="uu_sum", path="src/uu/sum" } -sync = { optional=true, version="0.0.4", package="uu_sync", path="src/uu/sync" } -tac = { optional=true, version="0.0.4", package="uu_tac", path="src/uu/tac" } -tail = { optional=true, version="0.0.4", package="uu_tail", path="src/uu/tail" } -tee = { optional=true, version="0.0.4", package="uu_tee", path="src/uu/tee" } -timeout = { optional=true, version="0.0.4", package="uu_timeout", path="src/uu/timeout" } -touch = { optional=true, version="0.0.4", package="uu_touch", path="src/uu/touch" } -tr = { optional=true, version="0.0.4", package="uu_tr", path="src/uu/tr" } -true = { optional=true, version="0.0.4", package="uu_true", path="src/uu/true" } -truncate = { optional=true, version="0.0.4", package="uu_truncate", path="src/uu/truncate" } -tsort = { optional=true, version="0.0.4", package="uu_tsort", path="src/uu/tsort" } -tty = { optional=true, version="0.0.4", package="uu_tty", path="src/uu/tty" } -uname = { optional=true, version="0.0.4", package="uu_uname", path="src/uu/uname" } -unexpand = { optional=true, version="0.0.4", package="uu_unexpand", path="src/uu/unexpand" } -uniq = { optional=true, version="0.0.4", package="uu_uniq", path="src/uu/uniq" } -unlink = { optional=true, version="0.0.4", package="uu_unlink", path="src/uu/unlink" } -uptime = { optional=true, version="0.0.4", package="uu_uptime", path="src/uu/uptime" } -users = { optional=true, version="0.0.4", package="uu_users", path="src/uu/users" } -wc = { optional=true, version="0.0.4", package="uu_wc", path="src/uu/wc" } -who = { optional=true, version="0.0.4", package="uu_who", path="src/uu/who" } -whoami = { optional=true, version="0.0.4", package="uu_whoami", path="src/uu/whoami" } -yes = { optional=true, version="0.0.4", package="uu_yes", path="src/uu/yes" } +arch = { optional=true, version="0.0.5", package="uu_arch", path="src/uu/arch" } +base32 = { optional=true, version="0.0.5", package="uu_base32", path="src/uu/base32" } +base64 = { optional=true, version="0.0.5", package="uu_base64", path="src/uu/base64" } +basename = { optional=true, version="0.0.5", package="uu_basename", path="src/uu/basename" } +cat = { optional=true, version="0.0.5", package="uu_cat", path="src/uu/cat" } +chgrp = { optional=true, version="0.0.5", package="uu_chgrp", path="src/uu/chgrp" } +chmod = { optional=true, version="0.0.5", package="uu_chmod", path="src/uu/chmod" } +chown = { optional=true, version="0.0.5", package="uu_chown", path="src/uu/chown" } +chroot = { optional=true, version="0.0.5", package="uu_chroot", path="src/uu/chroot" } +cksum = { optional=true, version="0.0.5", package="uu_cksum", path="src/uu/cksum" } +comm = { optional=true, version="0.0.5", package="uu_comm", path="src/uu/comm" } +cp = { optional=true, version="0.0.5", package="uu_cp", path="src/uu/cp" } +csplit = { optional=true, version="0.0.5", package="uu_csplit", path="src/uu/csplit" } +cut = { optional=true, version="0.0.5", package="uu_cut", path="src/uu/cut" } +date = { optional=true, version="0.0.5", package="uu_date", path="src/uu/date" } +df = { optional=true, version="0.0.5", package="uu_df", path="src/uu/df" } +dircolors= { optional=true, version="0.0.5", package="uu_dircolors", path="src/uu/dircolors" } +dirname = { optional=true, version="0.0.5", package="uu_dirname", path="src/uu/dirname" } +du = { optional=true, version="0.0.5", package="uu_du", path="src/uu/du" } +echo = { optional=true, version="0.0.5", package="uu_echo", path="src/uu/echo" } +env = { optional=true, version="0.0.5", package="uu_env", path="src/uu/env" } +expand = { optional=true, version="0.0.5", package="uu_expand", path="src/uu/expand" } +expr = { optional=true, version="0.0.5", package="uu_expr", path="src/uu/expr" } +factor = { optional=true, version="0.0.5", package="uu_factor", path="src/uu/factor" } +false = { optional=true, version="0.0.5", package="uu_false", path="src/uu/false" } +fmt = { optional=true, version="0.0.5", package="uu_fmt", path="src/uu/fmt" } +fold = { optional=true, version="0.0.5", package="uu_fold", path="src/uu/fold" } +groups = { optional=true, version="0.0.5", package="uu_groups", path="src/uu/groups" } +hashsum = { optional=true, version="0.0.5", package="uu_hashsum", path="src/uu/hashsum" } +head = { optional=true, version="0.0.5", package="uu_head", path="src/uu/head" } +hostid = { optional=true, version="0.0.5", package="uu_hostid", path="src/uu/hostid" } +hostname = { optional=true, version="0.0.5", package="uu_hostname", path="src/uu/hostname" } +id = { optional=true, version="0.0.5", package="uu_id", path="src/uu/id" } +install = { optional=true, version="0.0.5", package="uu_install", path="src/uu/install" } +join = { optional=true, version="0.0.5", package="uu_join", path="src/uu/join" } +kill = { optional=true, version="0.0.5", package="uu_kill", path="src/uu/kill" } +link = { optional=true, version="0.0.5", package="uu_link", path="src/uu/link" } +ln = { optional=true, version="0.0.5", package="uu_ln", path="src/uu/ln" } +ls = { optional=true, version="0.0.5", package="uu_ls", path="src/uu/ls" } +logname = { optional=true, version="0.0.5", package="uu_logname", path="src/uu/logname" } +mkdir = { optional=true, version="0.0.5", package="uu_mkdir", path="src/uu/mkdir" } +mkfifo = { optional=true, version="0.0.5", package="uu_mkfifo", path="src/uu/mkfifo" } +mknod = { optional=true, version="0.0.5", package="uu_mknod", path="src/uu/mknod" } +mktemp = { optional=true, version="0.0.5", package="uu_mktemp", path="src/uu/mktemp" } +more = { optional=true, version="0.0.5", package="uu_more", path="src/uu/more" } +mv = { optional=true, version="0.0.5", package="uu_mv", path="src/uu/mv" } +nice = { optional=true, version="0.0.5", package="uu_nice", path="src/uu/nice" } +nl = { optional=true, version="0.0.5", package="uu_nl", path="src/uu/nl" } +nohup = { optional=true, version="0.0.5", package="uu_nohup", path="src/uu/nohup" } +nproc = { optional=true, version="0.0.5", package="uu_nproc", path="src/uu/nproc" } +numfmt = { optional=true, version="0.0.5", package="uu_numfmt", path="src/uu/numfmt" } +od = { optional=true, version="0.0.5", package="uu_od", path="src/uu/od" } +paste = { optional=true, version="0.0.5", package="uu_paste", path="src/uu/paste" } +pathchk = { optional=true, version="0.0.5", package="uu_pathchk", path="src/uu/pathchk" } +pinky = { optional=true, version="0.0.5", package="uu_pinky", path="src/uu/pinky" } +printenv = { optional=true, version="0.0.5", package="uu_printenv", path="src/uu/printenv" } +printf = { optional=true, version="0.0.5", package="uu_printf", path="src/uu/printf" } +ptx = { optional=true, version="0.0.5", package="uu_ptx", path="src/uu/ptx" } +pwd = { optional=true, version="0.0.5", package="uu_pwd", path="src/uu/pwd" } +readlink = { optional=true, version="0.0.5", package="uu_readlink", path="src/uu/readlink" } +realpath = { optional=true, version="0.0.5", package="uu_realpath", path="src/uu/realpath" } +relpath = { optional=true, version="0.0.5", package="uu_relpath", path="src/uu/relpath" } +rm = { optional=true, version="0.0.5", package="uu_rm", path="src/uu/rm" } +rmdir = { optional=true, version="0.0.5", package="uu_rmdir", path="src/uu/rmdir" } +seq = { optional=true, version="0.0.5", package="uu_seq", path="src/uu/seq" } +shred = { optional=true, version="0.0.5", package="uu_shred", path="src/uu/shred" } +shuf = { optional=true, version="0.0.5", package="uu_shuf", path="src/uu/shuf" } +sleep = { optional=true, version="0.0.5", package="uu_sleep", path="src/uu/sleep" } +sort = { optional=true, version="0.0.5", package="uu_sort", path="src/uu/sort" } +split = { optional=true, version="0.0.5", package="uu_split", path="src/uu/split" } +stat = { optional=true, version="0.0.5", package="uu_stat", path="src/uu/stat" } +stdbuf = { optional=true, version="0.0.5", package="uu_stdbuf", path="src/uu/stdbuf" } +sum = { optional=true, version="0.0.5", package="uu_sum", path="src/uu/sum" } +sync = { optional=true, version="0.0.5", package="uu_sync", path="src/uu/sync" } +tac = { optional=true, version="0.0.5", package="uu_tac", path="src/uu/tac" } +tail = { optional=true, version="0.0.5", package="uu_tail", path="src/uu/tail" } +tee = { optional=true, version="0.0.5", package="uu_tee", path="src/uu/tee" } +timeout = { optional=true, version="0.0.5", package="uu_timeout", path="src/uu/timeout" } +touch = { optional=true, version="0.0.5", package="uu_touch", path="src/uu/touch" } +tr = { optional=true, version="0.0.5", package="uu_tr", path="src/uu/tr" } +true = { optional=true, version="0.0.5", package="uu_true", path="src/uu/true" } +truncate = { optional=true, version="0.0.5", package="uu_truncate", path="src/uu/truncate" } +tsort = { optional=true, version="0.0.5", package="uu_tsort", path="src/uu/tsort" } +tty = { optional=true, version="0.0.5", package="uu_tty", path="src/uu/tty" } +uname = { optional=true, version="0.0.5", package="uu_uname", path="src/uu/uname" } +unexpand = { optional=true, version="0.0.5", package="uu_unexpand", path="src/uu/unexpand" } +uniq = { optional=true, version="0.0.5", package="uu_uniq", path="src/uu/uniq" } +unlink = { optional=true, version="0.0.5", package="uu_unlink", path="src/uu/unlink" } +uptime = { optional=true, version="0.0.5", package="uu_uptime", path="src/uu/uptime" } +users = { optional=true, version="0.0.5", package="uu_users", path="src/uu/users" } +wc = { optional=true, version="0.0.5", package="uu_wc", path="src/uu/wc" } +who = { optional=true, version="0.0.5", package="uu_who", path="src/uu/who" } +whoami = { optional=true, version="0.0.5", package="uu_whoami", path="src/uu/whoami" } +yes = { optional=true, version="0.0.5", package="uu_yes", path="src/uu/yes" } # # * pinned transitive dependencies # Not needed for now. Keep as examples: @@ -343,7 +343,7 @@ sha1 = { version="0.6", features=["std"] } tempfile = "= 3.1.0" time = "0.1" unindent = "0.1" -uucore = { version=">=0.0.7", package="uucore", path="src/uucore", features=["entries"] } +uucore = { version=">=0.0.8", package="uucore", path="src/uucore", features=["entries"] } walkdir = "2.2" tempdir = "0.3" diff --git a/src/uu/arch/Cargo.toml b/src/uu/arch/Cargo.toml index 4ca0fbda7..e23067788 100644 --- a/src/uu/arch/Cargo.toml +++ b/src/uu/arch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_arch" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "arch ~ (uutils) display machine architecture" @@ -16,7 +16,7 @@ path = "src/arch.rs" [dependencies] platform-info = "0.1" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/base32/Cargo.toml b/src/uu/base32/Cargo.toml index 0abb718c8..d4415dd8c 100644 --- a/src/uu/base32/Cargo.toml +++ b/src/uu/base32/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_base32" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "base32 ~ (uutils) decode/encode input (base32-encoding)" @@ -15,7 +15,7 @@ edition = "2018" path = "src/base32.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features = ["encoding"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features = ["encoding"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/base64/Cargo.toml b/src/uu/base64/Cargo.toml index eef9b1ec3..e893caf3a 100644 --- a/src/uu/base64/Cargo.toml +++ b/src/uu/base64/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_base64" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "base64 ~ (uutils) decode/encode input (base64-encoding)" @@ -15,7 +15,7 @@ edition = "2018" path = "src/base64.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features = ["encoding"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features = ["encoding"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/basename/Cargo.toml b/src/uu/basename/Cargo.toml index 218d9eb08..681ccf1c4 100644 --- a/src/uu/basename/Cargo.toml +++ b/src/uu/basename/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_basename" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "basename ~ (uutils) display PATHNAME with leading directory components removed" @@ -15,7 +15,7 @@ edition = "2018" path = "src/basename.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index 3878aee96..25119dcfc 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cat" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "cat ~ (uutils) concatenate and display input" @@ -17,7 +17,7 @@ path = "src/cat.rs" [dependencies] clap = "2.33" thiserror = "1.0" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(unix)'.dependencies] diff --git a/src/uu/chgrp/Cargo.toml b/src/uu/chgrp/Cargo.toml index 60f9d6370..2cefca4d8 100644 --- a/src/uu/chgrp/Cargo.toml +++ b/src/uu/chgrp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chgrp" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "chgrp ~ (uutils) change the group ownership of FILE" @@ -15,7 +15,7 @@ edition = "2018" path = "src/chgrp.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } walkdir = "2.2" diff --git a/src/uu/chmod/Cargo.toml b/src/uu/chmod/Cargo.toml index d4917b525..71ded6d90 100644 --- a/src/uu/chmod/Cargo.toml +++ b/src/uu/chmod/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chmod" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "chmod ~ (uutils) change mode of FILE" @@ -17,7 +17,7 @@ path = "src/chmod.rs" [dependencies] clap = "2.33.3" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs", "mode"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs", "mode"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } walkdir = "2.2" diff --git a/src/uu/chown/Cargo.toml b/src/uu/chown/Cargo.toml index f2d21ef88..27a30da17 100644 --- a/src/uu/chown/Cargo.toml +++ b/src/uu/chown/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chown" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "chown ~ (uutils) change the ownership of FILE" @@ -17,7 +17,7 @@ path = "src/chown.rs" [dependencies] clap = "2.33" glob = "0.3.0" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } walkdir = "2.2" diff --git a/src/uu/chroot/Cargo.toml b/src/uu/chroot/Cargo.toml index e967d4137..51fb9541d 100644 --- a/src/uu/chroot/Cargo.toml +++ b/src/uu/chroot/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chroot" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "chroot ~ (uutils) run COMMAND under a new root directory" @@ -16,7 +16,7 @@ path = "src/chroot.rs" [dependencies] clap= "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/cksum/Cargo.toml b/src/uu/cksum/Cargo.toml index b7ac630f0..2f589e877 100644 --- a/src/uu/cksum/Cargo.toml +++ b/src/uu/cksum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cksum" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "cksum ~ (uutils) display CRC and size of input" @@ -17,7 +17,7 @@ path = "src/cksum.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/comm/Cargo.toml b/src/uu/comm/Cargo.toml index a0dc4e06f..9babe82ea 100644 --- a/src/uu/comm/Cargo.toml +++ b/src/uu/comm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_comm" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "comm ~ (uutils) compare sorted inputs" @@ -17,7 +17,7 @@ path = "src/comm.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/cp/Cargo.toml b/src/uu/cp/Cargo.toml index a0253433f..53d27137f 100644 --- a/src/uu/cp/Cargo.toml +++ b/src/uu/cp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cp" -version = "0.0.4" +version = "0.0.5" authors = [ "Jordy Dickinson ", "Joshua S. Miller ", @@ -23,7 +23,7 @@ clap = "2.33" filetime = "0.2" libc = "0.2.85" quick-error = "1.2.3" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } walkdir = "2.2" diff --git a/src/uu/csplit/Cargo.toml b/src/uu/csplit/Cargo.toml index 7cec4564b..a5eac1a02 100644 --- a/src/uu/csplit/Cargo.toml +++ b/src/uu/csplit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_csplit" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "csplit ~ (uutils) Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output" @@ -19,7 +19,7 @@ clap = "2.33" thiserror = "1.0" regex = "1.0.0" glob = "0.2.11" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/cut/Cargo.toml b/src/uu/cut/Cargo.toml index 71f7c3f6a..10a282ecf 100644 --- a/src/uu/cut/Cargo.toml +++ b/src/uu/cut/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cut" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "cut ~ (uutils) display byte/field columns of input lines" @@ -15,7 +15,7 @@ edition = "2018" path = "src/cut.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index c62cfe2b3..cacf29ff0 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_date" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "date ~ (uutils) display or set the current time" @@ -17,7 +17,7 @@ path = "src/date.rs" [dependencies] chrono = "0.4.4" clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(unix)'.dependencies] diff --git a/src/uu/df/Cargo.toml b/src/uu/df/Cargo.toml index 24fce763b..049422ce5 100644 --- a/src/uu/df/Cargo.toml +++ b/src/uu/df/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_df" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "df ~ (uutils) display file system information" @@ -18,7 +18,7 @@ path = "src/df.rs" clap = "2.33" libc = "0.2" number_prefix = "0.4" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(target_os = "windows")'.dependencies] diff --git a/src/uu/dircolors/Cargo.toml b/src/uu/dircolors/Cargo.toml index 667fc3b70..9ed55d20d 100644 --- a/src/uu/dircolors/Cargo.toml +++ b/src/uu/dircolors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dircolors" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "dircolors ~ (uutils) display commands to set LS_COLORS" @@ -16,7 +16,7 @@ path = "src/dircolors.rs" [dependencies] glob = "0.3.0" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/dirname/Cargo.toml b/src/uu/dirname/Cargo.toml index 9c565a3e6..575aefd51 100644 --- a/src/uu/dirname/Cargo.toml +++ b/src/uu/dirname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dirname" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "dirname ~ (uutils) display parent directory of PATHNAME" @@ -16,7 +16,7 @@ path = "src/dirname.rs" [dependencies] libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/du/Cargo.toml b/src/uu/du/Cargo.toml index bb46c299c..01045f887 100644 --- a/src/uu/du/Cargo.toml +++ b/src/uu/du/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_du" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "du ~ (uutils) display disk usage" @@ -16,7 +16,7 @@ path = "src/du.rs" [dependencies] time = "0.1.40" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } winapi = { version="0.3", features=[] } diff --git a/src/uu/echo/Cargo.toml b/src/uu/echo/Cargo.toml index 7b831fcb8..2ac09cd39 100644 --- a/src/uu/echo/Cargo.toml +++ b/src/uu/echo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_echo" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "echo ~ (uutils) display TEXT" @@ -16,7 +16,7 @@ path = "src/echo.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/env/Cargo.toml b/src/uu/env/Cargo.toml index 864ecd1b2..fc5317184 100644 --- a/src/uu/env/Cargo.toml +++ b/src/uu/env/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_env" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "env ~ (uutils) set each NAME to VALUE in the environment and run COMMAND" @@ -18,7 +18,7 @@ path = "src/env.rs" clap = "2.33" libc = "0.2.42" rust-ini = "0.13.0" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/expand/Cargo.toml b/src/uu/expand/Cargo.toml index b5c0343e7..09575254a 100644 --- a/src/uu/expand/Cargo.toml +++ b/src/uu/expand/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_expand" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "expand ~ (uutils) convert input tabs to spaces" @@ -17,7 +17,7 @@ path = "src/expand.rs" [dependencies] clap = "2.33" unicode-width = "0.1.5" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/expr/Cargo.toml b/src/uu/expr/Cargo.toml index 1246ff873..7e38103aa 100644 --- a/src/uu/expr/Cargo.toml +++ b/src/uu/expr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_expr" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "expr ~ (uutils) display the value of EXPRESSION" @@ -17,7 +17,7 @@ path = "src/expr.rs" [dependencies] libc = "0.2.42" onig = "~4.3.2" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/factor/Cargo.toml b/src/uu/factor/Cargo.toml index d1160c493..1d415a951 100644 --- a/src/uu/factor/Cargo.toml +++ b/src/uu/factor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_factor" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "factor ~ (uutils) display the prime factors of each NUMBER" @@ -19,7 +19,7 @@ num-traits = "0.2.13" # used in src/numerics.rs, which is included by build.rs num-traits = "0.2.13" # Needs at least version 0.2.13 for "OverflowingAdd" rand = { version="0.7", features=["small_rng"] } smallvec = { version="0.6.14, < 1.0" } -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [dev-dependencies] diff --git a/src/uu/false/Cargo.toml b/src/uu/false/Cargo.toml index 413cbc990..5651888d7 100644 --- a/src/uu/false/Cargo.toml +++ b/src/uu/false/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_false" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "false ~ (uutils) do nothing and fail" @@ -15,7 +15,7 @@ edition = "2018" path = "src/false.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/fmt/Cargo.toml b/src/uu/fmt/Cargo.toml index e150b2962..688967a5a 100644 --- a/src/uu/fmt/Cargo.toml +++ b/src/uu/fmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_fmt" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "fmt ~ (uutils) reformat each paragraph of input" @@ -18,7 +18,7 @@ path = "src/fmt.rs" clap = "2.33" libc = "0.2.42" unicode-width = "0.1.5" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/fold/Cargo.toml b/src/uu/fold/Cargo.toml index 23dadc8eb..de1aa2dd5 100644 --- a/src/uu/fold/Cargo.toml +++ b/src/uu/fold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_fold" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "fold ~ (uutils) wrap each line of input" @@ -15,7 +15,7 @@ edition = "2018" path = "src/fold.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/groups/Cargo.toml b/src/uu/groups/Cargo.toml index 455e2d224..d005599de 100644 --- a/src/uu/groups/Cargo.toml +++ b/src/uu/groups/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_groups" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "groups ~ (uutils) display group memberships for USERNAME" @@ -15,7 +15,7 @@ edition = "2018" path = "src/groups.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } clap = "2.33" diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml index c9bb4da9f..b08b853ef 100644 --- a/src/uu/hashsum/Cargo.toml +++ b/src/uu/hashsum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hashsum" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "hashsum ~ (uutils) display or check input digests" @@ -26,7 +26,7 @@ sha1 = "0.6.0" sha2 = "0.6.0" sha3 = "0.6.0" blake2-rfc = "0.2.18" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/head/Cargo.toml b/src/uu/head/Cargo.toml index 1cd075113..2f5d97d62 100644 --- a/src/uu/head/Cargo.toml +++ b/src/uu/head/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_head" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "head ~ (uutils) display the first lines of input" @@ -16,7 +16,7 @@ path = "src/head.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/hostid/Cargo.toml b/src/uu/hostid/Cargo.toml index b3870652e..e872aff06 100644 --- a/src/uu/hostid/Cargo.toml +++ b/src/uu/hostid/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hostid" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "hostid ~ (uutils) display the numeric identifier of the current host" @@ -16,7 +16,7 @@ path = "src/hostid.rs" [dependencies] libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/hostname/Cargo.toml b/src/uu/hostname/Cargo.toml index 75b9b5f9a..bc4b10951 100644 --- a/src/uu/hostname/Cargo.toml +++ b/src/uu/hostname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hostname" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "hostname ~ (uutils) display or set the host name of the current host" @@ -18,7 +18,7 @@ path = "src/hostname.rs" clap = "2.33" libc = "0.2.42" hostname = { version = "0.3", features = ["set"] } -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["wide"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["wide"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } winapi = { version="0.3", features=["sysinfoapi", "winsock2"] } diff --git a/src/uu/id/Cargo.toml b/src/uu/id/Cargo.toml index 46e5cb578..6edb1d606 100644 --- a/src/uu/id/Cargo.toml +++ b/src/uu/id/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_id" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "id ~ (uutils) display user and group information for USER" @@ -16,7 +16,7 @@ path = "src/id.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "process"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "process"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index 5aec0b07c..16f78bb7b 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_install" -version = "0.0.4" +version = "0.0.5" authors = [ "Ben Eills ", "uutils developers", @@ -22,7 +22,7 @@ clap = "2.33" filetime = "0.2" file_diff = "1.0.0" libc = ">= 0.2" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["mode", "perms", "entries"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["mode", "perms", "entries"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [dev-dependencies] diff --git a/src/uu/join/Cargo.toml b/src/uu/join/Cargo.toml index d02703a62..5b18603ab 100644 --- a/src/uu/join/Cargo.toml +++ b/src/uu/join/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_join" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "join ~ (uutils) merge lines from inputs with matching join fields" @@ -16,7 +16,7 @@ path = "src/join.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/kill/Cargo.toml b/src/uu/kill/Cargo.toml index dd69cd35d..16a34de69 100644 --- a/src/uu/kill/Cargo.toml +++ b/src/uu/kill/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_kill" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "kill ~ (uutils) send a signal to a process" @@ -16,7 +16,7 @@ path = "src/kill.rs" [dependencies] libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["signals"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["signals"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/link/Cargo.toml b/src/uu/link/Cargo.toml index aaa183981..9c15d8682 100644 --- a/src/uu/link/Cargo.toml +++ b/src/uu/link/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_link" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "link ~ (uutils) create a hard (file system) link to FILE" @@ -16,7 +16,7 @@ path = "src/link.rs" [dependencies] libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/ln/Cargo.toml b/src/uu/ln/Cargo.toml index 2b97f025a..2d7f39005 100644 --- a/src/uu/ln/Cargo.toml +++ b/src/uu/ln/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ln" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "ln ~ (uutils) create a (file system) link to TARGET" @@ -17,7 +17,7 @@ path = "src/ln.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/logname/Cargo.toml b/src/uu/logname/Cargo.toml index d58576c77..896fd5eb7 100644 --- a/src/uu/logname/Cargo.toml +++ b/src/uu/logname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_logname" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "logname ~ (uutils) display the login name of the current user" @@ -16,7 +16,7 @@ path = "src/logname.rs" [dependencies] libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index 59901f807..b1d44e485 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ls" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "ls ~ (uutils) display directory contents" @@ -22,7 +22,7 @@ term_grid = "0.1.5" termsize = "0.1.6" time = "0.1.40" unicode-width = "0.1.5" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(unix)'.dependencies] diff --git a/src/uu/mkdir/Cargo.toml b/src/uu/mkdir/Cargo.toml index 9cedb5c03..44a7eb18b 100644 --- a/src/uu/mkdir/Cargo.toml +++ b/src/uu/mkdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mkdir" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "mkdir ~ (uutils) create DIRECTORY" @@ -17,7 +17,7 @@ path = "src/mkdir.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs", "mode"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs", "mode"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/mkfifo/Cargo.toml b/src/uu/mkfifo/Cargo.toml index aa347a86e..8ff6694d6 100644 --- a/src/uu/mkfifo/Cargo.toml +++ b/src/uu/mkfifo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mkfifo" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "mkfifo ~ (uutils) create FIFOs (named pipes)" @@ -17,7 +17,7 @@ path = "src/mkfifo.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/mknod/Cargo.toml b/src/uu/mknod/Cargo.toml index 426534e75..9badb5f13 100644 --- a/src/uu/mknod/Cargo.toml +++ b/src/uu/mknod/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mknod" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "mknod ~ (uutils) create special file NAME of TYPE" @@ -18,7 +18,7 @@ path = "src/mknod.rs" [dependencies] getopts = "0.2.18" libc = "^0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["mode"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["mode"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/mktemp/Cargo.toml b/src/uu/mktemp/Cargo.toml index c48306a40..13685a586 100644 --- a/src/uu/mktemp/Cargo.toml +++ b/src/uu/mktemp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mktemp" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "mktemp ~ (uutils) create and display a temporary file or directory from TEMPLATE" @@ -18,7 +18,7 @@ path = "src/mktemp.rs" clap = "2.33" rand = "0.5" tempfile = "3.1" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/more/Cargo.toml b/src/uu/more/Cargo.toml index 243462232..c910d08b0 100644 --- a/src/uu/more/Cargo.toml +++ b/src/uu/more/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_more" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "more ~ (uutils) input perusal filter" diff --git a/src/uu/mv/Cargo.toml b/src/uu/mv/Cargo.toml index 1a4f90801..f84a68c3c 100644 --- a/src/uu/mv/Cargo.toml +++ b/src/uu/mv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mv" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "mv ~ (uutils) move (rename) SOURCE to DESTINATION" @@ -17,7 +17,7 @@ path = "src/mv.rs" [dependencies] clap = "2.33" fs_extra = "1.1.0" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/nice/Cargo.toml b/src/uu/nice/Cargo.toml index c851daa5a..2106b2d24 100644 --- a/src/uu/nice/Cargo.toml +++ b/src/uu/nice/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nice" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "nice ~ (uutils) run PROGRAM with modified scheduling priority" @@ -18,7 +18,7 @@ path = "src/nice.rs" clap = "2.33" libc = "0.2.42" nix = { version="<=0.13" } -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/nl/Cargo.toml b/src/uu/nl/Cargo.toml index 41f7c60ab..f64182475 100644 --- a/src/uu/nl/Cargo.toml +++ b/src/uu/nl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nl" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "nl ~ (uutils) display input with added line numbers" @@ -21,7 +21,7 @@ libc = "0.2.42" memchr = "2.2.0" regex = "1.0.1" regex-syntax = "0.6.7" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/nohup/Cargo.toml b/src/uu/nohup/Cargo.toml index e9b6f8bd4..604e1e9da 100644 --- a/src/uu/nohup/Cargo.toml +++ b/src/uu/nohup/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nohup" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "nohup ~ (uutils) run COMMAND, ignoring hangup signals" @@ -17,7 +17,7 @@ path = "src/nohup.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/nproc/Cargo.toml b/src/uu/nproc/Cargo.toml index 98f9a4afa..2541c5a3e 100644 --- a/src/uu/nproc/Cargo.toml +++ b/src/uu/nproc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nproc" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "nproc ~ (uutils) display the number of processing units available" @@ -18,7 +18,7 @@ path = "src/nproc.rs" libc = "0.2.42" num_cpus = "1.10" clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/numfmt/Cargo.toml b/src/uu/numfmt/Cargo.toml index b8e54656c..bde97cacb 100644 --- a/src/uu/numfmt/Cargo.toml +++ b/src/uu/numfmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_numfmt" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "numfmt ~ (uutils) reformat NUMBER" @@ -16,7 +16,7 @@ path = "src/numfmt.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/od/Cargo.toml b/src/uu/od/Cargo.toml index e4db9faf0..a939c6ee4 100644 --- a/src/uu/od/Cargo.toml +++ b/src/uu/od/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_od" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "od ~ (uutils) display formatted representation of input" @@ -19,7 +19,7 @@ byteorder = "1.3.2" clap = "2.33" half = "1.6" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/paste/Cargo.toml b/src/uu/paste/Cargo.toml index 3787ed270..2ac2074ed 100644 --- a/src/uu/paste/Cargo.toml +++ b/src/uu/paste/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_paste" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "paste ~ (uutils) merge lines from inputs" @@ -16,7 +16,7 @@ path = "src/paste.rs" [dependencies] clap = "2.33.3" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/pathchk/Cargo.toml b/src/uu/pathchk/Cargo.toml index c1d0d0dfa..63d00daac 100644 --- a/src/uu/pathchk/Cargo.toml +++ b/src/uu/pathchk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pathchk" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "pathchk ~ (uutils) diagnose invalid or non-portable PATHNAME" @@ -17,7 +17,7 @@ path = "src/pathchk.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/pinky/Cargo.toml b/src/uu/pinky/Cargo.toml index 1618eab57..96fb32e74 100644 --- a/src/uu/pinky/Cargo.toml +++ b/src/uu/pinky/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pinky" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "pinky ~ (uutils) display user information" @@ -15,7 +15,7 @@ edition = "2018" path = "src/pinky.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["utmpx", "entries"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["utmpx", "entries"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/printenv/Cargo.toml b/src/uu/printenv/Cargo.toml index 5266c1e03..f81240d77 100644 --- a/src/uu/printenv/Cargo.toml +++ b/src/uu/printenv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_printenv" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "printenv ~ (uutils) display value of environment VAR" @@ -16,7 +16,7 @@ path = "src/printenv.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/printf/Cargo.toml b/src/uu/printf/Cargo.toml index c6737d178..7f54decb5 100644 --- a/src/uu/printf/Cargo.toml +++ b/src/uu/printf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_printf" -version = "0.0.4" +version = "0.0.5" authors = [ "Nathan Ross", "uutils developers", @@ -19,7 +19,7 @@ path = "src/printf.rs" [dependencies] itertools = "0.8.0" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/ptx/Cargo.toml b/src/uu/ptx/Cargo.toml index 790b06305..889b4fafa 100644 --- a/src/uu/ptx/Cargo.toml +++ b/src/uu/ptx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ptx" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "ptx ~ (uutils) display a permuted index of input" @@ -21,7 +21,7 @@ libc = "0.2.42" memchr = "2.2.0" regex = "1.0.1" regex-syntax = "0.6.7" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/pwd/Cargo.toml b/src/uu/pwd/Cargo.toml index e074dc618..43ddeac2e 100644 --- a/src/uu/pwd/Cargo.toml +++ b/src/uu/pwd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pwd" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "pwd ~ (uutils) display current working directory" @@ -16,7 +16,7 @@ path = "src/pwd.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/readlink/Cargo.toml b/src/uu/readlink/Cargo.toml index 8e31f66f1..5d69125ce 100644 --- a/src/uu/readlink/Cargo.toml +++ b/src/uu/readlink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_readlink" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "readlink ~ (uutils) display resolved path of PATHNAME" @@ -17,7 +17,7 @@ path = "src/readlink.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/realpath/Cargo.toml b/src/uu/realpath/Cargo.toml index 6f03086ba..bd25d9980 100644 --- a/src/uu/realpath/Cargo.toml +++ b/src/uu/realpath/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_realpath" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "realpath ~ (uutils) display resolved absolute path of PATHNAME" @@ -16,7 +16,7 @@ path = "src/realpath.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/relpath/Cargo.toml b/src/uu/relpath/Cargo.toml index c923b42ac..34d3dd067 100644 --- a/src/uu/relpath/Cargo.toml +++ b/src/uu/relpath/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_relpath" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "relpath ~ (uutils) display relative path of PATHNAME_TO from PATHNAME_FROM" @@ -16,7 +16,7 @@ path = "src/relpath.rs" [dependencies] clap = "2.33.3" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index b916412d8..bd3415faf 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_rm" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "rm ~ (uutils) remove PATHNAME" @@ -18,7 +18,7 @@ path = "src/rm.rs" clap = "2.33" walkdir = "2.2" remove_dir_all = "0.5.1" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/rmdir/Cargo.toml b/src/uu/rmdir/Cargo.toml index 9d6bb03cc..cfd8dd6b0 100644 --- a/src/uu/rmdir/Cargo.toml +++ b/src/uu/rmdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_rmdir" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "rmdir ~ (uutils) remove empty DIRECTORY" @@ -16,7 +16,7 @@ path = "src/rmdir.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/seq/Cargo.toml b/src/uu/seq/Cargo.toml index d7ee72b68..2e98a0bb8 100644 --- a/src/uu/seq/Cargo.toml +++ b/src/uu/seq/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_seq" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "seq ~ (uutils) display a sequence of numbers" @@ -16,7 +16,7 @@ path = "src/seq.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/shred/Cargo.toml b/src/uu/shred/Cargo.toml index 6ff6e23ec..6157f3780 100644 --- a/src/uu/shred/Cargo.toml +++ b/src/uu/shred/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_shred" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "shred ~ (uutils) hide former FILE contents with repeated overwrites" @@ -20,7 +20,7 @@ filetime = "0.2.1" libc = "0.2.42" rand = "0.5" time = "0.1.40" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/shuf/Cargo.toml b/src/uu/shuf/Cargo.toml index 5e7c6c71a..7f911c156 100644 --- a/src/uu/shuf/Cargo.toml +++ b/src/uu/shuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_shuf" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "shuf ~ (uutils) display random permutations of input lines" @@ -17,7 +17,7 @@ path = "src/shuf.rs" [dependencies] clap = "2.33" rand = "0.5" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/sleep/Cargo.toml b/src/uu/sleep/Cargo.toml index 0ac5d6519..8ff8505e1 100644 --- a/src/uu/sleep/Cargo.toml +++ b/src/uu/sleep/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sleep" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "sleep ~ (uutils) pause for DURATION" @@ -16,7 +16,7 @@ path = "src/sleep.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["parse_time"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["parse_time"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index e50caf53b..e805d4fa2 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sort" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "sort ~ (uutils) sort input lines" @@ -20,7 +20,7 @@ clap = "2.33" twox-hash = "1.6.0" itertools = "0.8.0" semver = "0.9.0" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/split/Cargo.toml b/src/uu/split/Cargo.toml index 7c3f1a56e..6032c6351 100644 --- a/src/uu/split/Cargo.toml +++ b/src/uu/split/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_split" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "split ~ (uutils) split input into output files" @@ -16,7 +16,7 @@ path = "src/split.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/stat/Cargo.toml b/src/uu/stat/Cargo.toml index 52ea88110..bf19f95b7 100644 --- a/src/uu/stat/Cargo.toml +++ b/src/uu/stat/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stat" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "stat ~ (uutils) display FILE status" @@ -17,7 +17,7 @@ path = "src/stat.rs" [dependencies] clap = "2.33" time = "0.1.40" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "libc"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "libc"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/stdbuf/Cargo.toml b/src/uu/stdbuf/Cargo.toml index 7a80e99ae..3fde13f72 100644 --- a/src/uu/stdbuf/Cargo.toml +++ b/src/uu/stdbuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stdbuf" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "stdbuf ~ (uutils) run COMMAND with modified standard stream buffering" @@ -17,11 +17,11 @@ path = "src/stdbuf.rs" [dependencies] getopts = "0.2.18" tempfile = "3.1" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [build-dependencies] -libstdbuf = { version="0.0.4", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } +libstdbuf = { version="0.0.5", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } [[bin]] name = "stdbuf" diff --git a/src/uu/stdbuf/src/libstdbuf/Cargo.toml b/src/uu/stdbuf/src/libstdbuf/Cargo.toml index ac9c7230f..ba6e5ff42 100644 --- a/src/uu/stdbuf/src/libstdbuf/Cargo.toml +++ b/src/uu/stdbuf/src/libstdbuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stdbuf_libstdbuf" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "stdbuf/libstdbuf ~ (uutils); dynamic library required for stdbuf" @@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"] # XXX: note: the rlib is just to prevent Cargo f [dependencies] cpp = "0.5" libc = "0.2" -uucore = { version=">=0.0.7", package="uucore", path="../../../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../../../uucore_procs" } [build-dependencies] diff --git a/src/uu/sum/Cargo.toml b/src/uu/sum/Cargo.toml index 1e8590616..b5a6d5d91 100644 --- a/src/uu/sum/Cargo.toml +++ b/src/uu/sum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sum" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "sum ~ (uutils) display checksum and block counts for input" @@ -16,7 +16,7 @@ path = "src/sum.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/sync/Cargo.toml b/src/uu/sync/Cargo.toml index 4cbf69a41..39c49736a 100644 --- a/src/uu/sync/Cargo.toml +++ b/src/uu/sync/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sync" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "sync ~ (uutils) synchronize cache writes to storage" @@ -17,7 +17,7 @@ path = "src/sync.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["wide"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["wide"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } winapi = { version = "0.3", features = ["errhandlingapi", "fileapi", "handleapi", "std", "winbase", "winerror"] } diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index 2e54c129e..18e9fa430 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tac" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "tac ~ (uutils) concatenate and display input lines in reverse order" @@ -16,7 +16,7 @@ path = "src/tac.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/tail/Cargo.toml b/src/uu/tail/Cargo.toml index 6e51e3e35..715a214e2 100644 --- a/src/uu/tail/Cargo.toml +++ b/src/uu/tail/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tail" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "tail ~ (uutils) display the last lines of input" @@ -17,7 +17,7 @@ path = "src/tail.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } winapi = { version="0.3", features=["fileapi", "handleapi", "processthreadsapi", "synchapi", "winbase"] } diff --git a/src/uu/tee/Cargo.toml b/src/uu/tee/Cargo.toml index 51bba2e45..c1841ce0f 100644 --- a/src/uu/tee/Cargo.toml +++ b/src/uu/tee/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tee" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "tee ~ (uutils) display input and copy to FILE" @@ -18,7 +18,7 @@ path = "src/tee.rs" clap = "2.33.3" libc = "0.2.42" retain_mut = "0.1.2" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["libc"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["libc"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/test/Cargo.toml b/src/uu/test/Cargo.toml index 6471c9e62..c03b84ab4 100644 --- a/src/uu/test/Cargo.toml +++ b/src/uu/test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_test" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "test ~ (uutils) evaluate comparison and file type expressions" @@ -16,7 +16,7 @@ path = "src/test.rs" [dependencies] libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(target_os = "redox")'.dependencies] diff --git a/src/uu/timeout/Cargo.toml b/src/uu/timeout/Cargo.toml index c13a98d19..c32547559 100644 --- a/src/uu/timeout/Cargo.toml +++ b/src/uu/timeout/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_timeout" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "timeout ~ (uutils) run COMMAND with a DURATION time limit" @@ -17,7 +17,7 @@ path = "src/timeout.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["parse_time", "process", "signals"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["parse_time", "process", "signals"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index fc021c096..6fa84cbdd 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_touch" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "touch ~ (uutils) change FILE timestamps" @@ -18,7 +18,7 @@ path = "src/touch.rs" filetime = "0.2.1" clap = "2.33" time = "0.1.40" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["libc"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["libc"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/tr/Cargo.toml b/src/uu/tr/Cargo.toml index 3683211f6..04c013659 100644 --- a/src/uu/tr/Cargo.toml +++ b/src/uu/tr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tr" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "tr ~ (uutils) translate characters within input and display" @@ -18,7 +18,7 @@ path = "src/tr.rs" bit-set = "0.5.0" fnv = "1.0.5" clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/true/Cargo.toml b/src/uu/true/Cargo.toml index a73bfddd5..780288155 100644 --- a/src/uu/true/Cargo.toml +++ b/src/uu/true/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_true" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "true ~ (uutils) do nothing and succeed" @@ -15,7 +15,7 @@ edition = "2018" path = "src/true.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/truncate/Cargo.toml b/src/uu/truncate/Cargo.toml index 4f770e666..19f0d2736 100644 --- a/src/uu/truncate/Cargo.toml +++ b/src/uu/truncate/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_truncate" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "truncate ~ (uutils) truncate (or extend) FILE to SIZE" @@ -16,7 +16,7 @@ path = "src/truncate.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/tsort/Cargo.toml b/src/uu/tsort/Cargo.toml index d870e0155..3f3d20170 100644 --- a/src/uu/tsort/Cargo.toml +++ b/src/uu/tsort/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tsort" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "tsort ~ (uutils) topologically sort input (partially ordered) pairs" @@ -16,7 +16,7 @@ path = "src/tsort.rs" [dependencies] clap= "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/tty/Cargo.toml b/src/uu/tty/Cargo.toml index 7e4ffbd79..d2c5110b5 100644 --- a/src/uu/tty/Cargo.toml +++ b/src/uu/tty/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tty" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "tty ~ (uutils) display the name of the terminal connected to standard input" @@ -17,7 +17,7 @@ path = "src/tty.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/uname/Cargo.toml b/src/uu/uname/Cargo.toml index 87754f45a..a0461e33f 100644 --- a/src/uu/uname/Cargo.toml +++ b/src/uu/uname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uname" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "uname ~ (uutils) display system information" @@ -17,7 +17,7 @@ path = "src/uname.rs" [dependencies] clap = "2.33" platform-info = "0.1" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/unexpand/Cargo.toml b/src/uu/unexpand/Cargo.toml index d66d335bf..6d1cad613 100644 --- a/src/uu/unexpand/Cargo.toml +++ b/src/uu/unexpand/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_unexpand" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "unexpand ~ (uutils) convert input spaces to tabs" @@ -17,7 +17,7 @@ path = "src/unexpand.rs" [dependencies] clap = "2.33" unicode-width = "0.1.5" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/uniq/Cargo.toml b/src/uu/uniq/Cargo.toml index d3cf4309d..53c2281c4 100644 --- a/src/uu/uniq/Cargo.toml +++ b/src/uu/uniq/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uniq" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "uniq ~ (uutils) filter identical adjacent lines from input" @@ -16,7 +16,7 @@ path = "src/uniq.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/unlink/Cargo.toml b/src/uu/unlink/Cargo.toml index 68edec54d..ea18e2cbb 100644 --- a/src/uu/unlink/Cargo.toml +++ b/src/uu/unlink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_unlink" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "unlink ~ (uutils) remove a (file system) link to FILE" @@ -17,7 +17,7 @@ path = "src/unlink.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/uptime/Cargo.toml b/src/uu/uptime/Cargo.toml index d66acc77f..823879954 100644 --- a/src/uu/uptime/Cargo.toml +++ b/src/uu/uptime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uptime" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "uptime ~ (uutils) display dynamic system information" @@ -17,7 +17,7 @@ path = "src/uptime.rs" [dependencies] chrono = "0.4" clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["libc", "utmpx"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["libc", "utmpx"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/users/Cargo.toml b/src/uu/users/Cargo.toml index ed6f110b6..087272a59 100644 --- a/src/uu/users/Cargo.toml +++ b/src/uu/users/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_users" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "users ~ (uutils) display names of currently logged-in users" @@ -16,7 +16,7 @@ path = "src/users.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["utmpx"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["utmpx"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/wc/Cargo.toml b/src/uu/wc/Cargo.toml index 4e6cef101..3f44c1273 100644 --- a/src/uu/wc/Cargo.toml +++ b/src/uu/wc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_wc" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "wc ~ (uutils) display newline, word, and byte counts for input" @@ -16,7 +16,7 @@ path = "src/wc.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } thiserror = "1.0" diff --git a/src/uu/who/Cargo.toml b/src/uu/who/Cargo.toml index fce0178aa..928136b10 100644 --- a/src/uu/who/Cargo.toml +++ b/src/uu/who/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_who" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "who ~ (uutils) display information about currently logged-in users" @@ -15,7 +15,7 @@ edition = "2018" path = "src/who.rs" [dependencies] -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["utmpx"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["utmpx"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/whoami/Cargo.toml b/src/uu/whoami/Cargo.toml index a3158f62a..e843b2167 100644 --- a/src/uu/whoami/Cargo.toml +++ b/src/uu/whoami/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_whoami" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "whoami ~ (uutils) display user name of current effective user ID" @@ -16,7 +16,7 @@ path = "src/whoami.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "wide"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "wide"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(target_os = "windows")'.dependencies] diff --git a/src/uu/yes/Cargo.toml b/src/uu/yes/Cargo.toml index 729ce693a..ab8a6faff 100644 --- a/src/uu/yes/Cargo.toml +++ b/src/uu/yes/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_yes" -version = "0.0.4" +version = "0.0.5" authors = ["uutils developers"] license = "MIT" description = "yes ~ (uutils) repeatedly display a line with STRING (or 'y')" @@ -16,7 +16,7 @@ path = "src/yes.rs" [dependencies] clap = "2.33" -uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["zero-copy"] } +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["zero-copy"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [features] diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index a5fbe4c79..855e64b36 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uucore" -version = "0.0.7" +version = "0.0.8" authors = ["uutils developers"] license = "MIT" description = "uutils ~ 'core' uutils code library (cross-platform)" diff --git a/util/update-version.sh b/util/update-version.sh index 584d13608..f5b66fb8c 100644 --- a/util/update-version.sh +++ b/util/update-version.sh @@ -3,11 +3,11 @@ # So, it should be triple-checked -FROM="0.0.3" -TO="0.0.4" +FROM="0.0.4" +TO="0.0.5" -UUCORE_FROM="0.0.6" -UUCORE_TO="0.0.7" +UUCORE_FROM="0.0.7" +UUCORE_TO="0.0.8" PROGS=$(ls -1d src/uu/*/Cargo.toml src/uu/stdbuf/src/libstdbuf/Cargo.toml Cargo.toml) From 06bdc144d70329d68c0268943175c7b798afbb47 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Sat, 3 Apr 2021 12:43:37 +0200 Subject: [PATCH 080/132] ls: show/hide control chars --- src/uu/ls/src/ls.rs | 41 ++++++++- src/uu/ls/src/quoting_style.rs | 152 ++++++++++++++++++++++++++------- 2 files changed, 158 insertions(+), 35 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index ece497bdb..9bb8b7e63 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -119,7 +119,8 @@ pub mod options { pub static FILE_TYPE: &str = "file-type"; pub static CLASSIFY: &str = "classify"; } - + pub static HIDE_CONTROL_CHARS: &str = "hide-control-chars"; + pub static SHOW_CONTROL_CHARS: &str = "show-control-chars"; pub static WIDTH: &str = "width"; pub static AUTHOR: &str = "author"; pub static NO_GROUP: &str = "no-group"; @@ -366,24 +367,36 @@ impl Config { }) .or_else(|| termsize::get().map(|s| s.cols)); + let show_control = if options.is_present(options::HIDE_CONTROL_CHARS) { + false + } else if options.is_present(options::SHOW_CONTROL_CHARS) { + true + } else { + false // TODO: only if output is a terminal and the program is `ls` + }; + let quoting_style = if let Some(style) = options.value_of(options::QUOTING_STYLE) { match style { - "literal" => QuotingStyle::Literal, + "literal" => QuotingStyle::Literal { show_control }, "shell" => QuotingStyle::Shell { escape: false, always_quote: false, + show_control, }, "shell-always" => QuotingStyle::Shell { escape: false, always_quote: true, + show_control, }, "shell-escape" => QuotingStyle::Shell { escape: true, always_quote: false, + show_control, }, "shell-escape-always" => QuotingStyle::Shell { escape: true, always_quote: true, + show_control, }, "c" => QuotingStyle::C { quotes: quoting_style::Quotes::Double, @@ -394,7 +407,7 @@ impl Config { _ => unreachable!("Should have been caught by Clap"), } } else if options.is_present(options::quoting::LITERAL) { - QuotingStyle::Literal + QuotingStyle::Literal { show_control } } else if options.is_present(options::quoting::ESCAPE) { QuotingStyle::C { quotes: quoting_style::Quotes::None, @@ -408,6 +421,7 @@ impl Config { QuotingStyle::Shell { escape: true, always_quote: false, + show_control, } }; @@ -619,6 +633,27 @@ pub fn uumain(args: impl uucore::Args) -> i32 { ]) ) + // Control characters + .arg( + Arg::with_name(options::HIDE_CONTROL_CHARS) + .short("q") + .long(options::HIDE_CONTROL_CHARS) + .help("Replace control characters with '?' if they are not escaped.") + .overrides_with_all(&[ + options::HIDE_CONTROL_CHARS, + options::SHOW_CONTROL_CHARS, + ]) + ) + .arg( + Arg::with_name(options::SHOW_CONTROL_CHARS) + .long(options::SHOW_CONTROL_CHARS) + .help("Show control characters 'as is' if they are not escaped.") + .overrides_with_all(&[ + options::HIDE_CONTROL_CHARS, + options::SHOW_CONTROL_CHARS, + ]) + ) + // Time arguments .arg( Arg::with_name(options::TIME) diff --git a/src/uu/ls/src/quoting_style.rs b/src/uu/ls/src/quoting_style.rs index 74108094a..ceb54466c 100644 --- a/src/uu/ls/src/quoting_style.rs +++ b/src/uu/ls/src/quoting_style.rs @@ -2,14 +2,22 @@ use std::char::from_digit; const SPECIAL_SHELL_CHARS: &str = "~`#$&*()\\|[]{};'\"<>?! "; -pub(crate) enum QuotingStyle { - Shell { escape: bool, always_quote: bool }, - C { quotes: Quotes }, - Literal, +pub(super) enum QuotingStyle { + Shell { + escape: bool, + always_quote: bool, + show_control: bool, + }, + C { + quotes: Quotes, + }, + Literal { + show_control: bool, + }, } #[derive(Clone, Copy)] -pub(crate) enum Quotes { +pub(super) enum Quotes { None, Single, Double, @@ -81,6 +89,12 @@ impl EscapeOctal { } impl EscapedChar { + fn new_literal(c: char) -> Self { + Self { + state: EscapeState::Char(c), + } + } + fn new_c(c: char, quotes: Quotes) -> Self { use EscapeState::*; let init_state = match c { @@ -110,27 +124,10 @@ impl EscapedChar { Self { state: init_state } } - // fn new_shell(c: char, quotes: Quotes) -> Self { - // use EscapeState::*; - // let init_state = match c { - // // If the string is single quoted, the single quote should be escaped - // '\'' => match quotes { - // Quotes::Single => Backslash('\''), - // _ => Char('\''), - // }, - // // All control characters should be rendered as ?: - // _ if c.is_ascii_control() => Char('?'), - // // Special shell characters must be escaped: - // _ if SPECIAL_SHELL_CHARS.contains(c) => ForceQuote(c), - // _ => Char(c), - // }; - // Self { state: init_state } - // } - fn new_shell(c: char, escape: bool, quotes: Quotes) -> Self { use EscapeState::*; let init_state = match c { - _ if !escape && c.is_control() => Char('?'), + _ if !escape && c.is_control() => Char(c), '\x07' => Backslash('a'), '\x08' => Backslash('b'), '\t' => Backslash('t'), @@ -149,6 +146,15 @@ impl EscapedChar { }; Self { state: init_state } } + + fn hide_control(self) -> Self { + match self.state { + EscapeState::Char(c) if c.is_control() => Self { + state: EscapeState::Char('?'), + }, + _ => self, + } + } } impl Iterator for EscapedChar { @@ -170,12 +176,20 @@ impl Iterator for EscapedChar { } } -fn shell_without_escape(name: String, quotes: Quotes) -> (String, bool) { +fn shell_without_escape(name: String, quotes: Quotes, show_control_chars: bool) -> (String, bool) { let mut must_quote = false; let mut escaped_str = String::with_capacity(name.len()); for c in name.chars() { - let escaped = EscapedChar::new_shell(c, false, quotes); + let escaped = { + let ec = EscapedChar::new_shell(c, false, quotes); + if show_control_chars { + ec + } else { + ec.hide_control() + } + }; + match escaped.state { EscapeState::Backslash('\'') => escaped_str.push_str("'\\''"), EscapeState::ForceQuote(x) => { @@ -242,7 +256,15 @@ fn shell_with_escape(name: String, quotes: Quotes) -> (String, bool) { pub(super) fn escape_name(name: String, style: &QuotingStyle) -> String { match style { - QuotingStyle::Literal => name, + QuotingStyle::Literal { show_control } => { + if !show_control { + name.chars() + .flat_map(|c| EscapedChar::new_literal(c).hide_control()) + .collect() + } else { + name + } + } QuotingStyle::C { quotes } => { let escaped_str: String = name .chars() @@ -258,6 +280,7 @@ pub(super) fn escape_name(name: String, style: &QuotingStyle) -> String { QuotingStyle::Shell { escape, always_quote, + show_control, } => { let (quotes, must_quote) = if name.contains('"') { (Quotes::Single, true) @@ -272,7 +295,7 @@ pub(super) fn escape_name(name: String, style: &QuotingStyle) -> String { let (escaped_str, contains_quote_chars) = if *escape { shell_with_escape(name, quotes) } else { - shell_without_escape(name, quotes) + shell_without_escape(name, quotes, *show_control) }; match (must_quote | contains_quote_chars, quotes) { @@ -289,7 +312,10 @@ mod tests { use crate::quoting_style::{escape_name, Quotes, QuotingStyle}; fn get_style(s: &str) -> QuotingStyle { match s { - "literal" => QuotingStyle::Literal, + "literal" => QuotingStyle::Literal { + show_control: false, + }, + "literal-show" => QuotingStyle::Literal { show_control: true }, "escape" => QuotingStyle::C { quotes: Quotes::None, }, @@ -299,18 +325,32 @@ mod tests { "shell" => QuotingStyle::Shell { escape: false, always_quote: false, + show_control: false, + }, + "shell-show" => QuotingStyle::Shell { + escape: false, + always_quote: false, + show_control: true, }, "shell-always" => QuotingStyle::Shell { escape: false, always_quote: true, + show_control: false, + }, + "shell-always-show" => QuotingStyle::Shell { + escape: false, + always_quote: true, + show_control: true, }, "shell-escape" => QuotingStyle::Shell { escape: true, always_quote: false, + show_control: false, }, "shell-escape-always" => QuotingStyle::Shell { escape: true, always_quote: true, + show_control: false, }, _ => panic!("Invalid name!"), } @@ -333,10 +373,13 @@ mod tests { "one_two", vec![ ("one_two", "literal"), + ("one_two", "literal-show"), ("one_two", "escape"), ("\"one_two\"", "c"), ("one_two", "shell"), + ("one_two", "shell-show"), ("\'one_two\'", "shell-always"), + ("\'one_two\'", "shell-always-show"), ("one_two", "shell-escape"), ("\'one_two\'", "shell-escape-always"), ], @@ -349,10 +392,13 @@ mod tests { "one two", vec![ ("one two", "literal"), + ("one two", "literal-show"), ("one\\ two", "escape"), ("\"one two\"", "c"), ("\'one two\'", "shell"), + ("\'one two\'", "shell-show"), ("\'one two\'", "shell-always"), + ("\'one two\'", "shell-always-show"), ("\'one two\'", "shell-escape"), ("\'one two\'", "shell-escape-always"), ], @@ -362,10 +408,13 @@ mod tests { " one", vec![ (" one", "literal"), + (" one", "literal-show"), ("\\ one", "escape"), ("\" one\"", "c"), ("' one'", "shell"), + ("' one'", "shell-show"), ("' one'", "shell-always"), + ("' one'", "shell-always-show"), ("' one'", "shell-escape"), ("' one'", "shell-escape-always"), ], @@ -379,10 +428,13 @@ mod tests { "one\"two", vec![ ("one\"two", "literal"), + ("one\"two", "literal-show"), ("one\"two", "escape"), ("\"one\\\"two\"", "c"), ("'one\"two'", "shell"), + ("'one\"two'", "shell-show"), ("'one\"two'", "shell-always"), + ("'one\"two'", "shell-always-show"), ("'one\"two'", "shell-escape"), ("'one\"two'", "shell-escape-always"), ], @@ -393,10 +445,13 @@ mod tests { "one\'two", vec![ ("one'two", "literal"), + ("one'two", "literal-show"), ("one'two", "escape"), ("\"one'two\"", "c"), ("\"one'two\"", "shell"), + ("\"one'two\"", "shell-show"), ("\"one'two\"", "shell-always"), + ("\"one'two\"", "shell-always-show"), ("\"one'two\"", "shell-escape"), ("\"one'two\"", "shell-escape-always"), ], @@ -407,10 +462,13 @@ mod tests { "one'two\"three", vec![ ("one'two\"three", "literal"), + ("one'two\"three", "literal-show"), ("one'two\"three", "escape"), ("\"one'two\\\"three\"", "c"), ("'one'\\''two\"three'", "shell"), + ("'one'\\''two\"three'", "shell-show"), ("'one'\\''two\"three'", "shell-always"), + ("'one'\\''two\"three'", "shell-always-show"), ("'one'\\''two\"three'", "shell-escape"), ("'one'\\''two\"three'", "shell-escape-always"), ], @@ -421,10 +479,13 @@ mod tests { "one''two\"\"three", vec![ ("one''two\"\"three", "literal"), + ("one''two\"\"three", "literal-show"), ("one''two\"\"three", "escape"), ("\"one''two\\\"\\\"three\"", "c"), ("'one'\\'''\\''two\"\"three'", "shell"), + ("'one'\\'''\\''two\"\"three'", "shell-show"), ("'one'\\'''\\''two\"\"three'", "shell-always"), + ("'one'\\'''\\''two\"\"three'", "shell-always-show"), ("'one'\\'''\\''two\"\"three'", "shell-escape"), ("'one'\\'''\\''two\"\"three'", "shell-escape-always"), ], @@ -437,11 +498,14 @@ mod tests { check_names( "one\ntwo", vec![ - ("one\ntwo", "literal"), + ("one?two", "literal"), + ("one\ntwo", "literal-show"), ("one\\ntwo", "escape"), ("\"one\\ntwo\"", "c"), ("one?two", "shell"), + ("one\ntwo", "shell-show"), ("'one?two'", "shell-always"), + ("'one\ntwo'", "shell-always-show"), ("'one'$'\\n''two'", "shell-escape"), ("'one'$'\\n''two'", "shell-escape-always"), ], @@ -452,9 +516,10 @@ mod tests { check_names( "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", vec![ + ("????????????????", "literal"), ( "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", - "literal", + "literal-show", ), ( "\\000\\001\\002\\003\\004\\005\\006\\a\\b\\t\\n\\v\\f\\r\\016\\017", @@ -465,7 +530,15 @@ mod tests { "c", ), ("????????????????", "shell"), + ( + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + "shell-show", + ), ("'????????????????'", "shell-always"), + ( + "'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'", + "shell-always-show", + ), ( "''$'\\000\\001\\002\\003\\004\\005\\006\\a\\b\\t\\n\\v\\f\\r\\016\\017'", "shell-escape", @@ -481,9 +554,10 @@ mod tests { check_names( "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", vec![ + ("????????????????", "literal"), ( "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", - "literal", + "literal-show", ), ( "\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037", @@ -494,7 +568,15 @@ mod tests { "c", ), ("????????????????", "shell"), + ( + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", + "shell-show", + ), ("'????????????????'", "shell-always"), + ( + "'\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F'", + "shell-always-show", + ), ( "''$'\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037'", "shell-escape", @@ -510,11 +592,14 @@ mod tests { check_names( "\x7F", vec![ - ("\x7F", "literal"), + ("?", "literal"), + ("\x7F", "literal-show"), ("\\177", "escape"), ("\"\\177\"", "c"), ("?", "shell"), + ("\x7F", "shell-show"), ("'?'", "shell-always"), + ("'\x7F'", "shell-always-show"), ("''$'\\177'", "shell-escape"), ("''$'\\177'", "shell-escape-always"), ], @@ -530,10 +615,13 @@ mod tests { "one?two", vec![ ("one?two", "literal"), + ("one?two", "literal-show"), ("one?two", "escape"), ("\"one?two\"", "c"), ("'one?two'", "shell"), + ("'one?two'", "shell-show"), ("'one?two'", "shell-always"), + ("'one?two'", "shell-always-show"), ("'one?two'", "shell-escape"), ("'one?two'", "shell-escape-always"), ], From 9cb0fc2945afc7d7d5e7c96a4763039652c4c46c Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Sat, 3 Apr 2021 13:15:19 +0200 Subject: [PATCH 081/132] ls: forgot to push updated tests --- tests/by-util/test_ls.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index d403e5577..b49620eb1 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1142,9 +1142,9 @@ fn test_ls_quoting_style() { assert_eq!(result.stdout, "'one'$'\\n''two'\n"); for (arg, correct) in &[ - ("--quoting-style=literal", "one\ntwo"), - ("-N", "one\ntwo"), - ("--literal", "one\ntwo"), + ("--quoting-style=literal", "one?two"), + ("-N", "one?two"), + ("--literal", "one?two"), ("--quoting-style=c", "\"one\\ntwo\""), ("-Q", "\"one\\ntwo\""), ("--quote-name", "\"one\\ntwo\""), @@ -1161,6 +1161,24 @@ fn test_ls_quoting_style() { println!("stdout = {:?}", result.stdout); assert_eq!(result.stdout, format!("{}\n", correct)); } + + for (arg, correct) in &[ + ("--quoting-style=literal", "one\ntwo"), + ("-N", "one\ntwo"), + ("--literal", "one\ntwo"), + ("--quoting-style=shell", "one\ntwo"), + ("--quoting-style=shell-always", "'one\ntwo'"), + ] { + let result = scene + .ucmd() + .arg(arg) + .arg("--show-control-chars") + .arg("one\ntwo") + .run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert_eq!(result.stdout, format!("{}\n", correct)); + } } let result = scene.ucmd().arg("one two").succeeds(); From a85257474554e354d5018c9407c0d782b4ea8529 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 3 Apr 2021 15:49:13 +0200 Subject: [PATCH 082/132] Fix bug #2017 - cat isn't working Revert "cat: Improve performance on Linux (#1978)" This reverts commit 7a947cfe46b694f61a5a7d840d622ce292da457c. --- Cargo.lock | 3 +- src/uu/cat/Cargo.toml | 5 +- src/uu/cat/src/cat.rs | 426 +++++++++++++++++------------------------- 3 files changed, 178 insertions(+), 256 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5eb65a92..6c7c165e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1581,8 +1581,7 @@ name = "uu_cat" version = "0.0.5" dependencies = [ "clap", - "nix 0.20.0", - "thiserror", + "quick-error", "unix_socket", "uucore", "uucore_procs", diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index 25119dcfc..2176a5e0b 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -16,16 +16,13 @@ path = "src/cat.rs" [dependencies] clap = "2.33" -thiserror = "1.0" +quick-error = "1.2.3" uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(unix)'.dependencies] unix_socket = "0.5.0" -[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] -nix = "0.20" - [[bin]] name = "cat" path = "src/main.rs" diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index f39708fd8..cf5a384a4 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -3,13 +3,14 @@ // (c) Jordi Boggiano // (c) Evgeniy Klyuchikov // (c) Joshua S. Miller -// (c) Árni Dagur // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // spell-checker:ignore (ToDO) nonprint nonblank nonprinting +#[macro_use] +extern crate quick_error; #[cfg(unix)] extern crate unix_socket; #[macro_use] @@ -17,9 +18,9 @@ extern crate uucore; // last synced with: cat (GNU coreutils) 8.13 use clap::{App, Arg}; +use quick_error::ResultExt; use std::fs::{metadata, File}; -use std::io::{self, Read, Write}; -use thiserror::Error; +use std::io::{self, stderr, stdin, stdout, BufWriter, Read, Write}; use uucore::fs::is_stdin_interactive; /// Unix domain socket support @@ -30,44 +31,12 @@ use std::os::unix::fs::FileTypeExt; #[cfg(unix)] use unix_socket::UnixStream; -#[cfg(any(target_os = "linux", target_os = "android"))] -use nix::errno::Errno; -/// Linux splice support -#[cfg(any(target_os = "linux", target_os = "android"))] -use nix::fcntl::{splice, SpliceFFlags}; -#[cfg(any(target_os = "linux", target_os = "android"))] -use nix::unistd::pipe; -#[cfg(any(target_os = "linux", target_os = "android"))] -use std::os::unix::io::{AsRawFd, RawFd}; - static NAME: &str = "cat"; static VERSION: &str = env!("CARGO_PKG_VERSION"); static SYNTAX: &str = "[OPTION]... [FILE]..."; static SUMMARY: &str = "Concatenate FILE(s), or standard input, to standard output With no FILE, or when FILE is -, read standard input."; -#[derive(Error, Debug)] -enum CatError { - /// Wrapper around `io::Error` - #[error("{0}")] - Io(#[from] io::Error), - /// Wrapper around `nix::Error` - #[cfg(any(target_os = "linux", target_os = "android"))] - #[error("{0}")] - Nix(#[from] nix::Error), - /// Unknown file type; it's not a regular file, socket, etc. - #[error("{}: unknown filetype: {}", path, ft_debug)] - UnknownFiletype { - path: String, - /// A debug print of the file type - ft_debug: String, - }, - #[error("{0}: Expected a file, found directory")] - IsDirectory(String), -} - -type CatResult = Result; - #[derive(PartialEq)] enum NumberingMode { None, @@ -75,6 +44,39 @@ enum NumberingMode { All, } +quick_error! { + #[derive(Debug)] + enum CatError { + /// Wrapper for io::Error with path context + Input(err: io::Error, path: String) { + display("cat: {0}: {1}", path, err) + context(path: &'a str, err: io::Error) -> (err, path.to_owned()) + cause(err) + } + + /// Wrapper for io::Error with no context + Output(err: io::Error) { + display("cat: {0}", err) from() + cause(err) + } + + /// Unknown Filetype classification + UnknownFiletype(path: String) { + display("cat: {0}: unknown filetype", path) + } + + /// At least one error was encountered in reading or writing + EncounteredErrors(count: usize) { + display("cat: encountered {0} errors", count) + } + + /// Denotes an error caused by trying to `cat` a directory + IsDirectory(path: String) { + display("cat: {0}: Is a directory", path) + } + } +} + struct OutputOptions { /// Line numbering mode number: NumberingMode, @@ -85,56 +87,21 @@ struct OutputOptions { /// display TAB characters as `tab` show_tabs: bool, - /// Show end of lines - show_ends: bool, + /// If `show_tabs == true`, this string will be printed in the + /// place of tabs + tab: String, + + /// Can be set to show characters other than '\n' a the end of + /// each line, e.g. $ + end_of_line: String, /// use ^ and M- notation, except for LF (\\n) and TAB (\\t) show_nonprint: bool, } -impl OutputOptions { - fn tab(&self) -> &'static str { - if self.show_tabs { - "^I" - } else { - "\t" - } - } - - fn end_of_line(&self) -> &'static str { - if self.show_ends { - "$\n" - } else { - "\n" - } - } - - /// We can write fast if we can simply copy the contents of the file to - /// stdout, without augmenting the output with e.g. line numbers. - fn can_write_fast(&self) -> bool { - !(self.show_tabs - || self.show_nonprint - || self.show_ends - || self.squeeze_blank - || self.number != NumberingMode::None) - } -} - -/// State that persists between output of each file. This struct is only used -/// when we can't write fast. -struct OutputState { - /// The current line number - line_number: usize, - - /// Whether the output cursor is at the beginning of a new line - at_line_start: bool, -} - /// Represents an open file handle, stream, or other device -struct InputHandle { - #[cfg(any(target_os = "linux", target_os = "android"))] - file_descriptor: RawFd, - reader: R, +struct InputHandle { + reader: Box, is_interactive: bool, } @@ -157,6 +124,8 @@ enum InputType { Socket, } +type CatResult = Result; + mod options { pub static FILE: &str = "file"; pub static SHOW_ALL: &str = "show-all"; @@ -274,14 +243,30 @@ pub fn uumain(args: impl uucore::Args) -> i32 { None => vec!["-".to_owned()], }; - let options = OutputOptions { - show_ends, - number: number_mode, - show_nonprint, - show_tabs, - squeeze_blank, + let can_write_fast = !(show_tabs + || show_nonprint + || show_ends + || squeeze_blank + || number_mode != NumberingMode::None); + + let success = if can_write_fast { + write_fast(files).is_ok() + } else { + let tab = if show_tabs { "^I" } else { "\t" }.to_owned(); + + let end_of_line = if show_ends { "$\n" } else { "\n" }.to_owned(); + + let options = OutputOptions { + end_of_line, + number: number_mode, + show_nonprint, + show_tabs, + squeeze_blank, + tab, + }; + + write_lines(files, &options).is_ok() }; - let success = cat_files(files, &options).is_ok(); if success { 0 @@ -290,76 +275,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } } -fn cat_handle( - handle: &mut InputHandle, - options: &OutputOptions, - state: &mut OutputState, -) -> CatResult<()> { - if options.can_write_fast() { - write_fast(handle) - } else { - write_lines(handle, &options, state) - } -} - -fn cat_path(path: &str, options: &OutputOptions, state: &mut OutputState) -> CatResult<()> { - if path == "-" { - let stdin = io::stdin(); - let mut handle = InputHandle { - #[cfg(any(target_os = "linux", target_os = "android"))] - file_descriptor: stdin.as_raw_fd(), - reader: stdin, - is_interactive: is_stdin_interactive(), - }; - return cat_handle(&mut handle, &options, state); - } - match get_input_type(path)? { - InputType::Directory => Err(CatError::IsDirectory(path.to_owned())), - #[cfg(unix)] - InputType::Socket => { - let socket = UnixStream::connect(path)?; - socket.shutdown(Shutdown::Write)?; - let mut handle = InputHandle { - #[cfg(any(target_os = "linux", target_os = "android"))] - file_descriptor: socket.as_raw_fd(), - reader: socket, - is_interactive: false, - }; - cat_handle(&mut handle, &options, state) - } - _ => { - let file = File::open(path)?; - let mut handle = InputHandle { - #[cfg(any(target_os = "linux", target_os = "android"))] - file_descriptor: file.as_raw_fd(), - reader: file, - is_interactive: false, - }; - cat_handle(&mut handle, &options, state) - } - } -} - -fn cat_files(files: Vec, options: &OutputOptions) -> Result<(), u32> { - let mut error_count = 0; - let mut state = OutputState { - line_number: 1, - at_line_start: true, - }; - - for path in &files { - if let Err(err) = cat_path(path, &options, &mut state) { - show_error!("{}", err); - error_count += 1; - } - } - if error_count == 0 { - Ok(()) - } else { - Err(error_count) - } -} - /// Classifies the `InputType` of file at `path` if possible /// /// # Arguments @@ -370,8 +285,7 @@ fn get_input_type(path: &str) -> CatResult { return Ok(InputType::StdIn); } - let ft = metadata(path)?.file_type(); - match ft { + match metadata(path).context(path)?.file_type() { #[cfg(unix)] ft if ft.is_block_device() => Ok(InputType::BlockDevice), #[cfg(unix)] @@ -383,113 +297,125 @@ fn get_input_type(path: &str) -> CatResult { ft if ft.is_dir() => Ok(InputType::Directory), ft if ft.is_file() => Ok(InputType::File), ft if ft.is_symlink() => Ok(InputType::SymLink), - _ => Err(CatError::UnknownFiletype { - path: path.to_owned(), - ft_debug: format!("{:?}", ft), - }), + _ => Err(CatError::UnknownFiletype(path.to_owned())), } } -/// Writes handle to stdout with no configuration. This allows a -/// simple memory copy. -fn write_fast(handle: &mut InputHandle) -> CatResult<()> { - let stdout = io::stdout(); - let mut stdout_lock = stdout.lock(); - #[cfg(any(target_os = "linux", target_os = "android"))] - { - // If we're on Linux or Android, try to use the splice() system call - // for faster writing. If it works, we're done. - if !write_fast_using_splice(handle, stdout.as_raw_fd())? { - return Ok(()); - } - } - // If we're not on Linux or Android, or the splice() call failed, - // fall back on slower writing. - let mut buf = [0; 1024 * 64]; - while let Ok(n) = handle.reader.read(&mut buf) { - if n == 0 { - break; - } - stdout_lock.write_all(&buf[..n])?; - } - Ok(()) -} - -/// This function is called from `write_fast()` on Linux and Android. The -/// function `splice()` is used to move data between two file descriptors -/// without copying between kernel- and userspace. This results in a large -/// speedup. +/// Returns an InputHandle from which a Reader can be accessed or an +/// error /// -/// The `bool` in the result value indicates if we need to fall back to normal -/// copying or not. False means we don't have to. -#[cfg(any(target_os = "linux", target_os = "android"))] -#[inline] -fn write_fast_using_splice(handle: &mut InputHandle, writer: RawFd) -> CatResult { - const BUF_SIZE: usize = 1024 * 16; +/// # Arguments +/// +/// * `path` - `InputHandler` will wrap a reader from this file path +fn open(path: &str) -> CatResult { + if path == "-" { + let stdin = stdin(); + return Ok(InputHandle { + reader: Box::new(stdin) as Box, + is_interactive: is_stdin_interactive(), + }); + } - let (pipe_rd, pipe_wr) = pipe()?; - - // We only fall back if splice fails on the first call. - match splice( - handle.file_descriptor, - None, - pipe_wr, - None, - BUF_SIZE, - SpliceFFlags::empty(), - ) { - Ok(n) => { - if n == 0 { - return Ok(false); - } + match get_input_type(path)? { + InputType::Directory => Err(CatError::IsDirectory(path.to_owned())), + #[cfg(unix)] + InputType::Socket => { + let socket = UnixStream::connect(path).context(path)?; + socket.shutdown(Shutdown::Write).context(path)?; + Ok(InputHandle { + reader: Box::new(socket) as Box, + is_interactive: false, + }) } - Err(err) => { - match err.as_errno() { - Some(Errno::EPERM) | Some(Errno::ENOSYS) | Some(Errno::EINVAL) => { - // EPERM indicates the call was blocked by seccomp. - // ENOSYS indicates we're running on an ancient Kernel. - // EINVAL indicates some other failure. - return Ok(true); - } - _ => { - // Other errors include running out of memory, etc. We - // don't attempt to fall back from these. - return Err(err)?; + _ => { + let file = File::open(path).context(path)?; + Ok(InputHandle { + reader: Box::new(file) as Box, + is_interactive: false, + }) + } + } +} + +/// Writes files to stdout with no configuration. This allows a +/// simple memory copy. Returns `Ok(())` if no errors were +/// encountered, or an error with the number of errors encountered. +/// +/// # Arguments +/// +/// * `files` - There is no short circuit when encountering an error +/// reading a file in this vector +fn write_fast(files: Vec) -> CatResult<()> { + let mut writer = stdout(); + let mut in_buf = [0; 1024 * 64]; + let mut error_count = 0; + + for file in files { + match open(&file[..]) { + Ok(mut handle) => { + while let Ok(n) = handle.reader.read(&mut in_buf) { + if n == 0 { + break; + } + writer.write_all(&in_buf[..n]).context(&file[..])?; } } + Err(error) => { + writeln!(&mut stderr(), "{}", error)?; + error_count += 1; + } } } - loop { - let n = splice( - handle.file_descriptor, - None, - pipe_wr, - None, - BUF_SIZE, - SpliceFFlags::empty(), - )?; - if n == 0 { - // We read 0 bytes from the input, - // which means we're done copying. - break; + match error_count { + 0 => Ok(()), + _ => Err(CatError::EncounteredErrors(error_count)), + } +} + +/// State that persists between output of each file +struct OutputState { + /// The current line number + line_number: usize, + + /// Whether the output cursor is at the beginning of a new line + at_line_start: bool, +} + +/// Writes files to stdout with `options` as configuration. Returns +/// `Ok(())` if no errors were encountered, or an error with the +/// number of errors encountered. +/// +/// # Arguments +/// +/// * `files` - There is no short circuit when encountering an error +/// reading a file in this vector +fn write_lines(files: Vec, options: &OutputOptions) -> CatResult<()> { + let mut error_count = 0; + let mut state = OutputState { + line_number: 1, + at_line_start: true, + }; + + for file in files { + if let Err(error) = write_file_lines(&file, options, &mut state) { + writeln!(&mut stderr(), "{}", error).context(&file[..])?; + error_count += 1; } - splice(pipe_rd, None, writer, None, BUF_SIZE, SpliceFFlags::empty())?; } - Ok(false) + match error_count { + 0 => Ok(()), + _ => Err(CatError::EncounteredErrors(error_count)), + } } /// Outputs file contents to stdout in a line-by-line fashion, /// propagating any errors that might occur. -fn write_lines( - handle: &mut InputHandle, - options: &OutputOptions, - state: &mut OutputState, -) -> CatResult<()> { +fn write_file_lines(file: &str, options: &OutputOptions, state: &mut OutputState) -> CatResult<()> { + let mut handle = open(file)?; let mut in_buf = [0; 1024 * 31]; - let stdout = io::stdout(); - let mut writer = stdout.lock(); + let mut writer = BufWriter::with_capacity(1024 * 64, stdout()); let mut one_blank_kept = false; while let Ok(n) = handle.reader.read(&mut in_buf) { @@ -507,9 +433,9 @@ fn write_lines( write!(&mut writer, "{0:6}\t", state.line_number)?; state.line_number += 1; } - writer.write_all(options.end_of_line().as_bytes())?; + writer.write_all(options.end_of_line.as_bytes())?; if handle.is_interactive { - writer.flush()?; + writer.flush().context(file)?; } } state.at_line_start = true; @@ -524,7 +450,7 @@ fn write_lines( // print to end of line or end of buffer let offset = if options.show_nonprint { - write_nonprint_to_end(&in_buf[pos..], &mut writer, options.tab().as_bytes()) + write_nonprint_to_end(&in_buf[pos..], &mut writer, options.tab.as_bytes()) } else if options.show_tabs { write_tab_to_end(&in_buf[pos..], &mut writer) } else { @@ -536,7 +462,7 @@ fn write_lines( break; } // print suitable end of line - writer.write_all(options.end_of_line().as_bytes())?; + writer.write_all(options.end_of_line.as_bytes())?; if handle.is_interactive { writer.flush()?; } From 7750db4f8ecc84ac352d59946799ffbbc96a4f50 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 3 Apr 2021 16:06:29 +0200 Subject: [PATCH 083/132] cat: add a trivial test --- tests/by-util/test_cat.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/by-util/test_cat.rs b/tests/by-util/test_cat.rs index b194eb9b0..481b1683d 100644 --- a/tests/by-util/test_cat.rs +++ b/tests/by-util/test_cat.rs @@ -3,6 +3,14 @@ extern crate unix_socket; use crate::common::util::*; +#[test] +fn test_output_simple() { + new_ucmd!() + .args(&["alpha.txt"]) + .succeeds() + .stdout_only("abcde\nfghij\nklmno\npqrst\nuvwxyz\n"); +} + #[test] fn test_output_multi_files_print_all_chars() { new_ucmd!() From f37284129e7f00a2d77fa768b7b87c529994ad1f Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 3 Apr 2021 15:55:02 +0200 Subject: [PATCH 084/132] new release 0.0.6 to address the cat issue --- Cargo.lock | 194 ++++++++++++------------- Cargo.toml | 192 ++++++++++++------------ src/uu/arch/Cargo.toml | 2 +- src/uu/base32/Cargo.toml | 2 +- src/uu/base64/Cargo.toml | 2 +- src/uu/basename/Cargo.toml | 2 +- src/uu/cat/Cargo.toml | 2 +- src/uu/chgrp/Cargo.toml | 2 +- src/uu/chmod/Cargo.toml | 2 +- src/uu/chown/Cargo.toml | 2 +- src/uu/chroot/Cargo.toml | 2 +- src/uu/cksum/Cargo.toml | 2 +- src/uu/comm/Cargo.toml | 2 +- src/uu/cp/Cargo.toml | 2 +- src/uu/csplit/Cargo.toml | 2 +- src/uu/cut/Cargo.toml | 2 +- src/uu/date/Cargo.toml | 2 +- src/uu/df/Cargo.toml | 2 +- src/uu/dircolors/Cargo.toml | 2 +- src/uu/dirname/Cargo.toml | 2 +- src/uu/du/Cargo.toml | 2 +- src/uu/echo/Cargo.toml | 2 +- src/uu/env/Cargo.toml | 2 +- src/uu/expand/Cargo.toml | 2 +- src/uu/expr/Cargo.toml | 2 +- src/uu/factor/Cargo.toml | 2 +- src/uu/false/Cargo.toml | 2 +- src/uu/fmt/Cargo.toml | 2 +- src/uu/fold/Cargo.toml | 2 +- src/uu/groups/Cargo.toml | 2 +- src/uu/hashsum/Cargo.toml | 2 +- src/uu/head/Cargo.toml | 2 +- src/uu/hostid/Cargo.toml | 2 +- src/uu/hostname/Cargo.toml | 2 +- src/uu/id/Cargo.toml | 2 +- src/uu/install/Cargo.toml | 2 +- src/uu/join/Cargo.toml | 2 +- src/uu/kill/Cargo.toml | 2 +- src/uu/link/Cargo.toml | 2 +- src/uu/ln/Cargo.toml | 2 +- src/uu/logname/Cargo.toml | 2 +- src/uu/ls/Cargo.toml | 2 +- src/uu/mkdir/Cargo.toml | 2 +- src/uu/mkfifo/Cargo.toml | 2 +- src/uu/mknod/Cargo.toml | 2 +- src/uu/mktemp/Cargo.toml | 2 +- src/uu/more/Cargo.toml | 2 +- src/uu/mv/Cargo.toml | 2 +- src/uu/nice/Cargo.toml | 2 +- src/uu/nl/Cargo.toml | 2 +- src/uu/nohup/Cargo.toml | 2 +- src/uu/nproc/Cargo.toml | 2 +- src/uu/numfmt/Cargo.toml | 2 +- src/uu/od/Cargo.toml | 2 +- src/uu/paste/Cargo.toml | 2 +- src/uu/pathchk/Cargo.toml | 2 +- src/uu/pinky/Cargo.toml | 2 +- src/uu/printenv/Cargo.toml | 2 +- src/uu/printf/Cargo.toml | 2 +- src/uu/ptx/Cargo.toml | 2 +- src/uu/pwd/Cargo.toml | 2 +- src/uu/readlink/Cargo.toml | 2 +- src/uu/realpath/Cargo.toml | 2 +- src/uu/relpath/Cargo.toml | 2 +- src/uu/rm/Cargo.toml | 2 +- src/uu/rmdir/Cargo.toml | 2 +- src/uu/seq/Cargo.toml | 2 +- src/uu/shred/Cargo.toml | 2 +- src/uu/shuf/Cargo.toml | 2 +- src/uu/sleep/Cargo.toml | 2 +- src/uu/sort/Cargo.toml | 2 +- src/uu/split/Cargo.toml | 2 +- src/uu/stat/Cargo.toml | 2 +- src/uu/stdbuf/Cargo.toml | 4 +- src/uu/stdbuf/src/libstdbuf/Cargo.toml | 2 +- src/uu/sum/Cargo.toml | 2 +- src/uu/sync/Cargo.toml | 2 +- src/uu/tac/Cargo.toml | 2 +- src/uu/tail/Cargo.toml | 2 +- src/uu/tee/Cargo.toml | 2 +- src/uu/test/Cargo.toml | 2 +- src/uu/timeout/Cargo.toml | 2 +- src/uu/touch/Cargo.toml | 2 +- src/uu/tr/Cargo.toml | 2 +- src/uu/true/Cargo.toml | 2 +- src/uu/truncate/Cargo.toml | 2 +- src/uu/tsort/Cargo.toml | 2 +- src/uu/tty/Cargo.toml | 2 +- src/uu/uname/Cargo.toml | 2 +- src/uu/unexpand/Cargo.toml | 2 +- src/uu/uniq/Cargo.toml | 2 +- src/uu/unlink/Cargo.toml | 2 +- src/uu/uptime/Cargo.toml | 2 +- src/uu/users/Cargo.toml | 2 +- src/uu/wc/Cargo.toml | 2 +- src/uu/who/Cargo.toml | 2 +- src/uu/whoami/Cargo.toml | 2 +- src/uu/yes/Cargo.toml | 2 +- util/update-version.sh | 8 +- 99 files changed, 294 insertions(+), 294 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c7c165e6..ea1ee53ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,7 +204,7 @@ dependencies = [ [[package]] name = "coreutils" -version = "0.0.5" +version = "0.0.6" dependencies = [ "conv", "filetime", @@ -1545,7 +1545,7 @@ dependencies = [ [[package]] name = "uu_arch" -version = "0.0.5" +version = "0.0.6" dependencies = [ "platform-info", "uucore", @@ -1554,7 +1554,7 @@ dependencies = [ [[package]] name = "uu_base32" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -1562,7 +1562,7 @@ dependencies = [ [[package]] name = "uu_base64" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -1570,7 +1570,7 @@ dependencies = [ [[package]] name = "uu_basename" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -1578,7 +1578,7 @@ dependencies = [ [[package]] name = "uu_cat" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "quick-error", @@ -1589,7 +1589,7 @@ dependencies = [ [[package]] name = "uu_chgrp" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -1598,7 +1598,7 @@ dependencies = [ [[package]] name = "uu_chmod" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -1609,7 +1609,7 @@ dependencies = [ [[package]] name = "uu_chown" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "glob 0.3.0", @@ -1620,7 +1620,7 @@ dependencies = [ [[package]] name = "uu_chroot" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -1629,7 +1629,7 @@ dependencies = [ [[package]] name = "uu_cksum" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -1639,7 +1639,7 @@ dependencies = [ [[package]] name = "uu_comm" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -1649,7 +1649,7 @@ dependencies = [ [[package]] name = "uu_cp" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "filetime", @@ -1665,7 +1665,7 @@ dependencies = [ [[package]] name = "uu_csplit" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "glob 0.2.11", @@ -1677,7 +1677,7 @@ dependencies = [ [[package]] name = "uu_cut" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -1685,7 +1685,7 @@ dependencies = [ [[package]] name = "uu_date" -version = "0.0.5" +version = "0.0.6" dependencies = [ "chrono", "clap", @@ -1697,7 +1697,7 @@ dependencies = [ [[package]] name = "uu_df" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -1709,7 +1709,7 @@ dependencies = [ [[package]] name = "uu_dircolors" -version = "0.0.5" +version = "0.0.6" dependencies = [ "glob 0.3.0", "uucore", @@ -1718,7 +1718,7 @@ dependencies = [ [[package]] name = "uu_dirname" -version = "0.0.5" +version = "0.0.6" dependencies = [ "libc", "uucore", @@ -1727,7 +1727,7 @@ dependencies = [ [[package]] name = "uu_du" -version = "0.0.5" +version = "0.0.6" dependencies = [ "time", "uucore", @@ -1737,7 +1737,7 @@ dependencies = [ [[package]] name = "uu_echo" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -1746,7 +1746,7 @@ dependencies = [ [[package]] name = "uu_env" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -1757,7 +1757,7 @@ dependencies = [ [[package]] name = "uu_expand" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "unicode-width", @@ -1767,7 +1767,7 @@ dependencies = [ [[package]] name = "uu_expr" -version = "0.0.5" +version = "0.0.6" dependencies = [ "libc", "onig", @@ -1777,7 +1777,7 @@ dependencies = [ [[package]] name = "uu_factor" -version = "0.0.5" +version = "0.0.6" dependencies = [ "criterion", "num-traits", @@ -1792,7 +1792,7 @@ dependencies = [ [[package]] name = "uu_false" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -1800,7 +1800,7 @@ dependencies = [ [[package]] name = "uu_fmt" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -1811,7 +1811,7 @@ dependencies = [ [[package]] name = "uu_fold" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -1819,7 +1819,7 @@ dependencies = [ [[package]] name = "uu_groups" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -1828,7 +1828,7 @@ dependencies = [ [[package]] name = "uu_hashsum" -version = "0.0.5" +version = "0.0.6" dependencies = [ "blake2-rfc", "clap", @@ -1847,7 +1847,7 @@ dependencies = [ [[package]] name = "uu_head" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -1856,7 +1856,7 @@ dependencies = [ [[package]] name = "uu_hostid" -version = "0.0.5" +version = "0.0.6" dependencies = [ "libc", "uucore", @@ -1865,7 +1865,7 @@ dependencies = [ [[package]] name = "uu_hostname" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "hostname", @@ -1877,7 +1877,7 @@ dependencies = [ [[package]] name = "uu_id" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -1886,7 +1886,7 @@ dependencies = [ [[package]] name = "uu_install" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "file_diff", @@ -1899,7 +1899,7 @@ dependencies = [ [[package]] name = "uu_join" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -1908,7 +1908,7 @@ dependencies = [ [[package]] name = "uu_kill" -version = "0.0.5" +version = "0.0.6" dependencies = [ "libc", "uucore", @@ -1917,7 +1917,7 @@ dependencies = [ [[package]] name = "uu_link" -version = "0.0.5" +version = "0.0.6" dependencies = [ "libc", "uucore", @@ -1926,7 +1926,7 @@ dependencies = [ [[package]] name = "uu_ln" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -1936,7 +1936,7 @@ dependencies = [ [[package]] name = "uu_logname" -version = "0.0.5" +version = "0.0.6" dependencies = [ "libc", "uucore", @@ -1945,7 +1945,7 @@ dependencies = [ [[package]] name = "uu_ls" -version = "0.0.5" +version = "0.0.6" dependencies = [ "atty", "clap", @@ -1961,7 +1961,7 @@ dependencies = [ [[package]] name = "uu_mkdir" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -1971,7 +1971,7 @@ dependencies = [ [[package]] name = "uu_mkfifo" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -1981,7 +1981,7 @@ dependencies = [ [[package]] name = "uu_mknod" -version = "0.0.5" +version = "0.0.6" dependencies = [ "getopts", "libc", @@ -1991,7 +1991,7 @@ dependencies = [ [[package]] name = "uu_mktemp" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "rand 0.5.6", @@ -2002,7 +2002,7 @@ dependencies = [ [[package]] name = "uu_more" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "nix 0.13.1", @@ -2014,7 +2014,7 @@ dependencies = [ [[package]] name = "uu_mv" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "fs_extra", @@ -2024,7 +2024,7 @@ dependencies = [ [[package]] name = "uu_nice" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2035,7 +2035,7 @@ dependencies = [ [[package]] name = "uu_nl" -version = "0.0.5" +version = "0.0.6" dependencies = [ "aho-corasick", "clap", @@ -2049,7 +2049,7 @@ dependencies = [ [[package]] name = "uu_nohup" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2059,7 +2059,7 @@ dependencies = [ [[package]] name = "uu_nproc" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2070,7 +2070,7 @@ dependencies = [ [[package]] name = "uu_numfmt" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2079,7 +2079,7 @@ dependencies = [ [[package]] name = "uu_od" -version = "0.0.5" +version = "0.0.6" dependencies = [ "byteorder", "clap", @@ -2091,7 +2091,7 @@ dependencies = [ [[package]] name = "uu_paste" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2100,7 +2100,7 @@ dependencies = [ [[package]] name = "uu_pathchk" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2110,7 +2110,7 @@ dependencies = [ [[package]] name = "uu_pinky" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -2118,7 +2118,7 @@ dependencies = [ [[package]] name = "uu_printenv" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2127,7 +2127,7 @@ dependencies = [ [[package]] name = "uu_printf" -version = "0.0.5" +version = "0.0.6" dependencies = [ "itertools 0.8.2", "uucore", @@ -2136,7 +2136,7 @@ dependencies = [ [[package]] name = "uu_ptx" -version = "0.0.5" +version = "0.0.6" dependencies = [ "aho-corasick", "clap", @@ -2150,7 +2150,7 @@ dependencies = [ [[package]] name = "uu_pwd" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2159,7 +2159,7 @@ dependencies = [ [[package]] name = "uu_readlink" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2169,7 +2169,7 @@ dependencies = [ [[package]] name = "uu_realpath" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2178,7 +2178,7 @@ dependencies = [ [[package]] name = "uu_relpath" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2187,7 +2187,7 @@ dependencies = [ [[package]] name = "uu_rm" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "remove_dir_all", @@ -2198,7 +2198,7 @@ dependencies = [ [[package]] name = "uu_rmdir" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2207,7 +2207,7 @@ dependencies = [ [[package]] name = "uu_seq" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2216,7 +2216,7 @@ dependencies = [ [[package]] name = "uu_shred" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "filetime", @@ -2229,7 +2229,7 @@ dependencies = [ [[package]] name = "uu_shuf" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "rand 0.5.6", @@ -2239,7 +2239,7 @@ dependencies = [ [[package]] name = "uu_sleep" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2248,7 +2248,7 @@ dependencies = [ [[package]] name = "uu_sort" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "itertools 0.8.2", @@ -2261,7 +2261,7 @@ dependencies = [ [[package]] name = "uu_split" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2270,7 +2270,7 @@ dependencies = [ [[package]] name = "uu_stat" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "time", @@ -2280,7 +2280,7 @@ dependencies = [ [[package]] name = "uu_stdbuf" -version = "0.0.5" +version = "0.0.6" dependencies = [ "getopts", "tempfile", @@ -2291,7 +2291,7 @@ dependencies = [ [[package]] name = "uu_stdbuf_libstdbuf" -version = "0.0.5" +version = "0.0.6" dependencies = [ "cpp", "cpp_build", @@ -2302,7 +2302,7 @@ dependencies = [ [[package]] name = "uu_sum" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2311,7 +2311,7 @@ dependencies = [ [[package]] name = "uu_sync" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2322,7 +2322,7 @@ dependencies = [ [[package]] name = "uu_tac" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2331,7 +2331,7 @@ dependencies = [ [[package]] name = "uu_tail" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2343,7 +2343,7 @@ dependencies = [ [[package]] name = "uu_tee" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2354,7 +2354,7 @@ dependencies = [ [[package]] name = "uu_test" -version = "0.0.5" +version = "0.0.6" dependencies = [ "libc", "redox_syscall 0.1.57", @@ -2364,7 +2364,7 @@ dependencies = [ [[package]] name = "uu_timeout" -version = "0.0.5" +version = "0.0.6" dependencies = [ "getopts", "libc", @@ -2374,7 +2374,7 @@ dependencies = [ [[package]] name = "uu_touch" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "filetime", @@ -2385,7 +2385,7 @@ dependencies = [ [[package]] name = "uu_tr" -version = "0.0.5" +version = "0.0.6" dependencies = [ "bit-set", "clap", @@ -2396,7 +2396,7 @@ dependencies = [ [[package]] name = "uu_true" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -2404,7 +2404,7 @@ dependencies = [ [[package]] name = "uu_truncate" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2413,7 +2413,7 @@ dependencies = [ [[package]] name = "uu_tsort" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2422,7 +2422,7 @@ dependencies = [ [[package]] name = "uu_tty" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2432,7 +2432,7 @@ dependencies = [ [[package]] name = "uu_uname" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "platform-info", @@ -2442,7 +2442,7 @@ dependencies = [ [[package]] name = "uu_unexpand" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "unicode-width", @@ -2452,7 +2452,7 @@ dependencies = [ [[package]] name = "uu_uniq" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2461,7 +2461,7 @@ dependencies = [ [[package]] name = "uu_unlink" -version = "0.0.5" +version = "0.0.6" dependencies = [ "getopts", "libc", @@ -2471,7 +2471,7 @@ dependencies = [ [[package]] name = "uu_uptime" -version = "0.0.5" +version = "0.0.6" dependencies = [ "chrono", "clap", @@ -2481,7 +2481,7 @@ dependencies = [ [[package]] name = "uu_users" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", @@ -2490,7 +2490,7 @@ dependencies = [ [[package]] name = "uu_wc" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "libc", @@ -2502,7 +2502,7 @@ dependencies = [ [[package]] name = "uu_who" -version = "0.0.5" +version = "0.0.6" dependencies = [ "uucore", "uucore_procs", @@ -2510,7 +2510,7 @@ dependencies = [ [[package]] name = "uu_whoami" -version = "0.0.5" +version = "0.0.6" dependencies = [ "advapi32-sys", "clap", @@ -2521,7 +2521,7 @@ dependencies = [ [[package]] name = "uu_yes" -version = "0.0.5" +version = "0.0.6" dependencies = [ "clap", "uucore", diff --git a/Cargo.toml b/Cargo.toml index 398791ca9..7e3fb9139 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "coreutils" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "coreutils ~ GNU coreutils (updated); implemented as universal (cross-platform) utils, written in Rust" @@ -228,102 +228,102 @@ lazy_static = { version="1.3" } textwrap = { version="=0.11.0", features=["term_size"] } # !maint: [2020-05-10; rivy] unstable crate using undocumented features; pinned currently, will review uucore = { version=">=0.0.8", package="uucore", path="src/uucore" } # * uutils -uu_test = { optional=true, version="0.0.5", package="uu_test", path="src/uu/test" } +uu_test = { optional=true, version="0.0.6", package="uu_test", path="src/uu/test" } # -arch = { optional=true, version="0.0.5", package="uu_arch", path="src/uu/arch" } -base32 = { optional=true, version="0.0.5", package="uu_base32", path="src/uu/base32" } -base64 = { optional=true, version="0.0.5", package="uu_base64", path="src/uu/base64" } -basename = { optional=true, version="0.0.5", package="uu_basename", path="src/uu/basename" } -cat = { optional=true, version="0.0.5", package="uu_cat", path="src/uu/cat" } -chgrp = { optional=true, version="0.0.5", package="uu_chgrp", path="src/uu/chgrp" } -chmod = { optional=true, version="0.0.5", package="uu_chmod", path="src/uu/chmod" } -chown = { optional=true, version="0.0.5", package="uu_chown", path="src/uu/chown" } -chroot = { optional=true, version="0.0.5", package="uu_chroot", path="src/uu/chroot" } -cksum = { optional=true, version="0.0.5", package="uu_cksum", path="src/uu/cksum" } -comm = { optional=true, version="0.0.5", package="uu_comm", path="src/uu/comm" } -cp = { optional=true, version="0.0.5", package="uu_cp", path="src/uu/cp" } -csplit = { optional=true, version="0.0.5", package="uu_csplit", path="src/uu/csplit" } -cut = { optional=true, version="0.0.5", package="uu_cut", path="src/uu/cut" } -date = { optional=true, version="0.0.5", package="uu_date", path="src/uu/date" } -df = { optional=true, version="0.0.5", package="uu_df", path="src/uu/df" } -dircolors= { optional=true, version="0.0.5", package="uu_dircolors", path="src/uu/dircolors" } -dirname = { optional=true, version="0.0.5", package="uu_dirname", path="src/uu/dirname" } -du = { optional=true, version="0.0.5", package="uu_du", path="src/uu/du" } -echo = { optional=true, version="0.0.5", package="uu_echo", path="src/uu/echo" } -env = { optional=true, version="0.0.5", package="uu_env", path="src/uu/env" } -expand = { optional=true, version="0.0.5", package="uu_expand", path="src/uu/expand" } -expr = { optional=true, version="0.0.5", package="uu_expr", path="src/uu/expr" } -factor = { optional=true, version="0.0.5", package="uu_factor", path="src/uu/factor" } -false = { optional=true, version="0.0.5", package="uu_false", path="src/uu/false" } -fmt = { optional=true, version="0.0.5", package="uu_fmt", path="src/uu/fmt" } -fold = { optional=true, version="0.0.5", package="uu_fold", path="src/uu/fold" } -groups = { optional=true, version="0.0.5", package="uu_groups", path="src/uu/groups" } -hashsum = { optional=true, version="0.0.5", package="uu_hashsum", path="src/uu/hashsum" } -head = { optional=true, version="0.0.5", package="uu_head", path="src/uu/head" } -hostid = { optional=true, version="0.0.5", package="uu_hostid", path="src/uu/hostid" } -hostname = { optional=true, version="0.0.5", package="uu_hostname", path="src/uu/hostname" } -id = { optional=true, version="0.0.5", package="uu_id", path="src/uu/id" } -install = { optional=true, version="0.0.5", package="uu_install", path="src/uu/install" } -join = { optional=true, version="0.0.5", package="uu_join", path="src/uu/join" } -kill = { optional=true, version="0.0.5", package="uu_kill", path="src/uu/kill" } -link = { optional=true, version="0.0.5", package="uu_link", path="src/uu/link" } -ln = { optional=true, version="0.0.5", package="uu_ln", path="src/uu/ln" } -ls = { optional=true, version="0.0.5", package="uu_ls", path="src/uu/ls" } -logname = { optional=true, version="0.0.5", package="uu_logname", path="src/uu/logname" } -mkdir = { optional=true, version="0.0.5", package="uu_mkdir", path="src/uu/mkdir" } -mkfifo = { optional=true, version="0.0.5", package="uu_mkfifo", path="src/uu/mkfifo" } -mknod = { optional=true, version="0.0.5", package="uu_mknod", path="src/uu/mknod" } -mktemp = { optional=true, version="0.0.5", package="uu_mktemp", path="src/uu/mktemp" } -more = { optional=true, version="0.0.5", package="uu_more", path="src/uu/more" } -mv = { optional=true, version="0.0.5", package="uu_mv", path="src/uu/mv" } -nice = { optional=true, version="0.0.5", package="uu_nice", path="src/uu/nice" } -nl = { optional=true, version="0.0.5", package="uu_nl", path="src/uu/nl" } -nohup = { optional=true, version="0.0.5", package="uu_nohup", path="src/uu/nohup" } -nproc = { optional=true, version="0.0.5", package="uu_nproc", path="src/uu/nproc" } -numfmt = { optional=true, version="0.0.5", package="uu_numfmt", path="src/uu/numfmt" } -od = { optional=true, version="0.0.5", package="uu_od", path="src/uu/od" } -paste = { optional=true, version="0.0.5", package="uu_paste", path="src/uu/paste" } -pathchk = { optional=true, version="0.0.5", package="uu_pathchk", path="src/uu/pathchk" } -pinky = { optional=true, version="0.0.5", package="uu_pinky", path="src/uu/pinky" } -printenv = { optional=true, version="0.0.5", package="uu_printenv", path="src/uu/printenv" } -printf = { optional=true, version="0.0.5", package="uu_printf", path="src/uu/printf" } -ptx = { optional=true, version="0.0.5", package="uu_ptx", path="src/uu/ptx" } -pwd = { optional=true, version="0.0.5", package="uu_pwd", path="src/uu/pwd" } -readlink = { optional=true, version="0.0.5", package="uu_readlink", path="src/uu/readlink" } -realpath = { optional=true, version="0.0.5", package="uu_realpath", path="src/uu/realpath" } -relpath = { optional=true, version="0.0.5", package="uu_relpath", path="src/uu/relpath" } -rm = { optional=true, version="0.0.5", package="uu_rm", path="src/uu/rm" } -rmdir = { optional=true, version="0.0.5", package="uu_rmdir", path="src/uu/rmdir" } -seq = { optional=true, version="0.0.5", package="uu_seq", path="src/uu/seq" } -shred = { optional=true, version="0.0.5", package="uu_shred", path="src/uu/shred" } -shuf = { optional=true, version="0.0.5", package="uu_shuf", path="src/uu/shuf" } -sleep = { optional=true, version="0.0.5", package="uu_sleep", path="src/uu/sleep" } -sort = { optional=true, version="0.0.5", package="uu_sort", path="src/uu/sort" } -split = { optional=true, version="0.0.5", package="uu_split", path="src/uu/split" } -stat = { optional=true, version="0.0.5", package="uu_stat", path="src/uu/stat" } -stdbuf = { optional=true, version="0.0.5", package="uu_stdbuf", path="src/uu/stdbuf" } -sum = { optional=true, version="0.0.5", package="uu_sum", path="src/uu/sum" } -sync = { optional=true, version="0.0.5", package="uu_sync", path="src/uu/sync" } -tac = { optional=true, version="0.0.5", package="uu_tac", path="src/uu/tac" } -tail = { optional=true, version="0.0.5", package="uu_tail", path="src/uu/tail" } -tee = { optional=true, version="0.0.5", package="uu_tee", path="src/uu/tee" } -timeout = { optional=true, version="0.0.5", package="uu_timeout", path="src/uu/timeout" } -touch = { optional=true, version="0.0.5", package="uu_touch", path="src/uu/touch" } -tr = { optional=true, version="0.0.5", package="uu_tr", path="src/uu/tr" } -true = { optional=true, version="0.0.5", package="uu_true", path="src/uu/true" } -truncate = { optional=true, version="0.0.5", package="uu_truncate", path="src/uu/truncate" } -tsort = { optional=true, version="0.0.5", package="uu_tsort", path="src/uu/tsort" } -tty = { optional=true, version="0.0.5", package="uu_tty", path="src/uu/tty" } -uname = { optional=true, version="0.0.5", package="uu_uname", path="src/uu/uname" } -unexpand = { optional=true, version="0.0.5", package="uu_unexpand", path="src/uu/unexpand" } -uniq = { optional=true, version="0.0.5", package="uu_uniq", path="src/uu/uniq" } -unlink = { optional=true, version="0.0.5", package="uu_unlink", path="src/uu/unlink" } -uptime = { optional=true, version="0.0.5", package="uu_uptime", path="src/uu/uptime" } -users = { optional=true, version="0.0.5", package="uu_users", path="src/uu/users" } -wc = { optional=true, version="0.0.5", package="uu_wc", path="src/uu/wc" } -who = { optional=true, version="0.0.5", package="uu_who", path="src/uu/who" } -whoami = { optional=true, version="0.0.5", package="uu_whoami", path="src/uu/whoami" } -yes = { optional=true, version="0.0.5", package="uu_yes", path="src/uu/yes" } +arch = { optional=true, version="0.0.6", package="uu_arch", path="src/uu/arch" } +base32 = { optional=true, version="0.0.6", package="uu_base32", path="src/uu/base32" } +base64 = { optional=true, version="0.0.6", package="uu_base64", path="src/uu/base64" } +basename = { optional=true, version="0.0.6", package="uu_basename", path="src/uu/basename" } +cat = { optional=true, version="0.0.6", package="uu_cat", path="src/uu/cat" } +chgrp = { optional=true, version="0.0.6", package="uu_chgrp", path="src/uu/chgrp" } +chmod = { optional=true, version="0.0.6", package="uu_chmod", path="src/uu/chmod" } +chown = { optional=true, version="0.0.6", package="uu_chown", path="src/uu/chown" } +chroot = { optional=true, version="0.0.6", package="uu_chroot", path="src/uu/chroot" } +cksum = { optional=true, version="0.0.6", package="uu_cksum", path="src/uu/cksum" } +comm = { optional=true, version="0.0.6", package="uu_comm", path="src/uu/comm" } +cp = { optional=true, version="0.0.6", package="uu_cp", path="src/uu/cp" } +csplit = { optional=true, version="0.0.6", package="uu_csplit", path="src/uu/csplit" } +cut = { optional=true, version="0.0.6", package="uu_cut", path="src/uu/cut" } +date = { optional=true, version="0.0.6", package="uu_date", path="src/uu/date" } +df = { optional=true, version="0.0.6", package="uu_df", path="src/uu/df" } +dircolors= { optional=true, version="0.0.6", package="uu_dircolors", path="src/uu/dircolors" } +dirname = { optional=true, version="0.0.6", package="uu_dirname", path="src/uu/dirname" } +du = { optional=true, version="0.0.6", package="uu_du", path="src/uu/du" } +echo = { optional=true, version="0.0.6", package="uu_echo", path="src/uu/echo" } +env = { optional=true, version="0.0.6", package="uu_env", path="src/uu/env" } +expand = { optional=true, version="0.0.6", package="uu_expand", path="src/uu/expand" } +expr = { optional=true, version="0.0.6", package="uu_expr", path="src/uu/expr" } +factor = { optional=true, version="0.0.6", package="uu_factor", path="src/uu/factor" } +false = { optional=true, version="0.0.6", package="uu_false", path="src/uu/false" } +fmt = { optional=true, version="0.0.6", package="uu_fmt", path="src/uu/fmt" } +fold = { optional=true, version="0.0.6", package="uu_fold", path="src/uu/fold" } +groups = { optional=true, version="0.0.6", package="uu_groups", path="src/uu/groups" } +hashsum = { optional=true, version="0.0.6", package="uu_hashsum", path="src/uu/hashsum" } +head = { optional=true, version="0.0.6", package="uu_head", path="src/uu/head" } +hostid = { optional=true, version="0.0.6", package="uu_hostid", path="src/uu/hostid" } +hostname = { optional=true, version="0.0.6", package="uu_hostname", path="src/uu/hostname" } +id = { optional=true, version="0.0.6", package="uu_id", path="src/uu/id" } +install = { optional=true, version="0.0.6", package="uu_install", path="src/uu/install" } +join = { optional=true, version="0.0.6", package="uu_join", path="src/uu/join" } +kill = { optional=true, version="0.0.6", package="uu_kill", path="src/uu/kill" } +link = { optional=true, version="0.0.6", package="uu_link", path="src/uu/link" } +ln = { optional=true, version="0.0.6", package="uu_ln", path="src/uu/ln" } +ls = { optional=true, version="0.0.6", package="uu_ls", path="src/uu/ls" } +logname = { optional=true, version="0.0.6", package="uu_logname", path="src/uu/logname" } +mkdir = { optional=true, version="0.0.6", package="uu_mkdir", path="src/uu/mkdir" } +mkfifo = { optional=true, version="0.0.6", package="uu_mkfifo", path="src/uu/mkfifo" } +mknod = { optional=true, version="0.0.6", package="uu_mknod", path="src/uu/mknod" } +mktemp = { optional=true, version="0.0.6", package="uu_mktemp", path="src/uu/mktemp" } +more = { optional=true, version="0.0.6", package="uu_more", path="src/uu/more" } +mv = { optional=true, version="0.0.6", package="uu_mv", path="src/uu/mv" } +nice = { optional=true, version="0.0.6", package="uu_nice", path="src/uu/nice" } +nl = { optional=true, version="0.0.6", package="uu_nl", path="src/uu/nl" } +nohup = { optional=true, version="0.0.6", package="uu_nohup", path="src/uu/nohup" } +nproc = { optional=true, version="0.0.6", package="uu_nproc", path="src/uu/nproc" } +numfmt = { optional=true, version="0.0.6", package="uu_numfmt", path="src/uu/numfmt" } +od = { optional=true, version="0.0.6", package="uu_od", path="src/uu/od" } +paste = { optional=true, version="0.0.6", package="uu_paste", path="src/uu/paste" } +pathchk = { optional=true, version="0.0.6", package="uu_pathchk", path="src/uu/pathchk" } +pinky = { optional=true, version="0.0.6", package="uu_pinky", path="src/uu/pinky" } +printenv = { optional=true, version="0.0.6", package="uu_printenv", path="src/uu/printenv" } +printf = { optional=true, version="0.0.6", package="uu_printf", path="src/uu/printf" } +ptx = { optional=true, version="0.0.6", package="uu_ptx", path="src/uu/ptx" } +pwd = { optional=true, version="0.0.6", package="uu_pwd", path="src/uu/pwd" } +readlink = { optional=true, version="0.0.6", package="uu_readlink", path="src/uu/readlink" } +realpath = { optional=true, version="0.0.6", package="uu_realpath", path="src/uu/realpath" } +relpath = { optional=true, version="0.0.6", package="uu_relpath", path="src/uu/relpath" } +rm = { optional=true, version="0.0.6", package="uu_rm", path="src/uu/rm" } +rmdir = { optional=true, version="0.0.6", package="uu_rmdir", path="src/uu/rmdir" } +seq = { optional=true, version="0.0.6", package="uu_seq", path="src/uu/seq" } +shred = { optional=true, version="0.0.6", package="uu_shred", path="src/uu/shred" } +shuf = { optional=true, version="0.0.6", package="uu_shuf", path="src/uu/shuf" } +sleep = { optional=true, version="0.0.6", package="uu_sleep", path="src/uu/sleep" } +sort = { optional=true, version="0.0.6", package="uu_sort", path="src/uu/sort" } +split = { optional=true, version="0.0.6", package="uu_split", path="src/uu/split" } +stat = { optional=true, version="0.0.6", package="uu_stat", path="src/uu/stat" } +stdbuf = { optional=true, version="0.0.6", package="uu_stdbuf", path="src/uu/stdbuf" } +sum = { optional=true, version="0.0.6", package="uu_sum", path="src/uu/sum" } +sync = { optional=true, version="0.0.6", package="uu_sync", path="src/uu/sync" } +tac = { optional=true, version="0.0.6", package="uu_tac", path="src/uu/tac" } +tail = { optional=true, version="0.0.6", package="uu_tail", path="src/uu/tail" } +tee = { optional=true, version="0.0.6", package="uu_tee", path="src/uu/tee" } +timeout = { optional=true, version="0.0.6", package="uu_timeout", path="src/uu/timeout" } +touch = { optional=true, version="0.0.6", package="uu_touch", path="src/uu/touch" } +tr = { optional=true, version="0.0.6", package="uu_tr", path="src/uu/tr" } +true = { optional=true, version="0.0.6", package="uu_true", path="src/uu/true" } +truncate = { optional=true, version="0.0.6", package="uu_truncate", path="src/uu/truncate" } +tsort = { optional=true, version="0.0.6", package="uu_tsort", path="src/uu/tsort" } +tty = { optional=true, version="0.0.6", package="uu_tty", path="src/uu/tty" } +uname = { optional=true, version="0.0.6", package="uu_uname", path="src/uu/uname" } +unexpand = { optional=true, version="0.0.6", package="uu_unexpand", path="src/uu/unexpand" } +uniq = { optional=true, version="0.0.6", package="uu_uniq", path="src/uu/uniq" } +unlink = { optional=true, version="0.0.6", package="uu_unlink", path="src/uu/unlink" } +uptime = { optional=true, version="0.0.6", package="uu_uptime", path="src/uu/uptime" } +users = { optional=true, version="0.0.6", package="uu_users", path="src/uu/users" } +wc = { optional=true, version="0.0.6", package="uu_wc", path="src/uu/wc" } +who = { optional=true, version="0.0.6", package="uu_who", path="src/uu/who" } +whoami = { optional=true, version="0.0.6", package="uu_whoami", path="src/uu/whoami" } +yes = { optional=true, version="0.0.6", package="uu_yes", path="src/uu/yes" } # # * pinned transitive dependencies # Not needed for now. Keep as examples: diff --git a/src/uu/arch/Cargo.toml b/src/uu/arch/Cargo.toml index e23067788..0b4359620 100644 --- a/src/uu/arch/Cargo.toml +++ b/src/uu/arch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_arch" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "arch ~ (uutils) display machine architecture" diff --git a/src/uu/base32/Cargo.toml b/src/uu/base32/Cargo.toml index d4415dd8c..a1d7ba17e 100644 --- a/src/uu/base32/Cargo.toml +++ b/src/uu/base32/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_base32" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "base32 ~ (uutils) decode/encode input (base32-encoding)" diff --git a/src/uu/base64/Cargo.toml b/src/uu/base64/Cargo.toml index e893caf3a..841ab140c 100644 --- a/src/uu/base64/Cargo.toml +++ b/src/uu/base64/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_base64" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "base64 ~ (uutils) decode/encode input (base64-encoding)" diff --git a/src/uu/basename/Cargo.toml b/src/uu/basename/Cargo.toml index 681ccf1c4..92d0ca4cd 100644 --- a/src/uu/basename/Cargo.toml +++ b/src/uu/basename/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_basename" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "basename ~ (uutils) display PATHNAME with leading directory components removed" diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index 2176a5e0b..e44a874c1 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cat" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "cat ~ (uutils) concatenate and display input" diff --git a/src/uu/chgrp/Cargo.toml b/src/uu/chgrp/Cargo.toml index 2cefca4d8..9424ad35e 100644 --- a/src/uu/chgrp/Cargo.toml +++ b/src/uu/chgrp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chgrp" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "chgrp ~ (uutils) change the group ownership of FILE" diff --git a/src/uu/chmod/Cargo.toml b/src/uu/chmod/Cargo.toml index 71ded6d90..ac7030b62 100644 --- a/src/uu/chmod/Cargo.toml +++ b/src/uu/chmod/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chmod" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "chmod ~ (uutils) change mode of FILE" diff --git a/src/uu/chown/Cargo.toml b/src/uu/chown/Cargo.toml index 27a30da17..74533af04 100644 --- a/src/uu/chown/Cargo.toml +++ b/src/uu/chown/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chown" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "chown ~ (uutils) change the ownership of FILE" diff --git a/src/uu/chroot/Cargo.toml b/src/uu/chroot/Cargo.toml index 51fb9541d..bf1e0ef59 100644 --- a/src/uu/chroot/Cargo.toml +++ b/src/uu/chroot/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chroot" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "chroot ~ (uutils) run COMMAND under a new root directory" diff --git a/src/uu/cksum/Cargo.toml b/src/uu/cksum/Cargo.toml index 2f589e877..0332efbf8 100644 --- a/src/uu/cksum/Cargo.toml +++ b/src/uu/cksum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cksum" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "cksum ~ (uutils) display CRC and size of input" diff --git a/src/uu/comm/Cargo.toml b/src/uu/comm/Cargo.toml index 9babe82ea..f02217790 100644 --- a/src/uu/comm/Cargo.toml +++ b/src/uu/comm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_comm" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "comm ~ (uutils) compare sorted inputs" diff --git a/src/uu/cp/Cargo.toml b/src/uu/cp/Cargo.toml index 53d27137f..9d582adae 100644 --- a/src/uu/cp/Cargo.toml +++ b/src/uu/cp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cp" -version = "0.0.5" +version = "0.0.6" authors = [ "Jordy Dickinson ", "Joshua S. Miller ", diff --git a/src/uu/csplit/Cargo.toml b/src/uu/csplit/Cargo.toml index a5eac1a02..7687991b0 100644 --- a/src/uu/csplit/Cargo.toml +++ b/src/uu/csplit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_csplit" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "csplit ~ (uutils) Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output" diff --git a/src/uu/cut/Cargo.toml b/src/uu/cut/Cargo.toml index 10a282ecf..9cc852d2e 100644 --- a/src/uu/cut/Cargo.toml +++ b/src/uu/cut/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cut" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "cut ~ (uutils) display byte/field columns of input lines" diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index cacf29ff0..db6c077bd 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_date" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "date ~ (uutils) display or set the current time" diff --git a/src/uu/df/Cargo.toml b/src/uu/df/Cargo.toml index 049422ce5..4770cb557 100644 --- a/src/uu/df/Cargo.toml +++ b/src/uu/df/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_df" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "df ~ (uutils) display file system information" diff --git a/src/uu/dircolors/Cargo.toml b/src/uu/dircolors/Cargo.toml index 9ed55d20d..5e822820e 100644 --- a/src/uu/dircolors/Cargo.toml +++ b/src/uu/dircolors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dircolors" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "dircolors ~ (uutils) display commands to set LS_COLORS" diff --git a/src/uu/dirname/Cargo.toml b/src/uu/dirname/Cargo.toml index 575aefd51..d3cd185e7 100644 --- a/src/uu/dirname/Cargo.toml +++ b/src/uu/dirname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dirname" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "dirname ~ (uutils) display parent directory of PATHNAME" diff --git a/src/uu/du/Cargo.toml b/src/uu/du/Cargo.toml index 01045f887..eb7b23f8b 100644 --- a/src/uu/du/Cargo.toml +++ b/src/uu/du/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_du" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "du ~ (uutils) display disk usage" diff --git a/src/uu/echo/Cargo.toml b/src/uu/echo/Cargo.toml index 2ac09cd39..15f189030 100644 --- a/src/uu/echo/Cargo.toml +++ b/src/uu/echo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_echo" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "echo ~ (uutils) display TEXT" diff --git a/src/uu/env/Cargo.toml b/src/uu/env/Cargo.toml index fc5317184..ef0017e02 100644 --- a/src/uu/env/Cargo.toml +++ b/src/uu/env/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_env" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "env ~ (uutils) set each NAME to VALUE in the environment and run COMMAND" diff --git a/src/uu/expand/Cargo.toml b/src/uu/expand/Cargo.toml index 09575254a..4931cf53c 100644 --- a/src/uu/expand/Cargo.toml +++ b/src/uu/expand/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_expand" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "expand ~ (uutils) convert input tabs to spaces" diff --git a/src/uu/expr/Cargo.toml b/src/uu/expr/Cargo.toml index 7e38103aa..c535df7ce 100644 --- a/src/uu/expr/Cargo.toml +++ b/src/uu/expr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_expr" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "expr ~ (uutils) display the value of EXPRESSION" diff --git a/src/uu/factor/Cargo.toml b/src/uu/factor/Cargo.toml index 1d415a951..489c713be 100644 --- a/src/uu/factor/Cargo.toml +++ b/src/uu/factor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_factor" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "factor ~ (uutils) display the prime factors of each NUMBER" diff --git a/src/uu/false/Cargo.toml b/src/uu/false/Cargo.toml index 5651888d7..d7cbcd13a 100644 --- a/src/uu/false/Cargo.toml +++ b/src/uu/false/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_false" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "false ~ (uutils) do nothing and fail" diff --git a/src/uu/fmt/Cargo.toml b/src/uu/fmt/Cargo.toml index 688967a5a..24ee13b35 100644 --- a/src/uu/fmt/Cargo.toml +++ b/src/uu/fmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_fmt" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "fmt ~ (uutils) reformat each paragraph of input" diff --git a/src/uu/fold/Cargo.toml b/src/uu/fold/Cargo.toml index de1aa2dd5..f99abc691 100644 --- a/src/uu/fold/Cargo.toml +++ b/src/uu/fold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_fold" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "fold ~ (uutils) wrap each line of input" diff --git a/src/uu/groups/Cargo.toml b/src/uu/groups/Cargo.toml index d005599de..1a56bc2ab 100644 --- a/src/uu/groups/Cargo.toml +++ b/src/uu/groups/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_groups" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "groups ~ (uutils) display group memberships for USERNAME" diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml index b08b853ef..04a22cac7 100644 --- a/src/uu/hashsum/Cargo.toml +++ b/src/uu/hashsum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hashsum" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "hashsum ~ (uutils) display or check input digests" diff --git a/src/uu/head/Cargo.toml b/src/uu/head/Cargo.toml index 2f5d97d62..3c383cb6f 100644 --- a/src/uu/head/Cargo.toml +++ b/src/uu/head/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_head" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "head ~ (uutils) display the first lines of input" diff --git a/src/uu/hostid/Cargo.toml b/src/uu/hostid/Cargo.toml index e872aff06..ab6954104 100644 --- a/src/uu/hostid/Cargo.toml +++ b/src/uu/hostid/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hostid" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "hostid ~ (uutils) display the numeric identifier of the current host" diff --git a/src/uu/hostname/Cargo.toml b/src/uu/hostname/Cargo.toml index bc4b10951..fb1d00682 100644 --- a/src/uu/hostname/Cargo.toml +++ b/src/uu/hostname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hostname" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "hostname ~ (uutils) display or set the host name of the current host" diff --git a/src/uu/id/Cargo.toml b/src/uu/id/Cargo.toml index 6edb1d606..308d6089d 100644 --- a/src/uu/id/Cargo.toml +++ b/src/uu/id/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_id" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "id ~ (uutils) display user and group information for USER" diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index 16f78bb7b..91463199a 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_install" -version = "0.0.5" +version = "0.0.6" authors = [ "Ben Eills ", "uutils developers", diff --git a/src/uu/join/Cargo.toml b/src/uu/join/Cargo.toml index 5b18603ab..9371b7601 100644 --- a/src/uu/join/Cargo.toml +++ b/src/uu/join/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_join" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "join ~ (uutils) merge lines from inputs with matching join fields" diff --git a/src/uu/kill/Cargo.toml b/src/uu/kill/Cargo.toml index 16a34de69..6b66806bc 100644 --- a/src/uu/kill/Cargo.toml +++ b/src/uu/kill/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_kill" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "kill ~ (uutils) send a signal to a process" diff --git a/src/uu/link/Cargo.toml b/src/uu/link/Cargo.toml index 9c15d8682..13c3453cf 100644 --- a/src/uu/link/Cargo.toml +++ b/src/uu/link/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_link" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "link ~ (uutils) create a hard (file system) link to FILE" diff --git a/src/uu/ln/Cargo.toml b/src/uu/ln/Cargo.toml index 2d7f39005..c19d8fb52 100644 --- a/src/uu/ln/Cargo.toml +++ b/src/uu/ln/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ln" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "ln ~ (uutils) create a (file system) link to TARGET" diff --git a/src/uu/logname/Cargo.toml b/src/uu/logname/Cargo.toml index 896fd5eb7..416f817d7 100644 --- a/src/uu/logname/Cargo.toml +++ b/src/uu/logname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_logname" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "logname ~ (uutils) display the login name of the current user" diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index b1d44e485..e1d9b7990 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ls" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "ls ~ (uutils) display directory contents" diff --git a/src/uu/mkdir/Cargo.toml b/src/uu/mkdir/Cargo.toml index 44a7eb18b..a8d374bf9 100644 --- a/src/uu/mkdir/Cargo.toml +++ b/src/uu/mkdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mkdir" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "mkdir ~ (uutils) create DIRECTORY" diff --git a/src/uu/mkfifo/Cargo.toml b/src/uu/mkfifo/Cargo.toml index 8ff6694d6..d66003b10 100644 --- a/src/uu/mkfifo/Cargo.toml +++ b/src/uu/mkfifo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mkfifo" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "mkfifo ~ (uutils) create FIFOs (named pipes)" diff --git a/src/uu/mknod/Cargo.toml b/src/uu/mknod/Cargo.toml index 9badb5f13..2c3ac8fb9 100644 --- a/src/uu/mknod/Cargo.toml +++ b/src/uu/mknod/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mknod" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "mknod ~ (uutils) create special file NAME of TYPE" diff --git a/src/uu/mktemp/Cargo.toml b/src/uu/mktemp/Cargo.toml index 13685a586..c669f0acc 100644 --- a/src/uu/mktemp/Cargo.toml +++ b/src/uu/mktemp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mktemp" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "mktemp ~ (uutils) create and display a temporary file or directory from TEMPLATE" diff --git a/src/uu/more/Cargo.toml b/src/uu/more/Cargo.toml index c910d08b0..1f4bfed68 100644 --- a/src/uu/more/Cargo.toml +++ b/src/uu/more/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_more" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "more ~ (uutils) input perusal filter" diff --git a/src/uu/mv/Cargo.toml b/src/uu/mv/Cargo.toml index f84a68c3c..8f1e7b9ee 100644 --- a/src/uu/mv/Cargo.toml +++ b/src/uu/mv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mv" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "mv ~ (uutils) move (rename) SOURCE to DESTINATION" diff --git a/src/uu/nice/Cargo.toml b/src/uu/nice/Cargo.toml index 2106b2d24..279e79ae3 100644 --- a/src/uu/nice/Cargo.toml +++ b/src/uu/nice/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nice" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "nice ~ (uutils) run PROGRAM with modified scheduling priority" diff --git a/src/uu/nl/Cargo.toml b/src/uu/nl/Cargo.toml index f64182475..a51a2555e 100644 --- a/src/uu/nl/Cargo.toml +++ b/src/uu/nl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nl" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "nl ~ (uutils) display input with added line numbers" diff --git a/src/uu/nohup/Cargo.toml b/src/uu/nohup/Cargo.toml index 604e1e9da..5bbbd9dff 100644 --- a/src/uu/nohup/Cargo.toml +++ b/src/uu/nohup/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nohup" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "nohup ~ (uutils) run COMMAND, ignoring hangup signals" diff --git a/src/uu/nproc/Cargo.toml b/src/uu/nproc/Cargo.toml index 2541c5a3e..be9d8f2e3 100644 --- a/src/uu/nproc/Cargo.toml +++ b/src/uu/nproc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nproc" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "nproc ~ (uutils) display the number of processing units available" diff --git a/src/uu/numfmt/Cargo.toml b/src/uu/numfmt/Cargo.toml index bde97cacb..ac5266d68 100644 --- a/src/uu/numfmt/Cargo.toml +++ b/src/uu/numfmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_numfmt" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "numfmt ~ (uutils) reformat NUMBER" diff --git a/src/uu/od/Cargo.toml b/src/uu/od/Cargo.toml index a939c6ee4..6f9a75318 100644 --- a/src/uu/od/Cargo.toml +++ b/src/uu/od/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_od" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "od ~ (uutils) display formatted representation of input" diff --git a/src/uu/paste/Cargo.toml b/src/uu/paste/Cargo.toml index 2ac2074ed..4e9971368 100644 --- a/src/uu/paste/Cargo.toml +++ b/src/uu/paste/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_paste" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "paste ~ (uutils) merge lines from inputs" diff --git a/src/uu/pathchk/Cargo.toml b/src/uu/pathchk/Cargo.toml index 63d00daac..8c4e61d2b 100644 --- a/src/uu/pathchk/Cargo.toml +++ b/src/uu/pathchk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pathchk" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "pathchk ~ (uutils) diagnose invalid or non-portable PATHNAME" diff --git a/src/uu/pinky/Cargo.toml b/src/uu/pinky/Cargo.toml index 96fb32e74..3f4a75241 100644 --- a/src/uu/pinky/Cargo.toml +++ b/src/uu/pinky/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pinky" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "pinky ~ (uutils) display user information" diff --git a/src/uu/printenv/Cargo.toml b/src/uu/printenv/Cargo.toml index f81240d77..be95b8157 100644 --- a/src/uu/printenv/Cargo.toml +++ b/src/uu/printenv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_printenv" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "printenv ~ (uutils) display value of environment VAR" diff --git a/src/uu/printf/Cargo.toml b/src/uu/printf/Cargo.toml index 7f54decb5..bc77d31be 100644 --- a/src/uu/printf/Cargo.toml +++ b/src/uu/printf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_printf" -version = "0.0.5" +version = "0.0.6" authors = [ "Nathan Ross", "uutils developers", diff --git a/src/uu/ptx/Cargo.toml b/src/uu/ptx/Cargo.toml index 889b4fafa..eb4413cbd 100644 --- a/src/uu/ptx/Cargo.toml +++ b/src/uu/ptx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ptx" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "ptx ~ (uutils) display a permuted index of input" diff --git a/src/uu/pwd/Cargo.toml b/src/uu/pwd/Cargo.toml index 43ddeac2e..f4350d54c 100644 --- a/src/uu/pwd/Cargo.toml +++ b/src/uu/pwd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pwd" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "pwd ~ (uutils) display current working directory" diff --git a/src/uu/readlink/Cargo.toml b/src/uu/readlink/Cargo.toml index 5d69125ce..6e4be4dd8 100644 --- a/src/uu/readlink/Cargo.toml +++ b/src/uu/readlink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_readlink" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "readlink ~ (uutils) display resolved path of PATHNAME" diff --git a/src/uu/realpath/Cargo.toml b/src/uu/realpath/Cargo.toml index bd25d9980..327a875f8 100644 --- a/src/uu/realpath/Cargo.toml +++ b/src/uu/realpath/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_realpath" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "realpath ~ (uutils) display resolved absolute path of PATHNAME" diff --git a/src/uu/relpath/Cargo.toml b/src/uu/relpath/Cargo.toml index 34d3dd067..7a316c29c 100644 --- a/src/uu/relpath/Cargo.toml +++ b/src/uu/relpath/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_relpath" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "relpath ~ (uutils) display relative path of PATHNAME_TO from PATHNAME_FROM" diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index bd3415faf..961a8036c 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_rm" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "rm ~ (uutils) remove PATHNAME" diff --git a/src/uu/rmdir/Cargo.toml b/src/uu/rmdir/Cargo.toml index cfd8dd6b0..b6e04f71c 100644 --- a/src/uu/rmdir/Cargo.toml +++ b/src/uu/rmdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_rmdir" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "rmdir ~ (uutils) remove empty DIRECTORY" diff --git a/src/uu/seq/Cargo.toml b/src/uu/seq/Cargo.toml index 2e98a0bb8..96c629c68 100644 --- a/src/uu/seq/Cargo.toml +++ b/src/uu/seq/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_seq" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "seq ~ (uutils) display a sequence of numbers" diff --git a/src/uu/shred/Cargo.toml b/src/uu/shred/Cargo.toml index 6157f3780..dda68b45b 100644 --- a/src/uu/shred/Cargo.toml +++ b/src/uu/shred/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_shred" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "shred ~ (uutils) hide former FILE contents with repeated overwrites" diff --git a/src/uu/shuf/Cargo.toml b/src/uu/shuf/Cargo.toml index 7f911c156..dbf559454 100644 --- a/src/uu/shuf/Cargo.toml +++ b/src/uu/shuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_shuf" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "shuf ~ (uutils) display random permutations of input lines" diff --git a/src/uu/sleep/Cargo.toml b/src/uu/sleep/Cargo.toml index 8ff8505e1..fe7ee2941 100644 --- a/src/uu/sleep/Cargo.toml +++ b/src/uu/sleep/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sleep" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "sleep ~ (uutils) pause for DURATION" diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index e805d4fa2..7a6f95c41 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sort" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "sort ~ (uutils) sort input lines" diff --git a/src/uu/split/Cargo.toml b/src/uu/split/Cargo.toml index 6032c6351..056fbe034 100644 --- a/src/uu/split/Cargo.toml +++ b/src/uu/split/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_split" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "split ~ (uutils) split input into output files" diff --git a/src/uu/stat/Cargo.toml b/src/uu/stat/Cargo.toml index bf19f95b7..96bf63ffe 100644 --- a/src/uu/stat/Cargo.toml +++ b/src/uu/stat/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stat" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "stat ~ (uutils) display FILE status" diff --git a/src/uu/stdbuf/Cargo.toml b/src/uu/stdbuf/Cargo.toml index 3fde13f72..22ce4de6a 100644 --- a/src/uu/stdbuf/Cargo.toml +++ b/src/uu/stdbuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stdbuf" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "stdbuf ~ (uutils) run COMMAND with modified standard stream buffering" @@ -21,7 +21,7 @@ uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [build-dependencies] -libstdbuf = { version="0.0.5", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } +libstdbuf = { version="0.0.6", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } [[bin]] name = "stdbuf" diff --git a/src/uu/stdbuf/src/libstdbuf/Cargo.toml b/src/uu/stdbuf/src/libstdbuf/Cargo.toml index ba6e5ff42..86eb09d46 100644 --- a/src/uu/stdbuf/src/libstdbuf/Cargo.toml +++ b/src/uu/stdbuf/src/libstdbuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stdbuf_libstdbuf" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "stdbuf/libstdbuf ~ (uutils); dynamic library required for stdbuf" diff --git a/src/uu/sum/Cargo.toml b/src/uu/sum/Cargo.toml index b5a6d5d91..64b6d3de9 100644 --- a/src/uu/sum/Cargo.toml +++ b/src/uu/sum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sum" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "sum ~ (uutils) display checksum and block counts for input" diff --git a/src/uu/sync/Cargo.toml b/src/uu/sync/Cargo.toml index 39c49736a..fcff6002e 100644 --- a/src/uu/sync/Cargo.toml +++ b/src/uu/sync/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sync" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "sync ~ (uutils) synchronize cache writes to storage" diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index 18e9fa430..3a530d0ce 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tac" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "tac ~ (uutils) concatenate and display input lines in reverse order" diff --git a/src/uu/tail/Cargo.toml b/src/uu/tail/Cargo.toml index 715a214e2..d3f60e09b 100644 --- a/src/uu/tail/Cargo.toml +++ b/src/uu/tail/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tail" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "tail ~ (uutils) display the last lines of input" diff --git a/src/uu/tee/Cargo.toml b/src/uu/tee/Cargo.toml index c1841ce0f..7ac81adc4 100644 --- a/src/uu/tee/Cargo.toml +++ b/src/uu/tee/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tee" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "tee ~ (uutils) display input and copy to FILE" diff --git a/src/uu/test/Cargo.toml b/src/uu/test/Cargo.toml index c03b84ab4..e1f6e62e7 100644 --- a/src/uu/test/Cargo.toml +++ b/src/uu/test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_test" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "test ~ (uutils) evaluate comparison and file type expressions" diff --git a/src/uu/timeout/Cargo.toml b/src/uu/timeout/Cargo.toml index c32547559..51ac0bc0e 100644 --- a/src/uu/timeout/Cargo.toml +++ b/src/uu/timeout/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_timeout" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "timeout ~ (uutils) run COMMAND with a DURATION time limit" diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index 6fa84cbdd..0608a7b7c 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_touch" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "touch ~ (uutils) change FILE timestamps" diff --git a/src/uu/tr/Cargo.toml b/src/uu/tr/Cargo.toml index 04c013659..a3d066bfb 100644 --- a/src/uu/tr/Cargo.toml +++ b/src/uu/tr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tr" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "tr ~ (uutils) translate characters within input and display" diff --git a/src/uu/true/Cargo.toml b/src/uu/true/Cargo.toml index 780288155..9f13318fd 100644 --- a/src/uu/true/Cargo.toml +++ b/src/uu/true/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_true" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "true ~ (uutils) do nothing and succeed" diff --git a/src/uu/truncate/Cargo.toml b/src/uu/truncate/Cargo.toml index 19f0d2736..e2c0afadc 100644 --- a/src/uu/truncate/Cargo.toml +++ b/src/uu/truncate/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_truncate" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "truncate ~ (uutils) truncate (or extend) FILE to SIZE" diff --git a/src/uu/tsort/Cargo.toml b/src/uu/tsort/Cargo.toml index 3f3d20170..37f543012 100644 --- a/src/uu/tsort/Cargo.toml +++ b/src/uu/tsort/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tsort" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "tsort ~ (uutils) topologically sort input (partially ordered) pairs" diff --git a/src/uu/tty/Cargo.toml b/src/uu/tty/Cargo.toml index d2c5110b5..7be27a900 100644 --- a/src/uu/tty/Cargo.toml +++ b/src/uu/tty/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tty" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "tty ~ (uutils) display the name of the terminal connected to standard input" diff --git a/src/uu/uname/Cargo.toml b/src/uu/uname/Cargo.toml index a0461e33f..9707d8444 100644 --- a/src/uu/uname/Cargo.toml +++ b/src/uu/uname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uname" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "uname ~ (uutils) display system information" diff --git a/src/uu/unexpand/Cargo.toml b/src/uu/unexpand/Cargo.toml index 6d1cad613..e39dd87ca 100644 --- a/src/uu/unexpand/Cargo.toml +++ b/src/uu/unexpand/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_unexpand" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "unexpand ~ (uutils) convert input spaces to tabs" diff --git a/src/uu/uniq/Cargo.toml b/src/uu/uniq/Cargo.toml index 53c2281c4..8c63455ec 100644 --- a/src/uu/uniq/Cargo.toml +++ b/src/uu/uniq/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uniq" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "uniq ~ (uutils) filter identical adjacent lines from input" diff --git a/src/uu/unlink/Cargo.toml b/src/uu/unlink/Cargo.toml index ea18e2cbb..b193bd1b5 100644 --- a/src/uu/unlink/Cargo.toml +++ b/src/uu/unlink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_unlink" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "unlink ~ (uutils) remove a (file system) link to FILE" diff --git a/src/uu/uptime/Cargo.toml b/src/uu/uptime/Cargo.toml index 823879954..1136e6420 100644 --- a/src/uu/uptime/Cargo.toml +++ b/src/uu/uptime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uptime" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "uptime ~ (uutils) display dynamic system information" diff --git a/src/uu/users/Cargo.toml b/src/uu/users/Cargo.toml index 087272a59..84da13020 100644 --- a/src/uu/users/Cargo.toml +++ b/src/uu/users/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_users" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "users ~ (uutils) display names of currently logged-in users" diff --git a/src/uu/wc/Cargo.toml b/src/uu/wc/Cargo.toml index 3f44c1273..8ae79dc08 100644 --- a/src/uu/wc/Cargo.toml +++ b/src/uu/wc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_wc" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "wc ~ (uutils) display newline, word, and byte counts for input" diff --git a/src/uu/who/Cargo.toml b/src/uu/who/Cargo.toml index 928136b10..c0cd63795 100644 --- a/src/uu/who/Cargo.toml +++ b/src/uu/who/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_who" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "who ~ (uutils) display information about currently logged-in users" diff --git a/src/uu/whoami/Cargo.toml b/src/uu/whoami/Cargo.toml index e843b2167..f8dc01440 100644 --- a/src/uu/whoami/Cargo.toml +++ b/src/uu/whoami/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_whoami" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "whoami ~ (uutils) display user name of current effective user ID" diff --git a/src/uu/yes/Cargo.toml b/src/uu/yes/Cargo.toml index ab8a6faff..4a843ddd8 100644 --- a/src/uu/yes/Cargo.toml +++ b/src/uu/yes/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_yes" -version = "0.0.5" +version = "0.0.6" authors = ["uutils developers"] license = "MIT" description = "yes ~ (uutils) repeatedly display a line with STRING (or 'y')" diff --git a/util/update-version.sh b/util/update-version.sh index f5b66fb8c..042d43b71 100644 --- a/util/update-version.sh +++ b/util/update-version.sh @@ -3,8 +3,8 @@ # So, it should be triple-checked -FROM="0.0.4" -TO="0.0.5" +FROM="0.0.5" +TO="0.0.6" UUCORE_FROM="0.0.7" UUCORE_TO="0.0.8" @@ -19,8 +19,8 @@ sed -i -e "s|libstdbuf = { version=\"$FROM\"|libstdbuf = { version=\"$TO\"|" src sed -i -e "s|= { optional=true, version=\"$FROM\", package=\"uu_|= { optional=true, version=\"$TO\", package=\"uu_|g" Cargo.toml # Update uucore itself -sed -i -e "s|version = \"$UUCORE_FROM\"|version = \"$UUCORE_TO\"|" src/uucore/Cargo.toml +#sed -i -e "s|version = \"$UUCORE_FROM\"|version = \"$UUCORE_TO\"|" src/uucore/Cargo.toml # Update crates using uucore -sed -i -e "s|uucore = { version=\">=$UUCORE_FROM\",|uucore = { version=\">=$UUCORE_TO\",|" $PROGS +#sed -i -e "s|uucore = { version=\">=$UUCORE_FROM\",|uucore = { version=\">=$UUCORE_TO\",|" $PROGS From 54e9cb09dac17cdabd9d254c1dfade833d628f1c Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Sat, 3 Apr 2021 16:42:29 +0200 Subject: [PATCH 085/132] ls: add tests for --hide-control-chars --- tests/by-util/test_ls.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index b49620eb1..835a40a5e 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1162,6 +1162,24 @@ fn test_ls_quoting_style() { assert_eq!(result.stdout, format!("{}\n", correct)); } + for (arg, correct) in &[ + ("--quoting-style=literal", "one?two"), + ("-N", "one?two"), + ("--literal", "one?two"), + ("--quoting-style=shell", "one?two"), + ("--quoting-style=shell-always", "'one?two'"), + ] { + let result = scene + .ucmd() + .arg(arg) + .arg("--hide-control-chars") + .arg("one\ntwo") + .run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert_eq!(result.stdout, format!("{}\n", correct)); + } + for (arg, correct) in &[ ("--quoting-style=literal", "one\ntwo"), ("-N", "one\ntwo"), From b940b2d79c606baf027570d5d4b316ecfb9686f3 Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci Date: Sat, 3 Apr 2021 18:24:29 +0300 Subject: [PATCH 086/132] dirname: move to clap, simplify code --- Cargo.lock | 1 + src/uu/dirname/Cargo.toml | 1 + src/uu/dirname/src/dirname.rs | 40 ++++++++++++++++++++++++++++------- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea1ee53ae..47fa76428 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1720,6 +1720,7 @@ dependencies = [ name = "uu_dirname" version = "0.0.6" dependencies = [ + "clap", "libc", "uucore", "uucore_procs", diff --git a/src/uu/dirname/Cargo.toml b/src/uu/dirname/Cargo.toml index d3cd185e7..0975f33bb 100644 --- a/src/uu/dirname/Cargo.toml +++ b/src/uu/dirname/Cargo.toml @@ -15,6 +15,7 @@ edition = "2018" path = "src/dirname.rs" [dependencies] +clap = "2.33" libc = "0.2.42" uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/dirname/src/dirname.rs b/src/uu/dirname/src/dirname.rs index 59f47ff01..1cf35d0c4 100644 --- a/src/uu/dirname/src/dirname.rs +++ b/src/uu/dirname/src/dirname.rs @@ -8,32 +8,57 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::path::Path; static NAME: &str = "dirname"; static SYNTAX: &str = "[OPTION] NAME..."; static SUMMARY: &str = "strip last component from file name"; +static VERSION: &str = env!("CARGO_PKG_VERSION"); static LONG_HELP: &str = " Output each NAME with its last non-slash component and trailing slashes removed; if NAME contains no /'s, output '.' (meaning the current directory). "; +mod options { + pub const ZERO: &str = "zero"; + pub const DIR: &str = "dir"; +} + pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); - let matches = app!(SYNTAX, SUMMARY, LONG_HELP) - .optflag("z", "zero", "separate output with NUL rather than newline") - .parse(args); + let matches = App::new(executable!()) + .name(NAME) + .usage(SYNTAX) + .about(SUMMARY) + .after_help(LONG_HELP) + .version(VERSION) + .arg( + Arg::with_name(options::ZERO) + .short(options::ZERO) + .short("z") + .takes_value(false) + .help("separate output with NUL rather than newline"), + ) + .arg(Arg::with_name(options::DIR).hidden(true).multiple(true)) + .get_matches_from(args); - let separator = if matches.opt_present("zero") { + let separator = if matches.is_present(options::ZERO) { "\0" } else { "\n" }; - if !matches.free.is_empty() { - for path in &matches.free { + let dirnames: Vec = matches + .values_of(options::DIR) + .unwrap_or_default() + .map(str::to_owned) + .collect(); + + if !dirnames.is_empty() { + for path in dirnames.iter() { let p = Path::new(path); match p.parent() { Some(d) => { @@ -54,8 +79,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { print!("{}", separator); } } else { - println!("{0}: missing operand", NAME); - println!("Try '{0} --help' for more information.", NAME); + show_usage_error!("missing operand"); return 1; } From cfc3d52be40958d7042c0f56368212a41c0e8dcf Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci Date: Sat, 3 Apr 2021 20:19:30 +0300 Subject: [PATCH 087/132] cut: move to clap --- Cargo.lock | 1 + src/uu/cut/Cargo.toml | 1 + src/uu/cut/src/cut.rs | 150 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 124 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea1ee53ae..15f1a606d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1679,6 +1679,7 @@ dependencies = [ name = "uu_cut" version = "0.0.6" dependencies = [ + "clap", "uucore", "uucore_procs", ] diff --git a/src/uu/cut/Cargo.toml b/src/uu/cut/Cargo.toml index 9cc852d2e..d892ddeb5 100644 --- a/src/uu/cut/Cargo.toml +++ b/src/uu/cut/Cargo.toml @@ -15,6 +15,7 @@ edition = "2018" path = "src/cut.rs" [dependencies] +clap = "2.33" uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/cut/src/cut.rs b/src/uu/cut/src/cut.rs index 95411e3fb..2b65a3347 100644 --- a/src/uu/cut/src/cut.rs +++ b/src/uu/cut/src/cut.rs @@ -10,6 +10,7 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, Read, Stdout, Write}; use std::path::Path; @@ -20,6 +21,8 @@ use uucore::ranges::Range; mod buffer; mod searcher; +static NAME: &str = "cut"; +static VERSION: &str = env!("CARGO_PKG_VERSION"); static SYNTAX: &str = "[-d] [-s] [-z] [--output-delimiter] ((-f|-b|-c) {{sequence}}) {{sourcefile}}+"; static SUMMARY: &str = @@ -422,34 +425,119 @@ fn cut_files(mut filenames: Vec, mode: Mode) -> i32 { exit_code } +mod options { + pub const BYTES: &str = "bytes"; + pub const CHARACTERS: &str = "characters"; + pub const DELIMITER: &str = "delimiter"; + pub const FIELDS: &str = "fields"; + pub const LEGACY_OPTION: &str = "legacy-option"; + pub const ZERO_TERMINATED: &str = "zero-terminated"; + pub const ONLY_DELIMITED: &str = "only-delimited"; + pub const OUTPUT_DELIMITER: &str = "output-delimiter"; + pub const COMPLEMENT: &str = "complement"; + pub const FILE: &str = "file"; +} + pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); - let matches = app!(SYNTAX, SUMMARY, LONG_HELP) - .optopt("b", "bytes", "filter byte columns from the input source", "sequence") - .optopt("c", "characters", "alias for character mode", "sequence") - .optopt("d", "delimiter", "specify the delimiter character that separates fields in the input source. Defaults to Tab.", "delimiter") - .optopt("f", "fields", "filter field columns from the input source", "sequence") - .optflag("n", "", "legacy option - has no effect.") - .optflag("", "complement", "invert the filter - instead of displaying only the filtered columns, display all but those columns") - .optflag("s", "only-delimited", "in field mode, only print lines which contain the delimiter") - .optflag("z", "zero-terminated", "instead of filtering columns based on line, filter columns based on \\0 (NULL character)") - .optopt("", "output-delimiter", "in field mode, replace the delimiter in output lines with this option's argument", "new delimiter") - .parse(args); - let complement = matches.opt_present("complement"); + let matches = App::new(executable!()) + .name(NAME) + .version(VERSION) + .usage(SYNTAX) + .about(SUMMARY) + .after_help(LONG_HELP) + .arg( + Arg::with_name(options::BYTES) + .short("b") + .long(options::BYTES) + .takes_value(true) + .help("filter byte columns from the input source") + .allow_hyphen_values(true) + .value_name("LIST"), + ) + .arg( + Arg::with_name(options::CHARACTERS) + .short("c") + .long(options::CHARACTERS) + .help("alias for character mode") + .takes_value(true) + .allow_hyphen_values(true) + .value_name("LIST"), + ) + .arg( + Arg::with_name(options::DELIMITER) + .short("d") + .long(options::DELIMITER) + .help("specify the delimiter character that separates fields in the input source. Defaults to Tab.") + .takes_value(true) + .value_name("DELIM"), + ) + .arg( + Arg::with_name(options::FIELDS) + .short("f") + .long(options::FIELDS) + .help("filter field columns from the input source") + .takes_value(true) + .allow_hyphen_values(true) + .value_name("LIST"), + ) + .arg( + Arg::with_name(options::LEGACY_OPTION) + .short("n") + .long(options::LEGACY_OPTION) + .help("legacy option - has no effect.") + .takes_value(false) + ) + .arg( + Arg::with_name(options::COMPLEMENT) + .long(options::COMPLEMENT) + .help("invert the filter - instead of displaying only the filtered columns, display all but those columns") + .takes_value(false) + + ) + .arg( + Arg::with_name(options::ONLY_DELIMITED) + .short("s") + .long(options::ONLY_DELIMITED) + .help("in field mode, only print lines which contain the delimiter") + .takes_value(false) + ) + .arg( + Arg::with_name(options::ZERO_TERMINATED) + .short("z") + .long(options::ZERO_TERMINATED) + .help("instead of filtering columns based on line, filter columns based on \\0 (NULL character)") + .takes_value(false) + ) + .arg( + Arg::with_name(options::OUTPUT_DELIMITER) + .long(options::OUTPUT_DELIMITER) + .help("in field mode, replace the delimiter in output lines with this option's argument") + .takes_value(true) + .value_name("NEW_DELIM") + ) + .arg( + Arg::with_name(options::FILE) + .hidden(true) + .multiple(true) + ) + .get_matches_from(args); + + let complement = matches.is_present("complement"); let mode_parse = match ( - matches.opt_str("bytes"), - matches.opt_str("characters"), - matches.opt_str("fields"), + matches.value_of(options::BYTES), + matches.value_of(options::CHARACTERS), + matches.value_of(options::FIELDS), ) { (Some(byte_ranges), None, None) => { list_to_ranges(&byte_ranges[..], complement).map(|ranges| { Mode::Bytes( ranges, Options { - out_delim: matches.opt_str("output-delimiter"), - zero_terminated: matches.opt_present("zero-terminated"), + out_delim: Some(matches.value_of(options::OUTPUT_DELIMITER).unwrap_or_default().to_owned()), + zero_terminated: matches.is_present(options::ZERO_TERMINATED), }, ) }) @@ -459,29 +547,29 @@ pub fn uumain(args: impl uucore::Args) -> i32 { Mode::Characters( ranges, Options { - out_delim: matches.opt_str("output-delimiter"), - zero_terminated: matches.opt_present("zero-terminated"), + out_delim: Some(matches.value_of(options::OUTPUT_DELIMITER).unwrap_or_default().to_owned()), + zero_terminated: matches.is_present(options::ZERO_TERMINATED), }, ) }) } (None, None, Some(field_ranges)) => { list_to_ranges(&field_ranges[..], complement).and_then(|ranges| { - let out_delim = match matches.opt_str("output-delimiter") { + let out_delim = match matches.value_of(options::OUTPUT_DELIMITER) { Some(s) => { if s.is_empty() { Some("\0".to_owned()) } else { - Some(s) + Some(s.to_owned()) } } None => None, }; - let only_delimited = matches.opt_present("only-delimited"); - let zero_terminated = matches.opt_present("zero-terminated"); + let only_delimited = matches.is_present(options::ONLY_DELIMITED); + let zero_terminated = matches.is_present(options::ZERO_TERMINATED); - match matches.opt_str("delimiter") { + match matches.value_of(options::DELIMITER) { Some(delim) => { if delim.chars().count() > 1 { Err(msg_opt_invalid_should_be!( @@ -494,7 +582,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let delim = if delim.is_empty() { "\0".to_owned() } else { - delim + delim.to_owned() }; Ok(Mode::Fields( @@ -533,10 +621,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let mode_parse = match mode_parse { Err(_) => mode_parse, Ok(mode) => match mode { - Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.opt_present("delimiter") => Err( + Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.is_present("delimiter") => Err( msg_opt_only_usable_if!("printing a sequence of fields", "--delimiter", "-d"), ), - Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.opt_present("only-delimited") => { + Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.is_present("only-delimited") => { Err(msg_opt_only_usable_if!( "printing a sequence of fields", "--only-delimited", @@ -547,8 +635,14 @@ pub fn uumain(args: impl uucore::Args) -> i32 { }, }; + let files: Vec = matches + .values_of(options::FILE) + .unwrap_or_default() + .map(str::to_owned) + .collect(); + match mode_parse { - Ok(mode) => cut_files(matches.free, mode), + Ok(mode) => cut_files(files, mode), Err(err_msg) => { show_error!("{}", err_msg); 1 From 7e677b3e6c2b03203efe9039d05163434ac0cbcd Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci Date: Sat, 3 Apr 2021 20:21:57 +0300 Subject: [PATCH 088/132] cut: fix formatting, use constant values --- src/uu/cut/src/cut.rs | 33 +++++++++++++++++++++++++-------- src/uu/stdbuf/src/stdbuf.rs | 3 +-- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/uu/cut/src/cut.rs b/src/uu/cut/src/cut.rs index 2b65a3347..3781f0c9f 100644 --- a/src/uu/cut/src/cut.rs +++ b/src/uu/cut/src/cut.rs @@ -494,7 +494,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(options::COMPLEMENT) .help("invert the filter - instead of displaying only the filtered columns, display all but those columns") .takes_value(false) - ) .arg( Arg::with_name(options::ONLY_DELIMITED) @@ -524,7 +523,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { ) .get_matches_from(args); - let complement = matches.is_present("complement"); + let complement = matches.is_present(options::COMPLEMENT); let mode_parse = match ( matches.value_of(options::BYTES), @@ -536,7 +535,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 { Mode::Bytes( ranges, Options { - out_delim: Some(matches.value_of(options::OUTPUT_DELIMITER).unwrap_or_default().to_owned()), + out_delim: Some( + matches + .value_of(options::OUTPUT_DELIMITER) + .unwrap_or_default() + .to_owned(), + ), zero_terminated: matches.is_present(options::ZERO_TERMINATED), }, ) @@ -547,7 +551,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 { Mode::Characters( ranges, Options { - out_delim: Some(matches.value_of(options::OUTPUT_DELIMITER).unwrap_or_default().to_owned()), + out_delim: Some( + matches + .value_of(options::OUTPUT_DELIMITER) + .unwrap_or_default() + .to_owned(), + ), zero_terminated: matches.is_present(options::ZERO_TERMINATED), }, ) @@ -621,10 +630,18 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let mode_parse = match mode_parse { Err(_) => mode_parse, Ok(mode) => match mode { - Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.is_present("delimiter") => Err( - msg_opt_only_usable_if!("printing a sequence of fields", "--delimiter", "-d"), - ), - Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.is_present("only-delimited") => { + Mode::Bytes(_, _) | Mode::Characters(_, _) + if matches.is_present(options::DELIMITER) => + { + Err(msg_opt_only_usable_if!( + "printing a sequence of fields", + "--delimiter", + "-d" + )) + } + Mode::Bytes(_, _) | Mode::Characters(_, _) + if matches.is_present(options::ONLY_DELIMITED) => + { Err(msg_opt_only_usable_if!( "printing a sequence of fields", "--only-delimited", diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index a61ba967b..67ed9a838 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -80,8 +80,7 @@ fn print_version() { fn print_usage(opts: &Options) { let brief = "Run COMMAND, with modified buffering operations for its standard streams\n \ Mandatory arguments to long options are mandatory for short options too."; - let explanation = - "If MODE is 'L' the corresponding stream will be line buffered.\n \ + let explanation = "If MODE is 'L' the corresponding stream will be line buffered.\n \ This option is invalid with standard input.\n\n \ If MODE is '0' the corresponding stream will be unbuffered.\n\n \ Otherwise MODE is a number which may be followed by one of the following:\n\n \ From e84b60b7d5464db90a727b432150d90324f2b000 Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci Date: Sat, 3 Apr 2021 20:30:28 +0300 Subject: [PATCH 089/132] cut: add display order --- src/uu/cut/src/cut.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/uu/cut/src/cut.rs b/src/uu/cut/src/cut.rs index 3781f0c9f..ddedc4727 100644 --- a/src/uu/cut/src/cut.rs +++ b/src/uu/cut/src/cut.rs @@ -430,7 +430,6 @@ mod options { pub const CHARACTERS: &str = "characters"; pub const DELIMITER: &str = "delimiter"; pub const FIELDS: &str = "fields"; - pub const LEGACY_OPTION: &str = "legacy-option"; pub const ZERO_TERMINATED: &str = "zero-terminated"; pub const ONLY_DELIMITED: &str = "only-delimited"; pub const OUTPUT_DELIMITER: &str = "output-delimiter"; @@ -454,7 +453,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .takes_value(true) .help("filter byte columns from the input source") .allow_hyphen_values(true) - .value_name("LIST"), + .value_name("LIST") + .display_order(1), ) .arg( Arg::with_name(options::CHARACTERS) @@ -463,7 +463,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .help("alias for character mode") .takes_value(true) .allow_hyphen_values(true) - .value_name("LIST"), + .value_name("LIST") + .display_order(2), ) .arg( Arg::with_name(options::DELIMITER) @@ -471,7 +472,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(options::DELIMITER) .help("specify the delimiter character that separates fields in the input source. Defaults to Tab.") .takes_value(true) - .value_name("DELIM"), + .value_name("DELIM") + .display_order(3), ) .arg( Arg::with_name(options::FIELDS) @@ -480,20 +482,15 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .help("filter field columns from the input source") .takes_value(true) .allow_hyphen_values(true) - .value_name("LIST"), - ) - .arg( - Arg::with_name(options::LEGACY_OPTION) - .short("n") - .long(options::LEGACY_OPTION) - .help("legacy option - has no effect.") - .takes_value(false) + .value_name("LIST") + .display_order(4), ) .arg( Arg::with_name(options::COMPLEMENT) .long(options::COMPLEMENT) .help("invert the filter - instead of displaying only the filtered columns, display all but those columns") .takes_value(false) + .display_order(5), ) .arg( Arg::with_name(options::ONLY_DELIMITED) @@ -501,6 +498,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(options::ONLY_DELIMITED) .help("in field mode, only print lines which contain the delimiter") .takes_value(false) + .display_order(6), ) .arg( Arg::with_name(options::ZERO_TERMINATED) @@ -508,6 +506,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(options::ZERO_TERMINATED) .help("instead of filtering columns based on line, filter columns based on \\0 (NULL character)") .takes_value(false) + .display_order(8), ) .arg( Arg::with_name(options::OUTPUT_DELIMITER) @@ -515,6 +514,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .help("in field mode, replace the delimiter in output lines with this option's argument") .takes_value(true) .value_name("NEW_DELIM") + .display_order(7), ) .arg( Arg::with_name(options::FILE) From f47345ec9bb452068eaa8bf2af51a1bae3a5148b Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci Date: Sat, 3 Apr 2021 20:55:10 +0300 Subject: [PATCH 090/132] cut: add gnu compatability to error messages --- src/uu/cut/src/cut.rs | 9 +++++++-- tests/by-util/test_cut.rs | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/uu/cut/src/cut.rs b/src/uu/cut/src/cut.rs index ddedc4727..6b09b91d9 100644 --- a/src/uu/cut/src/cut.rs +++ b/src/uu/cut/src/cut.rs @@ -401,8 +401,13 @@ fn cut_files(mut filenames: Vec, mode: Mode) -> i32 { } else { let path = Path::new(&filename[..]); - if !path.exists() { - show_error!("{}", msg_args_nonexistent_file!(filename)); + if path.is_dir() { + show_error!("{}: Is a directory", filename); + continue; + } + + if !path.metadata().is_ok() { + show_error!("{}: No such file or directory", filename); continue; } diff --git a/tests/by-util/test_cut.rs b/tests/by-util/test_cut.rs index fc0f1b1f9..875317721 100644 --- a/tests/by-util/test_cut.rs +++ b/tests/by-util/test_cut.rs @@ -139,3 +139,21 @@ fn test_zero_terminated_only_delimited() { .succeeds() .stdout_only("82\n7\0"); } + +#[test] +fn test_directory_and_no_such_file() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.mkdir("some"); + + ucmd.arg("-b1") + .arg("some") + .run() + .stderr_is("cut: error: some: Is a directory\n"); + + new_ucmd!() + .arg("-b1") + .arg("some") + .run() + .stderr_is("cut: error: some: No such file or directory\n"); +} From bad1df9c1b9b31d26fc3e9f8de59094137b813fe Mon Sep 17 00:00:00 2001 From: Daniel Rocco Date: Fri, 2 Apr 2021 08:47:04 -0400 Subject: [PATCH 091/132] fold: improve newline handling and test coverage - refactor implementation for readability - correct handling of files with no trailing newline and/or blank lines --- src/uu/fold/src/fold.rs | 263 +++++++++++++++++++++-------------- tests/by-util/test_fold.rs | 277 +++++++++++++++++++++++++++++++++++++ 2 files changed, 433 insertions(+), 107 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 27ab319d0..8cf95b82a 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -79,7 +79,6 @@ fn handle_obsolete(args: &[String]) -> (Vec, Option) { (args.to_vec(), None) } -#[inline] fn fold(filenames: Vec, bytes: bool, spaces: bool, width: usize) { for filename in &filenames { let filename: &str = &filename; @@ -92,123 +91,173 @@ fn fold(filenames: Vec, bytes: bool, spaces: bool, width: usize) { file_buf = safe_unwrap!(File::open(Path::new(filename))); &mut file_buf as &mut dyn Read }); - fold_file(buffer, bytes, spaces, width); + + if bytes { + fold_file_bytewise(buffer, spaces, width); + } else { + fold_file(buffer, spaces, width); + } } } -#[inline] -fn fold_file(file: BufReader, bytes: bool, spaces: bool, width: usize) { - for line_result in file.lines() { - let mut line = safe_unwrap!(line_result); +/// Fold `file` to fit `width` (number of columns), counting all characters as +/// one column. +/// +/// This function handles folding for the `-b`/`--bytes` option, counting +/// tab, backspace, and carriage return as occupying one column, identically +/// to all other characters in the stream. +/// +/// If `spaces` is `true`, attempt to break lines at whitespace boundaries. +fn fold_file_bytewise(mut file: BufReader, spaces: bool, width: usize) { + let mut line = String::new(); - if line.is_empty() { + loop { + if let Ok(0) = file.read_line(&mut line) { + break; + } + + if line == "\n" { println!(); - } else if bytes { - let len = line.len(); - let mut i = 0; - while i < len { - let width = if len - i >= width { width } else { len - i }; - let slice = { - let slice = &line[i..i + width]; - if spaces && i + width < len { - match slice.rfind(char::is_whitespace) { - Some(m) => &slice[..=m], - None => slice, - } - } else { - slice + line.truncate(0); + continue; + } + + let len = line.len(); + let mut i = 0; + + while i < len { + let width = if len - i >= width { width } else { len - i }; + let slice = { + let slice = &line[i..i + width]; + if spaces && i + width < len { + match slice.rfind(char::is_whitespace) { + Some(m) => &slice[..=m], + None => slice, } - }; - print!("{}", slice); - i += slice.len(); + } else { + slice + } + }; + + // Don't duplicate trailing newlines: if the slice is "\n", the + // previous iteration folded just before the end of the line and + // has already printed this newline. + if slice == "\n" { + break; } - } else { - let mut len = line.chars().count(); - let newline = line.ends_with('\n'); - if newline { - if len == 1 { - println!(); + + i += slice.len(); + + let at_eol = i >= len; + + if at_eol { + print!("{}", slice); + } else { + println!("{}", slice); + } + } + + line.truncate(0); + } +} + +/// Fold `file` to fit `width` (number of columns). +/// +/// By default `fold` treats tab, backspace, and carriage return specially: +/// tab characters count as 8 columns, backspace decreases the +/// column count, and carriage return resets the column count to 0. +/// +/// If `spaces` is `true`, attempt to break lines at whitespace boundaries. +#[allow(unused_assignments)] +fn fold_file(mut file: BufReader, spaces: bool, width: usize) { + let mut line = String::new(); + let mut output = String::new(); + let mut col_count = 0; + let mut char_count = 0; + let mut last_space = None; + + /// Print the output line, resetting the column and character counts. + /// + /// If `spaces` is `true`, print the output line up to the last + /// encountered whitespace character (inclusive) and set the remaining + /// characters as the start of the next line. + macro_rules! emit_output { + () => { + let consume = match last_space { + Some(i) => i + 1, + None => output.len(), + }; + + println!("{}", &output[..consume]); + output.replace_range(..consume, ""); + char_count = output.len(); + + // we know there are no tabs left in output, so each char counts + // as 1 column + col_count = char_count; + + last_space = None; + }; + } + + loop { + if let Ok(0) = file.read_line(&mut line) { + break; + } + + for ch in line.chars() { + if ch == '\n' { + // make sure to _not_ split output at whitespace, since we + // know the entire output will fit + last_space = None; + emit_output!(); + break; + } + + if col_count >= width { + emit_output!(); + } + + match ch { + '\t' => { + if col_count + 8 > width && !output.is_empty() { + emit_output!(); + } + col_count += 8; + last_space = Some(char_count); + } + '\x08' => { + // FIXME: does not match GNU's handling of backspace + if col_count > 0 { + col_count -= 1; + char_count -= 1; + output.truncate(char_count); + } continue; } - len -= 1; - line.truncate(len); - } - let mut output = String::new(); - let mut count = 0; - for (i, ch) in line.chars().enumerate() { - if count >= width { - let (val, ncount) = { - let slice = &output[..]; - let (out, val, ncount) = if spaces && i + 1 < len { - match rfind_whitespace(slice) { - Some(m) => { - let routput = &slice[m + 1..slice.chars().count()]; - let ncount = routput.chars().fold(0, |out, ch: char| { - out + match ch { - '\t' => 8, - '\x08' => { - if out > 0 { - !0 - } else { - 0 - } - } - '\r' => return 0, - _ => 1, - } - }); - (&slice[0..=m], routput, ncount) - } - None => (slice, "", 0), - } - } else { - (slice, "", 0) - }; - println!("{}", out); - (val.to_owned(), ncount) - }; - output = val; - count = ncount; + '\r' => { + // FIXME: does not match GNU's handling of carriage return + output.truncate(0); + col_count = 0; + char_count = 0; + continue; } - match ch { - '\t' => { - count += 8; - if count > width { - println!("{}", output); - output.truncate(0); - count = 8; - } - } - '\x08' => { - if count > 0 { - count -= 1; - let len = output.len() - 1; - output.truncate(len); - } - continue; - } - '\r' => { - output.truncate(0); - count = 0; - continue; - } - _ => count += 1, - }; - output.push(ch); - } - if count > 0 { - println!("{}", output); - } - } - } -} + _ if spaces && ch.is_whitespace() => { + last_space = Some(char_count); + col_count += 1 + } + _ => col_count += 1, + }; -#[inline] -fn rfind_whitespace(slice: &str) -> Option { - for (i, ch) in slice.chars().rev().enumerate() { - if ch.is_whitespace() { - return Some(slice.chars().count() - (i + 1)); + output.push(ch); + char_count += 1; } + + if col_count > 0 { + print!("{}", output); + output.truncate(0); + } + + line.truncate(0); } - None } diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index 64d77cd2b..52e630e5b 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -32,6 +32,24 @@ fn test_default_wrap_with_newlines() { .stdout_is_fixture("lorem_ipsum_new_line_80_column.expected"); } +#[test] +fn test_should_preserve_empty_line_without_final_newline() { + new_ucmd!() + .arg("-w2") + .pipe_in("12\n\n34") + .succeeds() + .stdout_is("12\n\n34"); +} + +#[test] +fn test_should_preserve_empty_line_and_final_newline() { + new_ucmd!() + .arg("-w2") + .pipe_in("12\n\n34\n") + .succeeds() + .stdout_is("12\n\n34\n"); +} + #[test] fn test_should_preserve_empty_lines() { new_ucmd!().pipe_in("\n").succeeds().stdout_is("\n"); @@ -57,3 +75,262 @@ fn test_word_boundary_split_should_preserve_empty_lines() { .succeeds() .stdout_is("0\n1\n\n2\n\n\n"); } + +#[test] +fn test_should_not_add_newline_when_line_less_than_fold() { + new_ucmd!().pipe_in("1234").succeeds().stdout_is("1234"); +} + +#[test] +fn test_should_not_add_newline_when_line_longer_than_fold() { + new_ucmd!() + .arg("-w2") + .pipe_in("1234") + .succeeds() + .stdout_is("12\n34"); +} + +#[test] +fn test_should_not_add_newline_when_line_equal_to_fold() { + new_ucmd!() + .arg("-w1") + .pipe_in(" ") + .succeeds() + .stdout_is(" "); +} + +#[test] +fn test_should_preserve_final_newline_when_line_less_than_fold() { + new_ucmd!().pipe_in("1234\n").succeeds().stdout_is("1234\n"); +} + +#[test] +fn test_should_preserve_final_newline_when_line_longer_than_fold() { + new_ucmd!() + .arg("-w2") + .pipe_in("1234\n") + .succeeds() + .stdout_is("12\n34\n"); +} + +#[test] +fn test_should_preserve_final_newline_when_line_equal_to_fold() { + new_ucmd!() + .arg("-w2") + .pipe_in("1\n") + .succeeds() + .stdout_is("1\n"); +} + +#[test] +fn test_single_tab_should_not_add_extra_newline() { + new_ucmd!() + .arg("-w1") + .pipe_in("\t") + .succeeds() + .stdout_is("\t"); +} + +#[test] +fn test_tab_counts_as_8_columns() { + new_ucmd!() + .arg("-w8") + .pipe_in("\t1") + .succeeds() + .stdout_is("\t\n1"); +} + +#[test] +fn test_fold_at_word_boundary() { + new_ucmd!() + .args(&["-w4", "-s"]) + .pipe_in("one two") + .succeeds() + .stdout_is("one \ntwo"); +} + +#[test] +fn test_fold_at_leading_word_boundary() { + new_ucmd!() + .args(&["-w3", "-s"]) + .pipe_in(" aaa") + .succeeds() + .stdout_is(" \naaa"); +} + +#[test] +fn test_fold_at_word_boundary_preserve_final_newline() { + new_ucmd!() + .args(&["-w4", "-s"]) + .pipe_in("one two\n") + .succeeds() + .stdout_is("one \ntwo\n"); +} + +#[test] +fn test_fold_at_tab_as_word_boundary() { + new_ucmd!() + .args(&["-w10", "-s"]) + .pipe_in("a\tbbb\n") + .succeeds() + .stdout_is("a\t\nbbb\n"); +} + +#[test] +fn test_fold_at_word_boundary_only_whitespace() { + new_ucmd!() + .args(&["-w2", "-s"]) + .pipe_in(" ") + .succeeds() + .stdout_is(" \n "); +} + +#[test] +fn test_fold_at_word_boundary_only_whitespace_preserve_final_newline() { + new_ucmd!() + .args(&["-w2", "-s"]) + .pipe_in(" \n") + .succeeds() + .stdout_is(" \n \n"); +} + +// +// bytewise tests + +#[test] +fn test_bytewise_should_preserve_empty_line_without_final_newline() { + new_ucmd!() + .args(&["-w2", "-b"]) + .pipe_in("123\n\n45") + .succeeds() + .stdout_is("12\n3\n\n45"); +} + +#[test] +fn test_bytewise_should_preserve_empty_line_and_final_newline() { + new_ucmd!() + .args(&["-w2", "-b"]) + .pipe_in("12\n\n34\n") + .succeeds() + .stdout_is("12\n\n34\n"); +} + +#[test] +fn test_bytewise_should_preserve_empty_lines() { + new_ucmd!() + .arg("-b") + .pipe_in("\n") + .succeeds() + .stdout_is("\n"); + + new_ucmd!() + .args(&["-w1", "-b"]) + .pipe_in("0\n1\n\n2\n\n\n") + .succeeds() + .stdout_is("0\n1\n\n2\n\n\n"); +} + +#[test] +fn test_bytewise_word_boundary_split_should_preserve_empty_lines() { + new_ucmd!() + .args(&["-s", "-b"]) + .pipe_in("\n") + .succeeds() + .stdout_is("\n"); + + new_ucmd!() + .args(&["-w1", "-s", "-b"]) + .pipe_in("0\n1\n\n2\n\n\n") + .succeeds() + .stdout_is("0\n1\n\n2\n\n\n"); +} + +#[test] +fn test_bytewise_should_not_add_newline_when_line_less_than_fold() { + new_ucmd!() + .arg("-b") + .pipe_in("1234") + .succeeds() + .stdout_is("1234"); +} + +#[test] +fn test_bytewise_should_not_add_newline_when_line_longer_than_fold() { + new_ucmd!() + .args(&["-w2", "-b"]) + .pipe_in("1234") + .succeeds() + .stdout_is("12\n34"); +} + +#[test] +fn test_bytewise_should_not_add_newline_when_line_equal_to_fold() { + new_ucmd!() + .args(&["-w1", "-b"]) + .pipe_in(" ") + .succeeds() + .stdout_is(" "); +} + +#[test] +fn test_bytewise_should_preserve_final_newline_when_line_less_than_fold() { + new_ucmd!() + .arg("-b") + .pipe_in("1234\n") + .succeeds() + .stdout_is("1234\n"); +} + +#[test] +fn test_bytewise_should_preserve_final_newline_when_line_longer_than_fold() { + new_ucmd!() + .args(&["-w2", "-b"]) + .pipe_in("1234\n") + .succeeds() + .stdout_is("12\n34\n"); +} + +#[test] +fn test_bytewise_should_preserve_final_newline_when_line_equal_to_fold() { + new_ucmd!() + .args(&["-w2", "-b"]) + .pipe_in("1\n") + .succeeds() + .stdout_is("1\n"); +} + +#[test] +fn test_bytewise_single_tab_should_not_add_extra_newline() { + new_ucmd!() + .args(&["-w1", "-b"]) + .pipe_in("\t") + .succeeds() + .stdout_is("\t"); +} + +#[test] +fn test_tab_counts_as_one_byte() { + new_ucmd!() + .args(&["-w2", "-b"]) + .pipe_in("1\t2\n") + .succeeds() + .stdout_is("1\t\n2\n"); +} + +#[test] +fn test_bytewise_fold_at_word_boundary_only_whitespace() { + new_ucmd!() + .args(&["-w2", "-s", "-b"]) + .pipe_in(" ") + .succeeds() + .stdout_is(" \n "); +} + +#[test] +fn test_bytewise_fold_at_word_boundary_only_whitespace_preserve_final_newline() { + new_ucmd!() + .args(&["-w2", "-s", "-b"]) + .pipe_in(" \n") + .succeeds() + .stdout_is(" \n \n"); +} From 19c6a42de550ca6dd0f4ffd0d8a546b3e4146cc9 Mon Sep 17 00:00:00 2001 From: Chirag Jadwani Date: Sun, 4 Apr 2021 15:07:29 +0530 Subject: [PATCH 092/132] uniq: implement group option --- Cargo.lock | 35 +++++++++ src/uu/uniq/Cargo.toml | 2 + src/uu/uniq/src/uniq.rs | 83 ++++++++++++++++------ tests/by-util/test_uniq.rs | 45 ++++++++++++ tests/fixtures/uniq/group-append.expected | 26 +++++++ tests/fixtures/uniq/group-both.expected | 27 +++++++ tests/fixtures/uniq/group-prepend.expected | 26 +++++++ tests/fixtures/uniq/group.expected | 25 +++++++ 8 files changed, 249 insertions(+), 20 deletions(-) create mode 100644 tests/fixtures/uniq/group-append.expected create mode 100644 tests/fixtures/uniq/group-both.expected create mode 100644 tests/fixtures/uniq/group-prepend.expected create mode 100644 tests/fixtures/uniq/group.expected diff --git a/Cargo.lock b/Cargo.lock index ea1ee53ae..97398b7a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,6 +650,15 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" +[[package]] +name = "heck" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.18" @@ -1352,6 +1361,24 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "strum" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c" + +[[package]] +name = "strum_macros" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149" +dependencies = [ + "heck", + "proc-macro2", + "quote 1.0.9", + "syn", +] + [[package]] name = "syn" version = "1.0.68" @@ -1499,6 +1526,12 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +[[package]] +name = "unicode-segmentation" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" + [[package]] name = "unicode-width" version = "0.1.8" @@ -2455,6 +2488,8 @@ name = "uu_uniq" version = "0.0.6" dependencies = [ "clap", + "strum", + "strum_macros", "uucore", "uucore_procs", ] diff --git a/src/uu/uniq/Cargo.toml b/src/uu/uniq/Cargo.toml index 8c63455ec..3fe89b450 100644 --- a/src/uu/uniq/Cargo.toml +++ b/src/uu/uniq/Cargo.toml @@ -16,6 +16,8 @@ path = "src/uniq.rs" [dependencies] clap = "2.33" +strum = "0.20" +strum_macros = "0.20" uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/uniq/src/uniq.rs b/src/uu/uniq/src/uniq.rs index a1809f0f0..a61a78a61 100644 --- a/src/uu/uniq/src/uniq.rs +++ b/src/uu/uniq/src/uniq.rs @@ -13,6 +13,7 @@ use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Result, Write}; use std::path::Path; use std::str::FromStr; +use strum_macros::{AsRefStr, EnumString}; static ABOUT: &str = "Report or omit repeated lines."; static VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -26,14 +27,18 @@ pub mod options { pub static SKIP_CHARS: &str = "skip-chars"; pub static UNIQUE: &str = "unique"; pub static ZERO_TERMINATED: &str = "zero-terminated"; + pub static GROUP: &str = "group"; } static ARG_FILES: &str = "files"; -#[derive(PartialEq)] +#[derive(PartialEq, Clone, Copy, AsRefStr, EnumString)] +#[strum(serialize_all = "snake_case")] enum Delimiters { + Append, Prepend, Separate, + Both, None, } @@ -58,22 +63,33 @@ impl Uniq { ) { let mut lines: Vec = vec![]; let mut first_line_printed = false; - let delimiters = &self.delimiters; + let delimiters = self.delimiters; let line_terminator = self.get_line_terminator(); + // Don't print any delimiting lines before, after or between groups if delimiting method is 'none' + let no_delimiters = delimiters == Delimiters::None; + // The 'prepend' and 'both' delimit methods will cause output to start with delimiter line + let prepend_delimiter = delimiters == Delimiters::Prepend || delimiters == Delimiters::Both; + // The 'append' and 'both' delimit methods will cause output to end with delimiter line + let append_delimiter = delimiters == Delimiters::Append || delimiters == Delimiters::Both; for line in reader.split(line_terminator).map(get_line_string) { if !lines.is_empty() && self.cmp_keys(&lines[0], &line) { - let print_delimiter = delimiters == &Delimiters::Prepend - || (delimiters == &Delimiters::Separate && first_line_printed); + // Print delimiter if delimit method is not 'none' and any line has been output + // before or if we need to start output with delimiter + let print_delimiter = !no_delimiters && (prepend_delimiter || first_line_printed); first_line_printed |= self.print_lines(writer, &lines, print_delimiter); lines.truncate(0); } lines.push(line); } if !lines.is_empty() { - let print_delimiter = delimiters == &Delimiters::Prepend - || (delimiters == &Delimiters::Separate && first_line_printed); - self.print_lines(writer, &lines, print_delimiter); + // Print delimiter if delimit method is not 'none' and any line has been output + // before or if we need to start output with delimiter + let print_delimiter = !no_delimiters && (prepend_delimiter || first_line_printed); + first_line_printed |= self.print_lines(writer, &lines, print_delimiter); + } + if append_delimiter && first_line_printed { + crash_if_err!(1, writer.write_all(&[line_terminator])); } } @@ -233,10 +249,30 @@ pub fn uumain(args: impl uucore::Args) -> i32 { Arg::with_name(options::ALL_REPEATED) .short("D") .long(options::ALL_REPEATED) - .possible_values(&["none", "prepend", "separate"]) - .help("print all duplicate lines. Delimiting is done with blank lines") + .possible_values(&[ + Delimiters::None.as_ref(), Delimiters::Prepend.as_ref(), Delimiters::Separate.as_ref() + ]) + .help("print all duplicate lines. Delimiting is done with blank lines. [default: none]") .value_name("delimit-method") - .default_value("none"), + .min_values(0) + .max_values(1), + ) + .arg( + Arg::with_name(options::GROUP) + .long(options::GROUP) + .possible_values(&[ + Delimiters::Separate.as_ref(), Delimiters::Prepend.as_ref(), + Delimiters::Append.as_ref(), Delimiters::Both.as_ref() + ]) + .help("show all items, separating groups with an empty line. [default: separate]") + .value_name("group-method") + .min_values(0) + .max_values(1) + .conflicts_with_all(&[ + options::REPEATED, + options::ALL_REPEATED, + options::UNIQUE, + ]), ) .arg( Arg::with_name(options::CHECK_CHARS) @@ -314,17 +350,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let uniq = Uniq { repeats_only: matches.is_present(options::REPEATED) - || matches.occurrences_of(options::ALL_REPEATED) > 0, + || matches.is_present(options::ALL_REPEATED), uniques_only: matches.is_present(options::UNIQUE), - all_repeated: matches.occurrences_of(options::ALL_REPEATED) > 0, - delimiters: match matches.value_of(options::ALL_REPEATED).map(String::from) { - Some(ref opt_arg) if opt_arg != "none" => match &(*opt_arg.as_str()) { - "prepend" => Delimiters::Prepend, - "separate" => Delimiters::Separate, - _ => crash!(1, "Incorrect argument for all-repeated: {}", opt_arg), - }, - _ => Delimiters::None, - }, + all_repeated: matches.is_present(options::ALL_REPEATED) + || matches.is_present(options::GROUP), + delimiters: get_delimiter(&matches), show_counts: matches.is_present(options::COUNT), skip_fields: opt_parsed(options::SKIP_FIELDS, &matches), slice_start: opt_parsed(options::SKIP_CHARS, &matches), @@ -340,6 +370,19 @@ pub fn uumain(args: impl uucore::Args) -> i32 { 0 } +fn get_delimiter(matches: &ArgMatches) -> Delimiters { + let value = matches + .value_of(options::ALL_REPEATED) + .or_else(|| matches.value_of(options::GROUP)); + if let Some(delimiter_arg) = value { + crash_if_err!(1, Delimiters::from_str(delimiter_arg)) + } else if matches.is_present(options::GROUP) { + Delimiters::Separate + } else { + Delimiters::None + } +} + fn open_input_file(in_file_name: String) -> BufReader> { let in_file = if in_file_name == "-" { Box::new(stdin()) as Box diff --git a/tests/by-util/test_uniq.rs b/tests/by-util/test_uniq.rs index 22e67540e..c1e53faf3 100644 --- a/tests/by-util/test_uniq.rs +++ b/tests/by-util/test_uniq.rs @@ -147,3 +147,48 @@ fn test_invalid_utf8() { .failure() .stderr_only("uniq: error: invalid utf-8 sequence of 1 bytes from index 0"); } + +#[test] +fn test_group() { + new_ucmd!() + .args(&["--group"]) + .pipe_in_fixture(INPUT) + .run() + .stdout_is_fixture("group.expected"); +} + +#[test] +fn test_group_prepend() { + new_ucmd!() + .args(&["--group=prepend"]) + .pipe_in_fixture(INPUT) + .run() + .stdout_is_fixture("group-prepend.expected"); +} + +#[test] +fn test_group_append() { + new_ucmd!() + .args(&["--group=append"]) + .pipe_in_fixture(INPUT) + .run() + .stdout_is_fixture("group-append.expected"); +} + +#[test] +fn test_group_both() { + new_ucmd!() + .args(&["--group=both"]) + .pipe_in_fixture(INPUT) + .run() + .stdout_is_fixture("group-both.expected"); +} + +#[test] +fn test_group_separate() { + new_ucmd!() + .args(&["--group=separate"]) + .pipe_in_fixture(INPUT) + .run() + .stdout_is_fixture("group.expected"); +} diff --git a/tests/fixtures/uniq/group-append.expected b/tests/fixtures/uniq/group-append.expected new file mode 100644 index 000000000..62f53e69f --- /dev/null +++ b/tests/fixtures/uniq/group-append.expected @@ -0,0 +1,26 @@ + aaaaa ⅰ + + bbbbb ⅱ + bbbbb ⅱ + + ccccc ⅲ + ccccc ⅲ + ccccc ⅲ + + ddddd ⅲ + ddddd ⅲ + ddddd ⅲ + ddddd ⅲ + + eeeee ⅲ + + fffff ⅲ + fffff ⅲ + + ggggg ⅲ + ggggg ⅲ + ggggg ⅲ + + GGGGG ⅲ + GGGGG ⅲ + diff --git a/tests/fixtures/uniq/group-both.expected b/tests/fixtures/uniq/group-both.expected new file mode 100644 index 000000000..8a0f06bf2 --- /dev/null +++ b/tests/fixtures/uniq/group-both.expected @@ -0,0 +1,27 @@ + + aaaaa ⅰ + + bbbbb ⅱ + bbbbb ⅱ + + ccccc ⅲ + ccccc ⅲ + ccccc ⅲ + + ddddd ⅲ + ddddd ⅲ + ddddd ⅲ + ddddd ⅲ + + eeeee ⅲ + + fffff ⅲ + fffff ⅲ + + ggggg ⅲ + ggggg ⅲ + ggggg ⅲ + + GGGGG ⅲ + GGGGG ⅲ + diff --git a/tests/fixtures/uniq/group-prepend.expected b/tests/fixtures/uniq/group-prepend.expected new file mode 100644 index 000000000..5209f7fbe --- /dev/null +++ b/tests/fixtures/uniq/group-prepend.expected @@ -0,0 +1,26 @@ + + aaaaa ⅰ + + bbbbb ⅱ + bbbbb ⅱ + + ccccc ⅲ + ccccc ⅲ + ccccc ⅲ + + ddddd ⅲ + ddddd ⅲ + ddddd ⅲ + ddddd ⅲ + + eeeee ⅲ + + fffff ⅲ + fffff ⅲ + + ggggg ⅲ + ggggg ⅲ + ggggg ⅲ + + GGGGG ⅲ + GGGGG ⅲ diff --git a/tests/fixtures/uniq/group.expected b/tests/fixtures/uniq/group.expected new file mode 100644 index 000000000..145a78011 --- /dev/null +++ b/tests/fixtures/uniq/group.expected @@ -0,0 +1,25 @@ + aaaaa ⅰ + + bbbbb ⅱ + bbbbb ⅱ + + ccccc ⅲ + ccccc ⅲ + ccccc ⅲ + + ddddd ⅲ + ddddd ⅲ + ddddd ⅲ + ddddd ⅲ + + eeeee ⅲ + + fffff ⅲ + fffff ⅲ + + ggggg ⅲ + ggggg ⅲ + ggggg ⅲ + + GGGGG ⅲ + GGGGG ⅲ From fa4272a19be7c3d98c034a83ddf56b44732c61b7 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Sun, 4 Apr 2021 19:19:56 +0200 Subject: [PATCH 093/132] ls: --hide and --ignore --- src/uu/ls/Cargo.toml | 1 + src/uu/ls/src/ls.rs | 59 ++++++++++++++++++++++++----- tests/by-util/test_ls.rs | 80 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index e1d9b7990..bf3860bf3 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -22,6 +22,7 @@ term_grid = "0.1.5" termsize = "0.1.6" time = "0.1.40" unicode-width = "0.1.5" +glob = "0.3.0" uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index ece497bdb..e011b9e52 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -17,6 +17,7 @@ mod quoting_style; mod version_cmp; use clap::{App, Arg}; +use glob; use number_prefix::NumberPrefix; use quoting_style::{escape_name, QuotingStyle}; #[cfg(unix)] @@ -138,6 +139,8 @@ pub mod options { pub static COLOR: &str = "color"; pub static PATHS: &str = "paths"; pub static INDICATOR_STYLE: &str = "indicator-style"; + pub static HIDE: &str = "hide"; + pub static IGNORE: &str = "ignore"; } #[derive(PartialEq, Eq)] @@ -191,7 +194,7 @@ struct Config { recursive: bool, reverse: bool, dereference: bool, - ignore_backups: bool, + ignore_patterns: Vec, size_format: SizeFormat, directory: bool, time: Time, @@ -437,6 +440,28 @@ impl Config { IndicatorStyle::None }; + let mut ignore_patterns = Vec::new(); + if options.is_present(options::IGNORE_BACKUPS) { + ignore_patterns.push(glob::Pattern::new("*~").unwrap()); + ignore_patterns.push(glob::Pattern::new(".*~").unwrap()); + } + + for pattern in options.values_of(options::IGNORE).into_iter().flatten() { + match glob::Pattern::new(pattern) { + Ok(p) => ignore_patterns.push(p), + Err(e) => show_error!("{}", e), + } + } + + if files == Files::Normal { + for pattern in options.values_of(options::HIDE).into_iter().flatten() { + match glob::Pattern::new(pattern) { + Ok(p) => ignore_patterns.push(p), + Err(e) => show_error!("{}", e), + } + } + } + Config { format, files, @@ -444,7 +469,7 @@ impl Config { recursive: options.is_present(options::RECURSIVE), reverse: options.is_present(options::REVERSE), dereference: options.is_present(options::DEREFERENCE), - ignore_backups: options.is_present(options::IGNORE_BACKUPS), + ignore_patterns, size_format, directory: options.is_present(options::DIRECTORY), time, @@ -664,6 +689,26 @@ pub fn uumain(args: impl uucore::Args) -> i32 { ]) ) + // Hide and ignore + .arg( + Arg::with_name(options::HIDE) + .long(options::HIDE) + .takes_value(true) + .multiple(true) + ) + .arg( + Arg::with_name(options::IGNORE) + .long(options::IGNORE) + .takes_value(true) + .multiple(true) + ) + .arg( + Arg::with_name(options::IGNORE_BACKUPS) + .short("B") + .long(options::IGNORE_BACKUPS) + .help("Ignore entries which end with ~."), + ) + // Sort arguments .arg( Arg::with_name(options::SORT) @@ -761,12 +806,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 { '.' and '..'.", ), ) - .arg( - Arg::with_name(options::IGNORE_BACKUPS) - .short("B") - .long(options::IGNORE_BACKUPS) - .help("Ignore entries which end with ~."), - ) .arg( Arg::with_name(options::DIRECTORY) .short("d") @@ -985,10 +1024,12 @@ fn is_hidden(file_path: &DirEntry) -> bool { fn should_display(entry: &DirEntry, config: &Config) -> bool { let ffi_name = entry.file_name(); let name = ffi_name.to_string_lossy(); + if config.files == Files::Normal && is_hidden(entry) { return false; } - if config.ignore_backups && name.ends_with('~') { + + if config.ignore_patterns.iter().any(|p| p.matches(&name)) { return false; } true diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index d403e5577..7d678acea 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1209,3 +1209,83 @@ fn test_ls_quoting_style() { assert_eq!(result.stdout, format!("{}\n", correct)); } } + +#[test] +fn test_ls_ignore_hide() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.touch("README.md"); + at.touch("CONTRIBUTING.md"); + at.touch("some_other_file"); + at.touch("READMECAREFULLY.md"); + + scene.ucmd().arg("--hide").arg("*").succeeds().stdout_is(""); + + scene + .ucmd() + .arg("--ignore") + .arg("*") + .succeeds() + .stdout_is(""); + + scene + .ucmd() + .arg("--ignore") + .arg("irrelevant pattern") + .succeeds() + .stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); + + scene + .ucmd() + .arg("--ignore") + .arg("README*.md") + .succeeds() + .stdout_is("CONTRIBUTING.md\nsome_other_file\n"); + + scene + .ucmd() + .arg("--hide") + .arg("README*.md") + .succeeds() + .stdout_is("CONTRIBUTING.md\nsome_other_file\n"); + + scene + .ucmd() + .arg("--ignore") + .arg("*.md") + .succeeds() + .stdout_is("some_other_file\n"); + + scene + .ucmd() + .arg("-a") + .arg("--ignore") + .arg("*.md") + .succeeds() + .stdout_is(".\n..\nsome_other_file\n"); + + scene + .ucmd() + .arg("-a") + .arg("--hide") + .arg("*.md") + .succeeds() + .stdout_is(".\n..\nCONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); + + scene + .ucmd() + .arg("-A") + .arg("--ignore") + .arg("*.md") + .succeeds() + .stdout_is("some_other_file\n"); + + scene + .ucmd() + .arg("-A") + .arg("--hide") + .arg("*.md") + .succeeds() + .stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); +} From 76308dbec9f0538a17c443a01a241cf120c6177e Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Sun, 4 Apr 2021 22:35:22 +0200 Subject: [PATCH 094/132] ls: tests for invalid patterns for hide and ignore --- src/uu/ls/src/ls.rs | 4 ++-- tests/by-util/test_ls.rs | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index e011b9e52..1e6e300ff 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -449,7 +449,7 @@ impl Config { for pattern in options.values_of(options::IGNORE).into_iter().flatten() { match glob::Pattern::new(pattern) { Ok(p) => ignore_patterns.push(p), - Err(e) => show_error!("{}", e), + Err(_) => show_error!("Invalid pattern for ignore: '{}'", pattern), } } @@ -457,7 +457,7 @@ impl Config { for pattern in options.values_of(options::HIDE).into_iter().flatten() { match glob::Pattern::new(pattern) { Ok(p) => ignore_patterns.push(p), - Err(e) => show_error!("{}", e), + Err(_) => show_error!("Invalid pattern for hide: '{}'", pattern), } } } diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 7d678acea..377e12f74 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1288,4 +1288,29 @@ fn test_ls_ignore_hide() { .arg("*.md") .succeeds() .stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); + + // Stacking multiple patterns + scene + .ucmd() + .arg("--ignore") + .arg("README*") + .arg("--ignore") + .arg("CONTRIBUTING*") + .succeeds() + .stdout_is("some_other_file\n"); + + // Invalid patterns + scene + .ucmd() + .arg("--ignore") + .arg("READ[ME") + .succeeds() + .stderr_contains(&"Invalid pattern"); + + scene + .ucmd() + .arg("--ignore") + .arg("READ[ME") + .succeeds() + .stderr_contains(&"Invalid pattern"); } From 51770e6bee24431d104f6345e38648ecc3a34730 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Sun, 4 Apr 2021 22:40:36 +0200 Subject: [PATCH 095/132] ls: invalid pattern move from error to warning --- src/uu/ls/src/ls.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 1e6e300ff..4a0c52955 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -449,7 +449,7 @@ impl Config { for pattern in options.values_of(options::IGNORE).into_iter().flatten() { match glob::Pattern::new(pattern) { Ok(p) => ignore_patterns.push(p), - Err(_) => show_error!("Invalid pattern for ignore: '{}'", pattern), + Err(_) => show_warning!("Invalid pattern for ignore: '{}'", pattern), } } @@ -457,7 +457,7 @@ impl Config { for pattern in options.values_of(options::HIDE).into_iter().flatten() { match glob::Pattern::new(pattern) { Ok(p) => ignore_patterns.push(p), - Err(_) => show_error!("Invalid pattern for hide: '{}'", pattern), + Err(_) => show_warning!("Invalid pattern for hide: '{}'", pattern), } } } From bbb27800c91770a79efc28f29ab42c91d586c1bf Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Sun, 4 Apr 2021 23:14:55 +0200 Subject: [PATCH 096/132] ls: fix windows tests and commit lock --- Cargo.lock | 1 + tests/by-util/test_ls.rs | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index ea1ee53ae..034cb4304 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1949,6 +1949,7 @@ version = "0.0.6" dependencies = [ "atty", "clap", + "glob 0.3.0", "lazy_static", "number_prefix", "term_grid", diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 377e12f74..cde5a8b8a 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1220,12 +1220,19 @@ fn test_ls_ignore_hide() { at.touch("some_other_file"); at.touch("READMECAREFULLY.md"); - scene.ucmd().arg("--hide").arg("*").succeeds().stdout_is(""); + scene + .ucmd() + .arg("--hide") + .arg("*") + .arg("-1") + .succeeds() + .stdout_is(""); scene .ucmd() .arg("--ignore") .arg("*") + .arg("-1") .succeeds() .stdout_is(""); @@ -1233,6 +1240,7 @@ fn test_ls_ignore_hide() { .ucmd() .arg("--ignore") .arg("irrelevant pattern") + .arg("-1") .succeeds() .stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); @@ -1240,6 +1248,7 @@ fn test_ls_ignore_hide() { .ucmd() .arg("--ignore") .arg("README*.md") + .arg("-1") .succeeds() .stdout_is("CONTRIBUTING.md\nsome_other_file\n"); @@ -1247,6 +1256,7 @@ fn test_ls_ignore_hide() { .ucmd() .arg("--hide") .arg("README*.md") + .arg("-1") .succeeds() .stdout_is("CONTRIBUTING.md\nsome_other_file\n"); @@ -1254,6 +1264,7 @@ fn test_ls_ignore_hide() { .ucmd() .arg("--ignore") .arg("*.md") + .arg("-1") .succeeds() .stdout_is("some_other_file\n"); @@ -1262,6 +1273,7 @@ fn test_ls_ignore_hide() { .arg("-a") .arg("--ignore") .arg("*.md") + .arg("-1") .succeeds() .stdout_is(".\n..\nsome_other_file\n"); @@ -1270,6 +1282,7 @@ fn test_ls_ignore_hide() { .arg("-a") .arg("--hide") .arg("*.md") + .arg("-1") .succeeds() .stdout_is(".\n..\nCONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); @@ -1278,6 +1291,7 @@ fn test_ls_ignore_hide() { .arg("-A") .arg("--ignore") .arg("*.md") + .arg("-1") .succeeds() .stdout_is("some_other_file\n"); @@ -1286,6 +1300,7 @@ fn test_ls_ignore_hide() { .arg("-A") .arg("--hide") .arg("*.md") + .arg("-1") .succeeds() .stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); @@ -1296,6 +1311,7 @@ fn test_ls_ignore_hide() { .arg("README*") .arg("--ignore") .arg("CONTRIBUTING*") + .arg("-1") .succeeds() .stdout_is("some_other_file\n"); @@ -1304,6 +1320,7 @@ fn test_ls_ignore_hide() { .ucmd() .arg("--ignore") .arg("READ[ME") + .arg("-1") .succeeds() .stderr_contains(&"Invalid pattern"); @@ -1311,6 +1328,7 @@ fn test_ls_ignore_hide() { .ucmd() .arg("--ignore") .arg("READ[ME") + .arg("-1") .succeeds() .stderr_contains(&"Invalid pattern"); } From 5134348a117481bb257961d71ba4c206de973410 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Sun, 4 Apr 2021 23:39:11 +0200 Subject: [PATCH 097/132] ls: use globset instead of glob --- src/uu/ls/Cargo.toml | 2 +- src/uu/ls/src/ls.rs | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index bf3860bf3..dacdc7cd9 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -22,7 +22,7 @@ term_grid = "0.1.5" termsize = "0.1.6" time = "0.1.40" unicode-width = "0.1.5" -glob = "0.3.0" +globset = "0.4.6" uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 4a0c52955..c4f9ae047 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -17,7 +17,7 @@ mod quoting_style; mod version_cmp; use clap::{App, Arg}; -use glob; +use globset::{self, Glob, GlobSet, GlobSetBuilder}; use number_prefix::NumberPrefix; use quoting_style::{escape_name, QuotingStyle}; #[cfg(unix)] @@ -194,7 +194,7 @@ struct Config { recursive: bool, reverse: bool, dereference: bool, - ignore_patterns: Vec, + ignore_patterns: GlobSet, size_format: SizeFormat, directory: bool, time: Time, @@ -440,28 +440,34 @@ impl Config { IndicatorStyle::None }; - let mut ignore_patterns = Vec::new(); + let mut ignore_patterns = GlobSetBuilder::new(); if options.is_present(options::IGNORE_BACKUPS) { - ignore_patterns.push(glob::Pattern::new("*~").unwrap()); - ignore_patterns.push(glob::Pattern::new(".*~").unwrap()); + ignore_patterns.add(Glob::new("*~").unwrap()); + ignore_patterns.add(Glob::new(".*~").unwrap()); } for pattern in options.values_of(options::IGNORE).into_iter().flatten() { - match glob::Pattern::new(pattern) { - Ok(p) => ignore_patterns.push(p), + match Glob::new(pattern) { + Ok(p) => { + ignore_patterns.add(p); + } Err(_) => show_warning!("Invalid pattern for ignore: '{}'", pattern), } } if files == Files::Normal { for pattern in options.values_of(options::HIDE).into_iter().flatten() { - match glob::Pattern::new(pattern) { - Ok(p) => ignore_patterns.push(p), + match Glob::new(pattern) { + Ok(p) => { + ignore_patterns.add(p); + } Err(_) => show_warning!("Invalid pattern for hide: '{}'", pattern), } } } + let ignore_patterns = ignore_patterns.build().unwrap(); + Config { format, files, @@ -1023,13 +1029,12 @@ fn is_hidden(file_path: &DirEntry) -> bool { fn should_display(entry: &DirEntry, config: &Config) -> bool { let ffi_name = entry.file_name(); - let name = ffi_name.to_string_lossy(); if config.files == Files::Normal && is_hidden(entry) { return false; } - if config.ignore_patterns.iter().any(|p| p.matches(&name)) { + if config.ignore_patterns.is_match(&ffi_name) { return false; } true From d68959d69683dbe3ad41f1205fa214ad5ccfe30d Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Mon, 5 Apr 2021 10:12:23 +0200 Subject: [PATCH 098/132] ls: update cargo.lock with globset --- Cargo.lock | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 034cb4304..f6dfc3246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -644,6 +644,19 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "globset" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + [[package]] name = "half" version = "1.7.1" @@ -1949,7 +1962,7 @@ version = "0.0.6" dependencies = [ "atty", "clap", - "glob 0.3.0", + "globset", "lazy_static", "number_prefix", "term_grid", From a50eae76a499699c0e2e47b4217db331c4a75b4d Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Mon, 5 Apr 2021 12:17:42 +0200 Subject: [PATCH 099/132] ls: some more tests for ignore & hide --- tests/by-util/test_ls.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index cde5a8b8a..0547560cc 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1315,6 +1315,26 @@ fn test_ls_ignore_hide() { .succeeds() .stdout_is("some_other_file\n"); + scene + .ucmd() + .arg("--hide") + .arg("README*") + .arg("--ignore") + .arg("CONTRIBUTING*") + .arg("-1") + .succeeds() + .stdout_is("some_other_file\n"); + + scene + .ucmd() + .arg("--hide") + .arg("README*") + .arg("--hide") + .arg("CONTRIBUTING*") + .arg("-1") + .succeeds() + .stdout_is("some_other_file\n"); + // Invalid patterns scene .ucmd() @@ -1326,7 +1346,7 @@ fn test_ls_ignore_hide() { scene .ucmd() - .arg("--ignore") + .arg("--hide") .arg("READ[ME") .arg("-1") .succeeds() From e5c61a28beb89d4c62b798663cbbbefc20d0e68e Mon Sep 17 00:00:00 2001 From: Daniel Rocco Date: Mon, 5 Apr 2021 00:16:21 -0400 Subject: [PATCH 100/132] fold: variable width tabs, guard treating tab as whitespace Treat tab chars as advancing to the next tab stop rather than having a fixed 8-column width. Also treat tab as a whitespace split target only when splitting on word boundaries. --- src/uu/fold/src/fold.rs | 11 +++- tests/by-util/test_fold.rs | 65 +++++++++++++++++++++- tests/fixtures/fold/tab_stops.input | 11 ++++ tests/fixtures/fold/tab_stops_w16.expected | 13 +++++ tests/fixtures/fold/tab_stops_w8.expected | 18 ++++++ 5 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/fold/tab_stops.input create mode 100644 tests/fixtures/fold/tab_stops_w16.expected create mode 100644 tests/fixtures/fold/tab_stops_w8.expected diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 8cf95b82a..fac0ff28e 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -14,6 +14,8 @@ use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; +const TAB_WIDTH: usize = 8; + static SYNTAX: &str = "[OPTION]... [FILE]..."; static SUMMARY: &str = "Writes each file (or standard input if no files are given) to standard output whilst breaking long lines"; @@ -220,11 +222,14 @@ fn fold_file(mut file: BufReader, spaces: bool, width: usize) { match ch { '\t' => { - if col_count + 8 > width && !output.is_empty() { + let next_tab_stop = col_count + TAB_WIDTH - col_count % TAB_WIDTH; + + if next_tab_stop > width && !output.is_empty() { emit_output!(); } - col_count += 8; - last_space = Some(char_count); + + col_count = next_tab_stop; + last_space = if spaces { Some(char_count) } else { None }; } '\x08' => { // FIXME: does not match GNU's handling of backspace diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index 52e630e5b..cc92c8ff3 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -132,7 +132,7 @@ fn test_single_tab_should_not_add_extra_newline() { } #[test] -fn test_tab_counts_as_8_columns() { +fn test_initial_tab_counts_as_8_columns() { new_ucmd!() .arg("-w8") .pipe_in("\t1") @@ -140,6 +140,33 @@ fn test_tab_counts_as_8_columns() { .stdout_is("\t\n1"); } +#[test] +fn test_tab_should_advance_to_next_tab_stop() { + // tab advances the column count to the next tab stop, i.e. the width + // of the tab varies based on the leading text + new_ucmd!() + .args(&["-w8", "tab_stops.input"]) + .succeeds() + .stdout_is_fixture("tab_stops_w8.expected"); +} + +#[test] +fn test_all_tabs_should_advance_to_next_tab_stops() { + new_ucmd!() + .args(&["-w16", "tab_stops.input"]) + .succeeds() + .stdout_is_fixture("tab_stops_w16.expected"); +} + +#[test] +fn test_fold_before_tab_with_narrow_width() { + new_ucmd!() + .arg("-w7") + .pipe_in("a\t1") + .succeeds() + .stdout_is("a\n\t\n1"); +} + #[test] fn test_fold_at_word_boundary() { new_ucmd!() @@ -167,8 +194,35 @@ fn test_fold_at_word_boundary_preserve_final_newline() { .stdout_is("one \ntwo\n"); } +#[test] +fn test_fold_at_tab() { + new_ucmd!() + .arg("-w8") + .pipe_in("a\tbbb\n") + .succeeds() + .stdout_is("a\t\nbbb\n"); +} + +#[test] +fn test_fold_after_tab() { + new_ucmd!() + .arg("-w10") + .pipe_in("a\tbbb\n") + .succeeds() + .stdout_is("a\tbb\nb\n"); +} + #[test] fn test_fold_at_tab_as_word_boundary() { + new_ucmd!() + .args(&["-w8", "-s"]) + .pipe_in("a\tbbb\n") + .succeeds() + .stdout_is("a\t\nbbb\n"); +} + +#[test] +fn test_fold_after_tab_as_word_boundary() { new_ucmd!() .args(&["-w10", "-s"]) .pipe_in("a\tbbb\n") @@ -317,6 +371,15 @@ fn test_tab_counts_as_one_byte() { .stdout_is("1\t\n2\n"); } +#[test] +fn test_bytewise_fold_before_tab_with_narrow_width() { + new_ucmd!() + .args(&["-w7", "-b"]) + .pipe_in("a\t1") + .succeeds() + .stdout_is("a\t1"); +} + #[test] fn test_bytewise_fold_at_word_boundary_only_whitespace() { new_ucmd!() diff --git a/tests/fixtures/fold/tab_stops.input b/tests/fixtures/fold/tab_stops.input new file mode 100644 index 000000000..a96a378ea --- /dev/null +++ b/tests/fixtures/fold/tab_stops.input @@ -0,0 +1,11 @@ +1 +12 +123 +1234 +12345 +123456 +1234567 +12345678 +123456781 +12345678 2 +12345678 2 4 diff --git a/tests/fixtures/fold/tab_stops_w16.expected b/tests/fixtures/fold/tab_stops_w16.expected new file mode 100644 index 000000000..8122ac16d --- /dev/null +++ b/tests/fixtures/fold/tab_stops_w16.expected @@ -0,0 +1,13 @@ +1 +12 +123 +1234 +12345 +123456 +1234567 +12345678 +123456781 +12345678 +2 +12345678 +2 4 diff --git a/tests/fixtures/fold/tab_stops_w8.expected b/tests/fixtures/fold/tab_stops_w8.expected new file mode 100644 index 000000000..3173a4a22 --- /dev/null +++ b/tests/fixtures/fold/tab_stops_w8.expected @@ -0,0 +1,18 @@ +1 +12 +123 +1234 +12345 +123456 +1234567 +12345678 + +12345678 +1 +12345678 + +2 +12345678 + +2 +4 From 3bfb1afe5c84099c4ae22f12ec91d6f59944b8a7 Mon Sep 17 00:00:00 2001 From: ReggaeMuffin <644950+reggaemuffin@users.noreply.github.com> Date: Mon, 5 Apr 2021 16:16:00 +0100 Subject: [PATCH 101/132] uucore: Start testing uucore Before this change we never ran tests on uucore itself meaning that is was not possible to test functions of the shared core, only their usage in the different binaries This change adds running uucore to our ci, which will increase coverage for the few doctests that exist and is extracted from #1988 where first tests for uucore will be introduced --- .github/workflows/CICD.yml | 13 ++++++++++++- README.md | 5 +++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index a1683ab83..cc0972bf9 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -150,7 +150,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: test - args: --features "feat_os_unix" + args: --features "feat_os_unix" -p uucore -p coreutils env: RUSTFLAGS: '-Awarnings' @@ -536,6 +536,17 @@ jobs: CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo "-puu_${u}"; done;)" echo set-output name=UTILITY_LIST::${UTILITY_LIST} echo ::set-output name=CARGO_UTILITY_LIST_OPTIONS::${CARGO_UTILITY_LIST_OPTIONS} + - name: Test uucore + uses: actions-rs/cargo@v1 + with: + command: test + args: ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-fail-fast -p uucore + env: + CARGO_INCREMENTAL: '0' + RUSTC_WRAPPER: '' + RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort' + RUSTDOCFLAGS: '-Cpanic=abort' + # RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }} - name: Test uses: actions-rs/cargo@v1 with: diff --git a/README.md b/README.md index b6d265278..b2257b3fd 100644 --- a/README.md +++ b/README.md @@ -226,6 +226,11 @@ If you would prefer to test a select few utilities: $ cargo test --features "chmod mv tail" --no-default-features ``` +If you also want to test the core utilities: +```bash +$ cargo test -p uucore -p coreutils +``` + To debug: ```bash $ gdb --args target/debug/coreutils ls From 196bfebc8ba6817a13e35628842315474d14eebf Mon Sep 17 00:00:00 2001 From: ReggaeMuffin <644950+reggaemuffin@users.noreply.github.com> Date: Mon, 5 Apr 2021 16:27:26 +0100 Subject: [PATCH 102/132] uucore: add uucore testing to travis and cirrus --- .cirrus.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 3a34a933a..5d16dce92 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -11,4 +11,4 @@ task: - cargo build test_script: - . $HOME/.cargo/env - - cargo test + - cargo test -p uucore -p coreutils diff --git a/.travis.yml b/.travis.yml index 27525b5f2..389ba44b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ install: script: - cargo build $CARGO_ARGS --features "$FEATURES" - - if [ ! $REDOX ]; then cargo test $CARGO_ARGS --features "$FEATURES" --no-fail-fast; fi + - if [ ! $REDOX ]; then cargo test $CARGO_ARGS -p uucore -p coreutils --features "$FEATURES" --no-fail-fast; fi - if [ -n "$TEST_INSTALL" ]; then mkdir installdir_test; DESTDIR=installdir_test make install; [ `ls installdir_test/usr/local/bin | wc -l` -gt 0 ]; fi addons: From 4dfbbecc26bdd6be326d81cae85a97c20bcb3fd3 Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Mon, 5 Apr 2021 21:48:39 +0200 Subject: [PATCH 103/132] relpath: refactor tests for #1982 --- tests/by-util/test_relpath.rs | 70 ++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/tests/by-util/test_relpath.rs b/tests/by-util/test_relpath.rs index 690531896..cc17b45c3 100644 --- a/tests/by-util/test_relpath.rs +++ b/tests/by-util/test_relpath.rs @@ -70,10 +70,10 @@ fn convert_path<'a>(path: &'a str) -> Cow<'a, str> { #[test] fn test_relpath_with_from_no_d() { - for test in TESTS.iter() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + for test in TESTS.iter() { let from: &str = &convert_path(test.from); let to: &str = &convert_path(test.to); let expected: &str = &convert_path(test.expected); @@ -92,10 +92,10 @@ fn test_relpath_with_from_no_d() { #[test] fn test_relpath_with_from_with_d() { - for test in TESTS.iter() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + for test in TESTS.iter() { let from: &str = &convert_path(test.from); let to: &str = &convert_path(test.to); let pwd = at.as_string(); @@ -103,63 +103,75 @@ fn test_relpath_with_from_with_d() { at.mkdir_all(from); // d is part of subpath -> expect relative path - let mut result = scene + let mut result_stdout = scene .ucmd() .arg(to) .arg(from) .arg(&format!("-d{}", pwd)) - .run(); - assert!(result.success); + .succeeds() + .stdout_move_str(); // relax rules for windows test environment #[cfg(not(windows))] - assert!(Path::new(&result.stdout).is_relative()); + assert!(Path::new(&result_stdout).is_relative()); // d is not part of subpath -> expect absolut path - result = scene.ucmd().arg(to).arg(from).arg("-dnon_existing").run(); - assert!(result.success); - assert!(Path::new(&result.stdout).is_absolute()); + result_stdout = scene + .ucmd() + .arg(to) + .arg(from) + .arg("-dnon_existing") + .succeeds() + .stdout_move_str(); + assert!(Path::new(&result_stdout).is_absolute()); } } #[test] fn test_relpath_no_from_no_d() { - for test in TESTS.iter() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + for test in TESTS.iter() { let to: &str = &convert_path(test.to); at.mkdir_all(to); - let result = scene.ucmd().arg(to).run(); - assert!(result.success); + let result_stdout = scene.ucmd().arg(to).succeeds().stdout_move_str(); #[cfg(not(windows))] - assert_eq!(result.stdout, format!("{}\n", to)); + assert_eq!(result_stdout, format!("{}\n", to)); // relax rules for windows test environment #[cfg(windows)] - assert!(result.stdout.ends_with(&format!("{}\n", to))); + assert!(result_stdout.ends_with(&format!("{}\n", to))); } } #[test] fn test_relpath_no_from_with_d() { - for test in TESTS.iter() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + for test in TESTS.iter() { let to: &str = &convert_path(test.to); let pwd = at.as_string(); at.mkdir_all(to); // d is part of subpath -> expect relative path - let mut result = scene.ucmd().arg(to).arg(&format!("-d{}", pwd)).run(); - assert!(result.success); + let mut result_stdout = scene + .ucmd() + .arg(to) + .arg(&format!("-d{}", pwd)) + .succeeds() + .stdout_move_str(); // relax rules for windows test environment #[cfg(not(windows))] - assert!(Path::new(&result.stdout).is_relative()); + assert!(Path::new(&result_stdout).is_relative()); // d is not part of subpath -> expect absolut path - result = scene.ucmd().arg(to).arg("-dnon_existing").run(); - assert!(result.success); - assert!(Path::new(&result.stdout).is_absolute()); + result_stdout = scene + .ucmd() + .arg(to) + .arg("-dnon_existing") + .succeeds() + .stdout_move_str(); + assert!(Path::new(&result_stdout).is_absolute()); } } From 9581fcf688c175673ebd4f51341469aead8bf949 Mon Sep 17 00:00:00 2001 From: Marvin Hofmann <644950+reggaemuffin@users.noreply.github.com> Date: Mon, 5 Apr 2021 21:18:47 +0100 Subject: [PATCH 104/132] rm: add verbose output and trim multiple slashes (#1988) * rm: add verbose output and trim multiple slashes Uses the normalize_path used in cargo to strip duplicate slashes With a link to a std rfc https://github.com/rust-lang/rfcs/issues/2208 This fixes https://github.com/uutils/coreutils/issues/1829 This also touches https://github.com/uutils/coreutils/issues/1768 but does not attempt to fully solve it --- src/uu/rm/Cargo.toml | 3 +- src/uu/rm/src/rm.rs | 16 ++++-- src/uucore/src/lib/features/fs.rs | 90 +++++++++++++++++++++++++++++++ tests/by-util/test_rm.rs | 29 ++++++++++ 4 files changed, 133 insertions(+), 5 deletions(-) diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index 961a8036c..9974111aa 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -18,7 +18,8 @@ path = "src/rm.rs" clap = "2.33" walkdir = "2.2" remove_dir_all = "0.5.1" -uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } + +uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } [[bin]] diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 033a1a4aa..09671768b 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -16,7 +16,7 @@ use std::collections::VecDeque; use std::fs; use std::io::{stderr, stdin, BufRead, Write}; use std::ops::BitOr; -use std::path::Path; +use std::path::{Path, PathBuf}; use walkdir::{DirEntry, WalkDir}; #[derive(Eq, PartialEq, Clone, Copy)] @@ -251,7 +251,7 @@ fn handle_dir(path: &Path, options: &Options) -> bool { let is_root = path.has_root() && path.parent().is_none(); if options.recursive && (!is_root || !options.preserve_root) { - if options.interactive != InteractiveMode::Always { + if options.interactive != InteractiveMode::Always && !options.verbose { // we need the extra crate because apparently fs::remove_dir_all() does not function // correctly on Windows if let Err(e) = remove_dir_all(path) { @@ -311,7 +311,7 @@ fn remove_dir(path: &Path, options: &Options) -> bool { match fs::remove_dir(path) { Ok(_) => { if options.verbose { - println!("removed directory '{}'", path.display()); + println!("removed directory '{}'", normalize(path).display()); } } Err(e) => { @@ -349,7 +349,7 @@ fn remove_file(path: &Path, options: &Options) -> bool { match fs::remove_file(path) { Ok(_) => { if options.verbose { - println!("removed '{}'", path.display()); + println!("removed '{}'", normalize(path).display()); } } Err(e) => { @@ -370,6 +370,14 @@ fn prompt_file(path: &Path, is_dir: bool) -> bool { } } +fn normalize(path: &Path) -> PathBuf { + // copied from https://github.com/rust-lang/cargo/blob/2e4cfc2b7d43328b207879228a2ca7d427d188bb/src/cargo/util/paths.rs#L65-L90 + // both projects are MIT https://github.com/rust-lang/cargo/blob/master/LICENSE-MIT + // for std impl progress see rfc https://github.com/rust-lang/rfcs/issues/2208 + // TODO: replace this once that lands + uucore::fs::normalize_path(path) +} + fn prompt(msg: &str) -> bool { let _ = stderr().write_all(msg.as_bytes()); let _ = stderr().flush(); diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs index adf4f6f82..a72d6ea82 100644 --- a/src/uucore/src/lib/features/fs.rs +++ b/src/uucore/src/lib/features/fs.rs @@ -60,6 +60,37 @@ pub enum CanonicalizeMode { Missing, } +// copied from https://github.com/rust-lang/cargo/blob/2e4cfc2b7d43328b207879228a2ca7d427d188bb/src/cargo/util/paths.rs#L65-L90 +// both projects are MIT https://github.com/rust-lang/cargo/blob/master/LICENSE-MIT +// for std impl progress see rfc https://github.com/rust-lang/rfcs/issues/2208 +// replace this once that lands +pub fn normalize_path(path: &Path) -> PathBuf { + let mut components = path.components().peekable(); + let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { + components.next(); + PathBuf::from(c.as_os_str()) + } else { + PathBuf::new() + }; + + for component in components { + match component { + Component::Prefix(..) => unreachable!(), + Component::RootDir => { + ret.push(component.as_os_str()); + } + Component::CurDir => {} + Component::ParentDir => { + ret.pop(); + } + Component::Normal(c) => { + ret.push(c); + } + } + } + ret +} + fn resolve>(original: P) -> IOResult { const MAX_LINKS_FOLLOWED: u32 = 255; let mut followed = 0; @@ -266,3 +297,62 @@ pub fn display_permissions_unix(mode: u32) -> String { result } + +#[cfg(test)] +mod tests { + // Note this useful idiom: importing names from outer (for mod tests) scope. + use super::*; + + struct NormalizePathTestCase<'a> { + path: &'a str, + test: &'a str, + } + + const NORMALIZE_PATH_TESTS: [NormalizePathTestCase; 8] = [ + NormalizePathTestCase { + path: "./foo/bar.txt", + test: "foo/bar.txt", + }, + NormalizePathTestCase { + path: "bar/../foo/bar.txt", + test: "foo/bar.txt", + }, + NormalizePathTestCase { + path: "foo///bar.txt", + test: "foo/bar.txt", + }, + NormalizePathTestCase { + path: "foo///bar", + test: "foo/bar", + }, + NormalizePathTestCase { + path: "foo//./bar", + test: "foo/bar", + }, + NormalizePathTestCase { + path: "/foo//./bar", + test: "/foo/bar", + }, + NormalizePathTestCase { + path: r"C:/you/later/", + test: "C:/you/later", + }, + NormalizePathTestCase { + path: "\\networkshare/a//foo//./bar", + test: "\\networkshare/a/foo/bar", + }, + ]; + + #[test] + fn test_normalize_path() { + for test in NORMALIZE_PATH_TESTS.iter() { + let path = Path::new(test.path); + let normalized = normalize_path(path); + assert_eq!( + test.test + .replace("/", std::path::MAIN_SEPARATOR.to_string().as_str()), + normalized.to_str().expect("Path is not valid utf-8!") + ); + } + } +} diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 149d509c5..0d77d9b01 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -263,3 +263,32 @@ fn test_rm_no_operand() { ucmd.fails() .stderr_is("rm: error: missing an argument\nrm: error: for help, try 'rm --help'\n"); } + +#[test] +fn test_rm_verbose_slash() { + let (at, mut ucmd) = at_and_ucmd!(); + let dir = "test_rm_verbose_slash_directory"; + let file_a = &format!("{}/test_rm_verbose_slash_file_a", dir); + + at.mkdir(dir); + at.touch(file_a); + + let file_a_normalized = &format!( + "{}{}test_rm_verbose_slash_file_a", + dir, + std::path::MAIN_SEPARATOR + ); + + ucmd.arg("-r") + .arg("-f") + .arg("-v") + .arg(&format!("{}///", dir)) + .succeeds() + .stdout_only(format!( + "removed '{}'\nremoved directory '{}'\n", + file_a_normalized, dir + )); + + assert!(!at.dir_exists(dir)); + assert!(!at.file_exists(file_a)); +} From cbe07c93c65c53437b17c6c7146c9044301b2c0d Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Mon, 5 Apr 2021 23:21:21 +0300 Subject: [PATCH 105/132] cksum: add tests and fixtures (#1923) --- tests/by-util/test_cksum.rs | 76 +++++++++++++++++++ tests/fixtures/cksum/chars.txt | 1 + .../fixtures/cksum/larger_than_2056_bytes.txt | 1 + 3 files changed, 78 insertions(+) create mode 100644 tests/fixtures/cksum/chars.txt create mode 100644 tests/fixtures/cksum/larger_than_2056_bytes.txt diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index d0bf5ffc8..8c8a551a0 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -24,3 +24,79 @@ fn test_stdin() { .succeeds() .stdout_is_fixture("stdin.expected"); } + +#[test] +fn test_empty() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.touch("a"); + + ucmd.arg("a").succeeds().stdout.ends_with("0 a"); +} + +#[test] +fn test_arg_overrides_stdin() { + let (at, mut ucmd) = at_and_ucmd!(); + let input = "foobarfoobar"; + + at.touch("a"); + + let result = ucmd.arg("a").pipe_in(input.as_bytes()).run(); + + println!("{}, {}", result.stdout, result.stderr); + + assert!(result.stdout.ends_with("0 a\n")) +} + +#[test] +fn test_invalid_file() { + let (_, mut ucmd) = at_and_ucmd!(); + + let ls = TestScenario::new("ls"); + let files = ls.cmd("ls").arg("-l").run(); + println!("{:?}", files.stdout); + println!("{:?}", files.stderr); + + let folder_name = "asdf".to_string(); + + let result = ucmd.arg(&folder_name).run(); + + println!("stdout: {:?}", result.stdout); + println!("stderr: {:?}", result.stderr); + assert!(result.stderr.contains("cksum: error: 'asdf'")); + assert!(!result.success); +} + +// Make sure crc is correct for files larger than 32 bytes +// but <128 bytes (1 fold pclmul) +#[test] +fn test_crc_for_bigger_than_32_bytes() { + let (_, mut ucmd) = at_and_ucmd!(); + + let result = ucmd.arg("chars.txt").run(); + + let mut stdout_splitted = result.stdout.split(" "); + + let cksum: i64 = stdout_splitted.next().unwrap().parse().unwrap(); + let bytes_cnt: i64 = stdout_splitted.next().unwrap().parse().unwrap(); + + assert!(result.success); + assert_eq!(cksum, 586047089); + assert_eq!(bytes_cnt, 16); +} + +#[test] +fn test_stdin_larger_than_128_bytes() { + let (_, mut ucmd) = at_and_ucmd!(); + + let result = ucmd.arg("larger_than_2056_bytes.txt").run(); + + let mut stdout_splitted = result.stdout.split(" "); + + let cksum: i64 = stdout_splitted.next().unwrap().parse().unwrap(); + let bytes_cnt: i64 = stdout_splitted.next().unwrap().parse().unwrap(); + + assert!(result.success); + assert_eq!(cksum, 945881979); + assert_eq!(bytes_cnt, 2058); +} diff --git a/tests/fixtures/cksum/chars.txt b/tests/fixtures/cksum/chars.txt new file mode 100644 index 000000000..26eec03fe --- /dev/null +++ b/tests/fixtures/cksum/chars.txt @@ -0,0 +1 @@ +123456789:;<=>?@ \ No newline at end of file diff --git a/tests/fixtures/cksum/larger_than_2056_bytes.txt b/tests/fixtures/cksum/larger_than_2056_bytes.txt new file mode 100644 index 000000000..668de449a --- /dev/null +++ b/tests/fixtures/cksum/larger_than_2056_bytes.txt @@ -0,0 +1 @@ +\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\400\401\402\403\404\405\406\407\410\411\412\413\414\415\416\417\420\421\422\423\424\425\426\427\430\431\432\433\434\435\436\437\440\441\442\443\444\445\446\447\450\451\452\453\454\455\456\457\460\461\462\463\464\465\466\467\470\471\472\473\474\475\476\477\500\501\502\503\504\505\506\507\510\511\512\513\514\515\516\517\520\521\522\523\524\525\526\527\530\531\532\533\534\535\536\537\540\541\542\543\544\545\546\547\550\551\552\553\554\555\556\557\560\561\562\563\564\565\566\567\570\571\572\573\574\575\576\577\600\601\602\603\604\605\606\607\610\611\612\613\614\615\616\617\620\621\622\623\624\625\626\627\630\631\632\633\634\635\636\637\640\641\642\643\644\645\646\647\650\651\652\653\654\655\656\657\660\661\662\663\664\665\666\667\670\671\672\673\674\675\676\677\700\701\702\703\704\705\706\707\710\711\712\713\714\715\716\717\720\721\722\723\724\725\726\727\730\731\732\733\734\735\736\737\740\741\742\743\744\745\746\747\750\751\752\753\754\755\756\757\760\761\762\763\764\765\766\767\770\771\772\773\774\775\776\777\1000\1001 \ No newline at end of file From de757cb0251d52826b7e87bfbc4f56025efad17f Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Mon, 5 Apr 2021 23:05:07 +0200 Subject: [PATCH 106/132] tee: refactor tests for #1982 --- tests/by-util/test_tee.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index f01677ae7..f2587a11f 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -68,15 +68,14 @@ fn test_tee_no_more_writeable_1() { .collect::(); let file_out = "tee_file_out"; - let result = ucmd - .arg("/dev/full") + ucmd.arg("/dev/full") .arg(file_out) .pipe_in(&content[..]) - .fails(); + .fails() + .stdout_contains(&content) + .stderr_contains(&"No space left on device"); assert_eq!(at.read(file_out), content); - assert!(result.stdout.contains(&content)); - assert!(result.stderr.contains("No space left on device")); } #[test] From cbc5132981a099854e0c9fd1464214c9620db58f Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Mon, 5 Apr 2021 23:06:56 +0200 Subject: [PATCH 107/132] ls: add short option for ignore --- src/uu/ls/src/ls.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index c4f9ae047..09fb3a7ea 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -704,6 +704,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { ) .arg( Arg::with_name(options::IGNORE) + .short("I") .long(options::IGNORE) .takes_value(true) .multiple(true) From cc30aead2241414d026b079e690afe1338fd3d74 Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Mon, 5 Apr 2021 23:55:02 +0200 Subject: [PATCH 108/132] realpath: refactor tests for #1982 --- tests/by-util/test_realpath.rs | 98 +++++++++++++++++----------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/tests/by-util/test_realpath.rs b/tests/by-util/test_realpath.rs index 750a8db01..e1384ac74 100644 --- a/tests/by-util/test_realpath.rs +++ b/tests/by-util/test_realpath.rs @@ -1,106 +1,108 @@ use crate::common::util::*; #[test] -fn test_current_directory() { +fn test_realpath_current_directory() { let (at, mut ucmd) = at_and_ucmd!(); - let actual = ucmd.arg(".").run().stdout; let expect = at.root_dir_resolved() + "\n"; - println!("actual: {:?}", actual); - println!("expect: {:?}", expect); - assert_eq!(actual, expect); + ucmd.arg(".").succeeds().stdout_is(expect); } #[test] -fn test_long_redirection_to_current_dir() { +fn test_realpath_long_redirection_to_current_dir() { let (at, mut ucmd) = at_and_ucmd!(); // Create a 256-character path to current directory let dir = path_concat!(".", ..128); - let actual = ucmd.arg(dir).run().stdout; let expect = at.root_dir_resolved() + "\n"; - println!("actual: {:?}", actual); - println!("expect: {:?}", expect); - assert_eq!(actual, expect); + ucmd.arg(dir).succeeds().stdout_is(expect); } #[test] -fn test_long_redirection_to_root() { +fn test_realpath_long_redirection_to_root() { // Create a 255-character path to root let dir = path_concat!("..", ..85); - let actual = new_ucmd!().arg(dir).run().stdout; let expect = get_root_path().to_owned() + "\n"; - println!("actual: {:?}", actual); - println!("expect: {:?}", expect); - assert_eq!(actual, expect); + new_ucmd!().arg(dir).succeeds().stdout_is(expect); } #[test] -fn test_file_and_links() { +fn test_realpath_file_and_links() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.touch("foo"); at.symlink_file("foo", "bar"); - let actual = scene.ucmd().arg("foo").run().stdout; - println!("actual: {:?}", actual); - assert!(actual.contains("foo\n")); - - let actual = scene.ucmd().arg("bar").run().stdout; - println!("actual: {:?}", actual); - assert!(actual.contains("foo\n")); + scene.ucmd().arg("foo").succeeds().stdout_contains("foo\n"); + scene.ucmd().arg("bar").succeeds().stdout_contains("foo\n"); } #[test] -fn test_file_and_links_zero() { +fn test_realpath_file_and_links_zero() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.touch("foo"); at.symlink_file("foo", "bar"); - let actual = scene.ucmd().arg("foo").arg("-z").run().stdout; - println!("actual: {:?}", actual); - assert!(actual.contains("foo")); - assert!(!actual.contains("\n")); + scene + .ucmd() + .arg("foo") + .arg("-z") + .succeeds() + .stdout_contains("foo\u{0}"); - let actual = scene.ucmd().arg("bar").arg("-z").run().stdout; - println!("actual: {:?}", actual); - assert!(actual.contains("foo")); - assert!(!actual.contains("\n")); + scene + .ucmd() + .arg("bar") + .arg("-z") + .succeeds() + .stdout_contains("foo\u{0}"); } #[test] -fn test_file_and_links_strip() { +fn test_realpath_file_and_links_strip() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.touch("foo"); at.symlink_file("foo", "bar"); - let actual = scene.ucmd().arg("foo").arg("-s").run().stdout; - println!("actual: {:?}", actual); - assert!(actual.contains("foo\n")); + scene + .ucmd() + .arg("foo") + .arg("-s") + .succeeds() + .stdout_contains("foo\n"); - let actual = scene.ucmd().arg("bar").arg("-s").run().stdout; - println!("actual: {:?}", actual); - assert!(actual.contains("bar\n")); + scene + .ucmd() + .arg("bar") + .arg("-s") + .succeeds() + .stdout_contains("bar\n"); } #[test] -fn test_file_and_links_strip_zero() { +fn test_realpath_file_and_links_strip_zero() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.touch("foo"); at.symlink_file("foo", "bar"); - let actual = scene.ucmd().arg("foo").arg("-s").arg("-z").run().stdout; - println!("actual: {:?}", actual); - assert!(actual.contains("foo")); - assert!(!actual.contains("\n")); + scene + .ucmd() + .arg("foo") + .arg("-s") + .arg("-z") + .succeeds() + .stdout_contains("foo\u{0}"); - let actual = scene.ucmd().arg("bar").arg("-s").arg("-z").run().stdout; - println!("actual: {:?}", actual); - assert!(actual.contains("bar")); - assert!(!actual.contains("\n")); + scene + .ucmd() + .arg("bar") + .arg("-s") + .arg("-z") + .succeeds() + .stdout_contains("bar\u{0}"); } From 057ceebdb032f049dd2905d87c78df8aea59ebc0 Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Tue, 6 Apr 2021 00:04:49 +0200 Subject: [PATCH 109/132] rm: refactor tests for #1982 --- tests/by-util/test_rm.rs | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 0d77d9b01..9a068887c 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -15,14 +15,12 @@ fn test_rm_one_file() { #[test] fn test_rm_failed() { let (_at, mut ucmd) = at_and_ucmd!(); - let file = "test_rm_one_file"; + let file = "test_rm_one_file"; // Doesn't exist - let result = ucmd.arg(file).fails(); // Doesn't exist - - assert!(result.stderr.contains(&format!( + ucmd.arg(file).fails().stderr_contains(&format!( "cannot remove '{}': No such file or directory", file - ))); + )); } #[test] @@ -145,10 +143,10 @@ fn test_rm_non_empty_directory() { at.mkdir(dir); at.touch(file_a); - let result = ucmd.arg("-d").arg(dir).fails(); - assert!(result - .stderr - .contains(&format!("cannot remove '{}': Directory not empty", dir))); + ucmd.arg("-d") + .arg(dir) + .fails() + .stderr_contains(&format!("cannot remove '{}': Directory not empty", dir)); assert!(at.file_exists(file_a)); assert!(at.dir_exists(dir)); } @@ -178,11 +176,9 @@ fn test_rm_directory_without_flag() { at.mkdir(dir); - let result = ucmd.arg(dir).fails(); - println!("{}", result.stderr); - assert!(result - .stderr - .contains(&format!("cannot remove '{}': Is a directory", dir))); + ucmd.arg(dir) + .fails() + .stderr_contains(&format!("cannot remove '{}': Is a directory", dir)); } #[test] @@ -229,10 +225,11 @@ fn test_rm_symlink_dir() { at.mkdir(dir); at.symlink_dir(dir, link); - let result = scene.ucmd().arg(link).fails(); - assert!(result - .stderr - .contains(&format!("cannot remove '{}': Is a directory", link))); + scene + .ucmd() + .arg(link) + .fails() + .stderr_contains(&format!("cannot remove '{}': Is a directory", link)); assert!(at.dir_exists(link)); From 0b731dfd1a2cb6fd15ef341d6e03150b5fdaffbe Mon Sep 17 00:00:00 2001 From: Daniel Rocco Date: Mon, 5 Apr 2021 20:39:43 -0400 Subject: [PATCH 110/132] fold: preserve backspace and overwritten chars in output --- src/uu/fold/src/fold.rs | 6 +--- tests/by-util/test_fold.rs | 73 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index fac0ff28e..3bcb55e51 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -232,13 +232,9 @@ fn fold_file(mut file: BufReader, spaces: bool, width: usize) { last_space = if spaces { Some(char_count) } else { None }; } '\x08' => { - // FIXME: does not match GNU's handling of backspace if col_count > 0 { col_count -= 1; - char_count -= 1; - output.truncate(char_count); } - continue; } '\r' => { // FIXME: does not match GNU's handling of carriage return @@ -258,7 +254,7 @@ fn fold_file(mut file: BufReader, spaces: bool, width: usize) { char_count += 1; } - if col_count > 0 { + if char_count > 0 { print!("{}", output); output.truncate(0); } diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index cc92c8ff3..287b05157 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -248,6 +248,43 @@ fn test_fold_at_word_boundary_only_whitespace_preserve_final_newline() { .stdout_is(" \n \n"); } +#[test] +fn test_backspace_should_be_preserved() { + new_ucmd!().pipe_in("\x08").succeeds().stdout_is("\x08"); +} + +#[test] +fn test_backspaced_char_should_be_preserved() { + new_ucmd!().pipe_in("x\x08").succeeds().stdout_is("x\x08"); +} + +#[test] +fn test_backspace_should_decrease_column_count() { + new_ucmd!() + .arg("-w2") + .pipe_in("1\x08345") + .succeeds() + .stdout_is("1\x0834\n5"); +} + +#[test] +fn test_backspace_should_not_decrease_column_count_past_zero() { + new_ucmd!() + .arg("-w2") + .pipe_in("1\x08\x083456") + .succeeds() + .stdout_is("1\x08\x0834\n56"); +} + +#[test] +fn test_backspace_is_not_word_boundary() { + new_ucmd!() + .args(&["-w10", "-s"]) + .pipe_in("foobar\x086789abcdef") + .succeeds() + .stdout_is("foobar\x086789a\nbcdef"); +} + // // bytewise tests @@ -397,3 +434,39 @@ fn test_bytewise_fold_at_word_boundary_only_whitespace_preserve_final_newline() .succeeds() .stdout_is(" \n \n"); } + +#[test] +fn test_bytewise_backspace_should_be_preserved() { + new_ucmd!() + .arg("-b") + .pipe_in("\x08") + .succeeds() + .stdout_is("\x08"); +} + +#[test] +fn test_bytewise_backspaced_char_should_be_preserved() { + new_ucmd!() + .arg("-b") + .pipe_in("x\x08") + .succeeds() + .stdout_is("x\x08"); +} + +#[test] +fn test_bytewise_backspace_should_not_decrease_column_count() { + new_ucmd!() + .args(&["-w2", "-b"]) + .pipe_in("1\x08345") + .succeeds() + .stdout_is("1\x08\n34\n5"); +} + +#[test] +fn test_bytewise_backspace_is_not_word_boundary() { + new_ucmd!() + .args(&["-w10", "-s", "-b"]) + .pipe_in("foobar\x0889abcdef") + .succeeds() + .stdout_is("foobar\x0889a\nbcdef"); +} From 56bc7a44ebaaceb1f7338895dce489090044f8c8 Mon Sep 17 00:00:00 2001 From: Daniel Rocco Date: Mon, 5 Apr 2021 21:41:25 -0400 Subject: [PATCH 111/132] fold: preserve carriage return and overwritten chars in output --- src/uu/fold/src/fold.rs | 23 +++++--------- tests/by-util/test_fold.rs | 64 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 3bcb55e51..54cb41e27 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -132,7 +132,7 @@ fn fold_file_bytewise(mut file: BufReader, spaces: bool, width: usiz let slice = { let slice = &line[i..i + width]; if spaces && i + width < len { - match slice.rfind(char::is_whitespace) { + match slice.rfind(|c: char| c.is_whitespace() && c != '\r') { Some(m) => &slice[..=m], None => slice, } @@ -175,7 +175,6 @@ fn fold_file(mut file: BufReader, spaces: bool, width: usize) { let mut line = String::new(); let mut output = String::new(); let mut col_count = 0; - let mut char_count = 0; let mut last_space = None; /// Print the output line, resetting the column and character counts. @@ -192,11 +191,10 @@ fn fold_file(mut file: BufReader, spaces: bool, width: usize) { println!("{}", &output[..consume]); output.replace_range(..consume, ""); - char_count = output.len(); // we know there are no tabs left in output, so each char counts // as 1 column - col_count = char_count; + col_count = output.len(); last_space = None; }; @@ -221,6 +219,7 @@ fn fold_file(mut file: BufReader, spaces: bool, width: usize) { } match ch { + '\r' => col_count = 0, '\t' => { let next_tab_stop = col_count + TAB_WIDTH - col_count % TAB_WIDTH; @@ -229,32 +228,24 @@ fn fold_file(mut file: BufReader, spaces: bool, width: usize) { } col_count = next_tab_stop; - last_space = if spaces { Some(char_count) } else { None }; + last_space = if spaces { Some(output.len()) } else { None }; } '\x08' => { if col_count > 0 { col_count -= 1; } } - '\r' => { - // FIXME: does not match GNU's handling of carriage return - output.truncate(0); - col_count = 0; - char_count = 0; - continue; - } _ if spaces && ch.is_whitespace() => { - last_space = Some(char_count); - col_count += 1 + last_space = Some(output.len()); + col_count += 1; } _ => col_count += 1, }; output.push(ch); - char_count += 1; } - if char_count > 0 { + if !output.is_empty() { print!("{}", output); output.truncate(0); } diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index 287b05157..61c057782 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -285,6 +285,34 @@ fn test_backspace_is_not_word_boundary() { .stdout_is("foobar\x086789a\nbcdef"); } +#[test] +fn test_carriage_return_should_be_preserved() { + new_ucmd!().pipe_in("\r").succeeds().stdout_is("\r"); +} + +#[test] +fn test_carriage_return_overwrriten_char_should_be_preserved() { + new_ucmd!().pipe_in("x\ry").succeeds().stdout_is("x\ry"); +} + +#[test] +fn test_carriage_return_should_reset_column_count() { + new_ucmd!() + .arg("-w6") + .pipe_in("12345\r123456789abcdef") + .succeeds() + .stdout_is("12345\r123456\n789abc\ndef"); +} + +#[test] +fn test_carriage_return_is_not_word_boundary() { + new_ucmd!() + .args(&["-w6", "-s"]) + .pipe_in("fizz\rbuzz\rfizzbuzz") + .succeeds() + .stdout_is("fizz\rbuzz\rfizzbu\nzz"); +} + // // bytewise tests @@ -470,3 +498,39 @@ fn test_bytewise_backspace_is_not_word_boundary() { .succeeds() .stdout_is("foobar\x0889a\nbcdef"); } + +#[test] +fn test_bytewise_carriage_return_should_be_preserved() { + new_ucmd!() + .arg("-b") + .pipe_in("\r") + .succeeds() + .stdout_is("\r"); +} + +#[test] +fn test_bytewise_carriage_return_overwrriten_char_should_be_preserved() { + new_ucmd!() + .arg("-b") + .pipe_in("x\ry") + .succeeds() + .stdout_is("x\ry"); +} + +#[test] +fn test_bytewise_carriage_return_should_not_reset_column_count() { + new_ucmd!() + .args(&["-w6", "-b"]) + .pipe_in("12345\r123456789abcdef") + .succeeds() + .stdout_is("12345\r\n123456\n789abc\ndef"); +} + +#[test] +fn test_bytewise_carriage_return_is_not_word_boundary() { + new_ucmd!() + .args(&["-w6", "-s", "-b"]) + .pipe_in("fizz\rbuzz\rfizzbuzz") + .succeeds() + .stdout_is("fizz\rb\nuzz\rfi\nzzbuzz"); +} From bc426fb3af7bc68c4ef575775a6196f8d21d1ff3 Mon Sep 17 00:00:00 2001 From: Gilad Naaman Date: Tue, 6 Apr 2021 01:59:25 +0300 Subject: [PATCH 112/132] Fixed panic!/assert! used with improper format strings --- src/uu/od/src/inputdecoder.rs | 51 +++++++++++++++-------------------- src/uucore/src/lib/macros.rs | 4 +-- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/uu/od/src/inputdecoder.rs b/src/uu/od/src/inputdecoder.rs index 3b36c28fb..f6ba59885 100644 --- a/src/uu/od/src/inputdecoder.rs +++ b/src/uu/od/src/inputdecoder.rs @@ -166,39 +166,30 @@ mod tests { let mut input = PeekReader::new(Cursor::new(&data)); let mut sut = InputDecoder::new(&mut input, 8, 2, ByteOrder::Little); - match sut.peek_read() { - Ok(mut mem) => { - assert_eq!(8, mem.length()); + // Peek normal length + let mut mem = sut.peek_read().unwrap(); - assert_eq!(-2.0, mem.read_float(0, 8)); - assert_eq!(-2.0, mem.read_float(4, 4)); - assert_eq!(0xc000000000000000, mem.read_uint(0, 8)); - assert_eq!(0xc0000000, mem.read_uint(4, 4)); - assert_eq!(0xc000, mem.read_uint(6, 2)); - assert_eq!(0xc0, mem.read_uint(7, 1)); - assert_eq!(&[0, 0xc0], mem.get_buffer(6)); - assert_eq!(&[0, 0xc0, 0xff, 0xff], mem.get_full_buffer(6)); + assert_eq!(8, mem.length()); - let mut copy: Vec = Vec::new(); - mem.clone_buffer(&mut copy); - assert_eq!(vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0], copy); + assert_eq!(-2.0, mem.read_float(0, 8)); + assert_eq!(-2.0, mem.read_float(4, 4)); + assert_eq!(0xc000000000000000, mem.read_uint(0, 8)); + assert_eq!(0xc0000000, mem.read_uint(4, 4)); + assert_eq!(0xc000, mem.read_uint(6, 2)); + assert_eq!(0xc0, mem.read_uint(7, 1)); + assert_eq!(&[0, 0xc0], mem.get_buffer(6)); + assert_eq!(&[0, 0xc0, 0xff, 0xff], mem.get_full_buffer(6)); - mem.zero_out_buffer(7, 8); - assert_eq!(&[0, 0, 0xff, 0xff], mem.get_full_buffer(6)); - } - Err(e) => { - assert!(false, e); - } - } + let mut copy: Vec = Vec::new(); + mem.clone_buffer(&mut copy); + assert_eq!(vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0], copy); - match sut.peek_read() { - Ok(mem) => { - assert_eq!(2, mem.length()); - assert_eq!(0xffff, mem.read_uint(0, 2)); - } - Err(e) => { - assert!(false, e); - } - } + mem.zero_out_buffer(7, 8); + assert_eq!(&[0, 0, 0xff, 0xff], mem.get_full_buffer(6)); + + // Peek tail + let mem = sut.peek_read().unwrap(); + assert_eq!(2, mem.length()); + assert_eq!(0xffff, mem.read_uint(0, 2)); } } diff --git a/src/uucore/src/lib/macros.rs b/src/uucore/src/lib/macros.rs index 6836f81aa..24b392ebd 100644 --- a/src/uucore/src/lib/macros.rs +++ b/src/uucore/src/lib/macros.rs @@ -108,7 +108,7 @@ macro_rules! safe_write( ($fd:expr, $($args:tt)+) => ( match write!($fd, $($args)+) { Ok(_) => {} - Err(f) => panic!(f.to_string()) + Err(f) => panic!("{}", f) } ) ); @@ -118,7 +118,7 @@ macro_rules! safe_writeln( ($fd:expr, $($args:tt)+) => ( match writeln!($fd, $($args)+) { Ok(_) => {} - Err(f) => panic!(f.to_string()) + Err(f) => panic!("{}", f) } ) ); From f9fc3b5a1d3259c12d3175c514cdb397c0ae6cae Mon Sep 17 00:00:00 2001 From: Wisha Wa Date: Tue, 6 Apr 2021 13:19:27 +0000 Subject: [PATCH 113/132] ptx: add explaination comments, replace mut with shadowing, and rename variables for clarity. --- src/uu/ptx/src/ptx.rs | 91 +++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 24 deletions(-) diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index 6b3dae27f..65e310576 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -224,6 +224,9 @@ fn read_input(input_files: &[String], config: &Config) -> FileMap { Box::new(file) }); let lines: Vec = reader.lines().map(|x| crash_if_err!(1, x)).collect(); + + // Indexing UTF-8 string requires walking from the beginning, which can hurts performance badly when the line is long. + // Since we will be jumping around the line a lot, we dump the content into a Vec, which can be indexed in constant time. let chars_lines: Vec> = lines.iter().map(|x| x.chars().collect()).collect(); let size = lines.len(); file_map.insert( @@ -239,6 +242,7 @@ fn read_input(input_files: &[String], config: &Config) -> FileMap { file_map } +/// Go through every lines in the input files and record each match occurance as a `WordRef`. fn create_word_set(config: &Config, filter: &WordFilter, file_map: &FileMap) -> BTreeSet { let reg = Regex::new(&filter.word_regex).unwrap(); let ref_reg = Regex::new(&config.context_regex).unwrap(); @@ -345,6 +349,8 @@ fn get_output_chunks( all_after: &[char], config: &Config, ) -> (String, String, String, String) { + // Chunk size logics are mostly copied from the GNU ptx source. + // https://github.com/MaiZure/coreutils-8.3/blob/master/src/ptx.c#L1234 let half_line_size = (config.line_width / 2) as usize; let max_before_size = cmp::max(half_line_size as isize - config.gap_size as isize, 0) as usize; let max_after_size = cmp::max( @@ -355,56 +361,92 @@ fn get_output_chunks( 0, ) as usize; + // Allocate plenty space for all the chunks. let mut head = String::with_capacity(half_line_size); let mut before = String::with_capacity(half_line_size); let mut after = String::with_capacity(half_line_size); let mut tail = String::with_capacity(half_line_size); - // get before - let (_, be) = trim_idx(all_before, 0, all_before.len()); - let mut bb_tmp = cmp::max(be as isize - max_before_size as isize, 0) as usize; - bb_tmp = trim_broken_word_left(all_before, bb_tmp, be); - let (before_beg, before_end) = trim_idx(all_before, bb_tmp, be); + // the before chunk + + // trim whitespace away from all_before to get the index where the before chunk should end. + let (_, before_end) = trim_idx(all_before, 0, all_before.len()); + + // the minimum possible begin index of the before_chunk is the end index minus the length. + let before_beg = cmp::max(before_end as isize - max_before_size as isize, 0) as usize; + // in case that falls in the middle of a word, trim away the word. + let before_beg = trim_broken_word_left(all_before, before_beg, before_end); + + // trim away white space. + let (before_beg, before_end) = trim_idx(all_before, before_beg, before_end); + + // and get the string. let before_str: String = all_before[before_beg..before_end].iter().collect(); before.push_str(&before_str); assert!(max_before_size >= before.len()); - // get after - let mut ae_tmp = cmp::min(max_after_size, all_after.len()); - ae_tmp = trim_broken_word_right(all_after, 0, ae_tmp); - let (_, after_end) = trim_idx(all_after, 0, ae_tmp); + // the after chunk + + // must be no longer than the minimum between the max size and the total available string. + let after_end = cmp::min(max_after_size, all_after.len()); + // in case that falls in the middle of a word, trim away the word. + let after_end = trim_broken_word_right(all_after, 0, after_end); + + // trim away white space. + let (_, after_end) = trim_idx(all_after, 0, after_end); + + // and get the string let after_str: String = all_after[0..after_end].iter().collect(); after.push_str(&after_str); assert!(max_after_size >= after.len()); - // get tail + // the tail chunk + + // max size of the tail chunk = max size of left half - space taken by before chunk - gap size. let max_tail_size = cmp::max( max_before_size as isize - before.len() as isize - config.gap_size as isize, 0, ) as usize; - let (tb, _) = trim_idx(all_after, after_end, all_after.len()); - let mut te_tmp = cmp::min(all_after.len(), tb + max_tail_size) as usize; - te_tmp = trim_broken_word_right( + + // the tail chunk takes text starting from where the after chunk ends (with whitespaces trimmed). + let (tail_beg, _) = trim_idx(all_after, after_end, all_after.len()); + + // end = begin + max length + let tail_end = cmp::min(all_after.len(), tail_beg + max_tail_size) as usize; + // in case that falls in the middle of a word, trim away the word. + let tail_end = trim_broken_word_right( all_after, - tb, - cmp::max(te_tmp as isize - 1, tb as isize) as usize, + tail_beg, + cmp::max(tail_end as isize - 1, tail_beg as isize) as usize, ); - let (tail_beg, tail_end) = trim_idx(all_after, tb, te_tmp); + + // trim away whitespace again. + let (tail_beg, tail_end) = trim_idx(all_after, tail_beg, tail_end); + + // and get the string let tail_str: String = all_after[tail_beg..tail_end].iter().collect(); tail.push_str(&tail_str); - // get head + // the head chunk + + // max size of the head chunk = max size of right half - space taken by after chunk - gap size. let max_head_size = cmp::max( max_after_size as isize - after.len() as isize - config.gap_size as isize, 0, ) as usize; - let (_, he) = trim_idx(all_before, 0, before_beg); - let hb_tmp = trim_broken_word_left( - all_before, - cmp::max(he as isize - max_head_size as isize, 0) as usize, - he, - ); - let (head_beg, head_end) = trim_idx(all_before, hb_tmp, he); + + // the head chunk takes text from before the before chunk + let (_, head_end) = trim_idx(all_before, 0, before_beg); + + // begin = end - max length + let head_beg = cmp::max(head_end as isize - max_head_size as isize, 0) as usize; + // in case that falls in the middle of a word, trim away the word. + let head_beg = trim_broken_word_left(all_before, head_beg, head_end); + + // trim away white space again. + let (head_beg, head_end) = trim_idx(all_before, head_beg, head_end); + + // and get the string. let head_str: String = all_before[head_beg..head_end].iter().collect(); head.push_str(&head_str); @@ -434,6 +476,7 @@ fn tex_mapper(x: char) -> String { } } +/// Escape special characters for TeX. fn format_tex_field(s: &str) -> String { let mapped_chunks: Vec = s.chars().map(tex_mapper).collect(); mapped_chunks.join("") From 5fc007b295230730bb2b67d3db32fb7defcac6a3 Mon Sep 17 00:00:00 2001 From: Wisha Wa Date: Tue, 6 Apr 2021 13:40:14 +0000 Subject: [PATCH 114/132] ptx: remove a hack that was added in attempt to mimick GNU ptx --- src/uu/ptx/src/ptx.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index 65e310576..6d30d471b 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -414,11 +414,7 @@ fn get_output_chunks( // end = begin + max length let tail_end = cmp::min(all_after.len(), tail_beg + max_tail_size) as usize; // in case that falls in the middle of a word, trim away the word. - let tail_end = trim_broken_word_right( - all_after, - tail_beg, - cmp::max(tail_end as isize - 1, tail_beg as isize) as usize, - ); + let tail_end = trim_broken_word_right(all_after, tail_beg, tail_end); // trim away whitespace again. let (tail_beg, tail_end) = trim_idx(all_after, tail_beg, tail_end); From 7b20c79bddb52e6b726d70ac22ede33dc80eed78 Mon Sep 17 00:00:00 2001 From: Wisha Wa Date: Tue, 6 Apr 2021 18:07:02 +0000 Subject: [PATCH 115/132] ptx: fix an incorrect option name in option parsing --- src/uu/ptx/src/ptx.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index 6d30d471b..38327e4e3 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -169,9 +169,9 @@ fn get_config(matches: &clap::ArgMatches) -> Config { .expect(err_msg) .to_string(); } - if matches.is_present(options::IGNORE_CASE) { + if matches.is_present(options::FLAG_TRUNCATION) { config.trunc_str = matches - .value_of(options::IGNORE_CASE) + .value_of(options::FLAG_TRUNCATION) .expect(err_msg) .to_string(); } From c965effe07b80b726f108d80d77e01da7705f2fd Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Tue, 6 Apr 2021 23:51:27 +0300 Subject: [PATCH 116/132] fold: move to clap, add tests (#2015) --- Cargo.lock | 1 + src/uu/fold/Cargo.toml | 1 + src/uu/fold/src/fold.rs | 76 ++++++++++++------- tests/by-util/test_fold.rs | 10 +++ tests/fixtures/fold/space_separated_words.txt | 1 + 5 files changed, 63 insertions(+), 26 deletions(-) create mode 100644 tests/fixtures/fold/space_separated_words.txt diff --git a/Cargo.lock b/Cargo.lock index ce4457231..f65ba3dff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1861,6 +1861,7 @@ dependencies = [ name = "uu_fold" version = "0.0.6" dependencies = [ + "clap", "uucore", "uucore_procs", ] diff --git a/src/uu/fold/Cargo.toml b/src/uu/fold/Cargo.toml index f99abc691..c5578384e 100644 --- a/src/uu/fold/Cargo.toml +++ b/src/uu/fold/Cargo.toml @@ -15,6 +15,7 @@ edition = "2018" path = "src/fold.rs" [dependencies] +clap = "2.33" uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index fac0ff28e..e19e9db19 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -10,48 +10,71 @@ #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; const TAB_WIDTH: usize = 8; +static NAME: &str = "fold"; +static VERSION: &str = env!("CARGO_PKG_VERSION"); static SYNTAX: &str = "[OPTION]... [FILE]..."; static SUMMARY: &str = "Writes each file (or standard input if no files are given) to standard output whilst breaking long lines"; -static LONG_HELP: &str = ""; + +mod options { + pub const BYTES: &str = "bytes"; + pub const SPACES: &str = "spaces"; + pub const WIDTH: &str = "width"; + pub const FILE: &str = "file"; +} pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); let (args, obs_width) = handle_obsolete(&args[..]); - let matches = app!(SYNTAX, SUMMARY, LONG_HELP) - .optflag( - "b", - "bytes", - "count using bytes rather than columns (meaning control characters \ + let matches = App::new(executable!()) + .name(NAME) + .version(VERSION) + .usage(SYNTAX) + .about(SUMMARY) + .arg( + Arg::with_name(options::BYTES) + .long(options::BYTES) + .short("b") + .help( + "count using bytes rather than columns (meaning control characters \ such as newline are not treated specially)", + ) + .takes_value(false), ) - .optflag( - "s", - "spaces", - "break lines at word boundaries rather than a hard cut-off", + .arg( + Arg::with_name(options::SPACES) + .long(options::SPACES) + .short("s") + .help("break lines at word boundaries rather than a hard cut-off") + .takes_value(false), ) - .optopt( - "w", - "width", - "set WIDTH as the maximum line width rather than 80", - "WIDTH", + .arg( + Arg::with_name(options::WIDTH) + .long(options::WIDTH) + .short("w") + .help("set WIDTH as the maximum line width rather than 80") + .value_name("WIDTH") + .allow_hyphen_values(true) + .takes_value(true), ) - .parse(args); + .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) + .get_matches_from(args.clone()); - let bytes = matches.opt_present("b"); - let spaces = matches.opt_present("s"); - let poss_width = if matches.opt_present("w") { - matches.opt_str("w") - } else { - obs_width + let bytes = matches.is_present(options::BYTES); + let spaces = matches.is_present(options::SPACES); + let poss_width = match matches.value_of(options::WIDTH) { + Some(v) => Some(v.to_owned()), + None => obs_width, }; + let width = match poss_width { Some(inp_width) => match inp_width.parse::() { Ok(width) => width, @@ -59,11 +82,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 { }, None => 80, }; - let files = if matches.free.is_empty() { - vec!["-".to_owned()] - } else { - matches.free + + let files = match matches.values_of(options::FILE) { + Some(v) => v.map(|v| v.to_owned()).collect(), + None => vec!["-".to_owned()], }; + fold(files, bytes, spaces, width); 0 diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index cc92c8ff3..bdc5e2246 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -397,3 +397,13 @@ fn test_bytewise_fold_at_word_boundary_only_whitespace_preserve_final_newline() .succeeds() .stdout_is(" \n \n"); } + +#[test] +fn test_obsolete_syntax() { + new_ucmd!() + .arg("-5") + .arg("-s") + .arg("space_separated_words.txt") + .succeeds() + .stdout_is("test1\n \ntest2\n \ntest3\n \ntest4\n \ntest5\n \ntest6\n "); +} diff --git a/tests/fixtures/fold/space_separated_words.txt b/tests/fixtures/fold/space_separated_words.txt new file mode 100644 index 000000000..13b980632 --- /dev/null +++ b/tests/fixtures/fold/space_separated_words.txt @@ -0,0 +1 @@ +test1 test2 test3 test4 test5 test6 \ No newline at end of file From cccf89a48cbac9cda450caf1767881aaa8099f37 Mon Sep 17 00:00:00 2001 From: Ricardo Iglesias Date: Tue, 6 Apr 2021 21:52:56 -0700 Subject: [PATCH 117/132] timeout: Moved argument parsing to clap Changed from optparse to clap. None of the logic within timeout has been changed, which could use some refactoring, but that's beyond the scope of this commit. --- src/uu/timeout/Cargo.toml | 2 + src/uu/timeout/src/timeout.rs | 201 +++++++++++++++++++++------------- 2 files changed, 129 insertions(+), 74 deletions(-) diff --git a/src/uu/timeout/Cargo.toml b/src/uu/timeout/Cargo.toml index 51ac0bc0e..206a98c08 100644 --- a/src/uu/timeout/Cargo.toml +++ b/src/uu/timeout/Cargo.toml @@ -15,11 +15,13 @@ edition = "2018" path = "src/timeout.rs" [dependencies] +clap = "2.33" getopts = "0.2.18" libc = "0.2.42" uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["parse_time", "process", "signals"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } + [[bin]] name = "timeout" path = "src/main.rs" diff --git a/src/uu/timeout/src/timeout.rs b/src/uu/timeout/src/timeout.rs index 0dd7c2016..3efd04c86 100644 --- a/src/uu/timeout/src/timeout.rs +++ b/src/uu/timeout/src/timeout.rs @@ -10,99 +10,152 @@ #[macro_use] extern crate uucore; +extern crate clap; + +use clap::{App, Arg, ArgMatches, AppSettings}; use std::io::ErrorKind; use std::process::{Command, Stdio}; use std::time::Duration; use uucore::process::ChildExt; +use uucore::signals::{Signal, signal_by_name_or_value}; + static NAME: &str = "timeout"; static VERSION: &str = env!("CARGO_PKG_VERSION"); const ERR_EXIT_STATUS: i32 = 125; +pub mod options { + pub static FOREGROUND: &str = "foreground"; + pub static KILL_AFTER: &str = "kill-after"; + pub static SIGNAL: &str = "signal"; + pub static VERSION: &str = "version"; + pub static PRESERVE_STATUS: &str = "preserve-status"; + + // Positional args. + pub static DURATION: &str = "duration"; + pub static COMMAND: &str = "command"; + pub static ARGS: &str = "args"; +} + +struct Config { + foreground: bool, + kill_after: Option, + signal: Option, + version: bool, + duration: Duration, + preserve_status: bool + + command: String, + command_args: &[String] +} + +impl Config { + fn from(options: Clap::ArgMatches) -> Config { + let timeout_signal = match options.value_of(options::SIGNAL) { + Some(signal_) => + { + let signal_result = signal_by_name_or_value(&signal_); + match signal_result{ + None => { + show_error!("invalid signal '{}'", signal_); + return ERR_EXIT_STATUS; + }, + _ => Some(signal_result) + } + }, + _ => None + }; + + let kill_after: Option = + match options.value_of(options::KILL_AFTER) { + Some(time) => Some(uucore::parse_time::from_str(&time)), + None => None + }; + + let duration: Duration = uucore::parse_time::from_str( + options.value_of(options::DURATION) + ); + + let preserve_status: bool = options.is_present(options::PRESERVE_STATUS); + + let command: String = options.value_of(options::COMMAND).to_str(); + let command_args: &[String] = options.values_of(options::ARGS) + .map(|x| x.as_str()); + + Config { + foreground: options.is_present(options::FOREGROUND), + kill_after, + signal: timeout_signal, + duration, + preserve_status, + command, + command_args + } + } +} + pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); let program = args[0].clone(); let mut opts = getopts::Options::new(); - opts.optflag( - "", - "preserve-status", - "exit with the same status as COMMAND, even when the command times out", - ); - opts.optflag("", "foreground", "when not running timeout directly from a shell prompt, allow COMMAND to read from the TTY and get TTY signals; in this mode, children of COMMAND will not be timed out"); - opts.optopt("k", "kill-after", "also send a KILL signal if COMMAND is still running this long after the initial signal was sent", "DURATION"); - opts.optflag("s", "signal", "specify the signal to be sent on timeout; SIGNAL may be a name like 'HUP' or a number; see 'kill -l' for a list of signals"); - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("V", "version", "output version information and exit"); - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => crash!(ERR_EXIT_STATUS, "{}", f), - }; - if matches.opt_present("help") { - print!( - "{} {} -Usage: - {} [OPTION] DURATION COMMAND [ARG]... + let mut app = App::new("timeout") + .version(VERSION) + .arg( + Arg::with_name(options::FOREGROUND) + .long(options::FOREGROUND) + .help("when not running timeout directly from a shell prompt, allow COMMAND to read from the TTY and get TTY signals; in this mode, children of COMMAND will not be timed out") + ) + .arg( + Arg::with_name(options::KILL_AFTER) + .short("k") + .takes_value(true)) + .arg( + Arg::with_name(options::PRESERVE_STATUS) + .long(options::PRESERVE_STATUS) + .help("exit with the same status as COMMAND, even when the command times out") + ) + .arg( + Arg::with_name(options::SIGNAL) + .short("s") + .long(options::SIGNAL) + .help("specify the signal to be sent on timeout; SIGNAL may be a name like 'HUP' or a number; see 'kill -l' for a list of signals") + .takes_value(true) + ) + .arg( + Arg::with_name(options::DURATION) + .index(1) + .required(true) + ) + .arg( + Arg::with_name(options::COMMAND) + .index(2) + .required(true) + ) + .arg( + Arg::with_name(options::ARGS).required(true).multiple(true) + ) + .setting(AppSettings::TrailingVarArg); -{}", - NAME, - VERSION, - program, - &opts.usage("Start COMMAND, and kill it if still running after DURATION.") - ); - } else if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - } else if matches.free.len() < 2 { - show_error!("missing an argument"); - show_error!("for help, try '{0} --help'", program); - return ERR_EXIT_STATUS; - } else { - let status = matches.opt_present("preserve-status"); - let foreground = matches.opt_present("foreground"); - let kill_after = match matches.opt_str("kill-after") { - Some(tstr) => match uucore::parse_time::from_str(&tstr) { - Ok(time) => time, - Err(f) => { - show_error!("{}", f); - return ERR_EXIT_STATUS; - } - }, - None => Duration::new(0, 0), - }; - let signal = match matches.opt_str("signal") { - Some(sigstr) => match uucore::signals::signal_by_name_or_value(&sigstr) { - Some(sig) => sig, - None => { - show_error!("invalid signal '{}'", sigstr); - return ERR_EXIT_STATUS; - } - }, - None => uucore::signals::signal_by_name_or_value("TERM").unwrap(), - }; - let duration = match uucore::parse_time::from_str(&matches.free[0]) { - Ok(time) => time, - Err(f) => { - show_error!("{}", f); - return ERR_EXIT_STATUS; - } - }; - return timeout( - &matches.free[1], - &matches.free[2..], - duration, - signal, - kill_after, - foreground, - status, - ); - } + let matches = app.get_matches_from(args); - 0 + let config = Config::from(matches); + timeout(config.command, + config.command_args, + config.duration, + config.signal, + config.kill_after, + config.foreground, + config.preserve_status + ) } +/// TODO: Improve exit codes, and make them consistent with the GNU Coreutil +/// exit codes. + fn timeout( cmdname: &str, args: &[String], @@ -126,10 +179,10 @@ fn timeout( Err(err) => { show_error!("failed to execute process: {}", err); if err.kind() == ErrorKind::NotFound { - // XXX: not sure which to use + // FIXME: not sure which to use return 127; } else { - // XXX: this may not be 100% correct... + // FIXME: this may not be 100% correct... return 126; } } From ea0ead6a2e8da6f76cb509c844467c956ca8a092 Mon Sep 17 00:00:00 2001 From: Ricardo Iglesias Date: Tue, 6 Apr 2021 22:16:52 -0700 Subject: [PATCH 118/132] Ran cargo lock update command. --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index f65ba3dff..d8aea5e08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2416,6 +2416,7 @@ dependencies = [ name = "uu_timeout" version = "0.0.6" dependencies = [ + "clap", "getopts", "libc", "uucore", From 431a6ee1b5af6d901d41c29d10a56e0491ba91f7 Mon Sep 17 00:00:00 2001 From: Ricardo Iglesias Date: Tue, 6 Apr 2021 23:07:52 -0700 Subject: [PATCH 119/132] timeout: Fixed ownership issues Fixed some minor ownership issues in converting from the options to the arguments to the timeout COMMAND. Additionally, fixed a rustfmt issue in other files (fold/stdbuf.rs) --- src/uu/fold/src/fold.rs | 2 +- src/uu/stdbuf/src/stdbuf.rs | 3 +- src/uu/timeout/src/timeout.rs | 94 ++++++++++++++++++----------------- 3 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index cfd3b74cf..c35e996f2 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -45,7 +45,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .short("b") .help( "count using bytes rather than columns (meaning control characters \ - such as newline are not treated specially)", + such as newline are not treated specially)", ) .takes_value(false), ) diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index 67ed9a838..a61ba967b 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -80,7 +80,8 @@ fn print_version() { fn print_usage(opts: &Options) { let brief = "Run COMMAND, with modified buffering operations for its standard streams\n \ Mandatory arguments to long options are mandatory for short options too."; - let explanation = "If MODE is 'L' the corresponding stream will be line buffered.\n \ + let explanation = + "If MODE is 'L' the corresponding stream will be line buffered.\n \ This option is invalid with standard input.\n\n \ If MODE is '0' the corresponding stream will be unbuffered.\n\n \ Otherwise MODE is a number which may be followed by one of the following:\n\n \ diff --git a/src/uu/timeout/src/timeout.rs b/src/uu/timeout/src/timeout.rs index 3efd04c86..bd340a122 100644 --- a/src/uu/timeout/src/timeout.rs +++ b/src/uu/timeout/src/timeout.rs @@ -12,16 +12,19 @@ extern crate uucore; extern crate clap; -use clap::{App, Arg, ArgMatches, AppSettings}; +use clap::{App, AppSettings, Arg}; use std::io::ErrorKind; use std::process::{Command, Stdio}; use std::time::Duration; use uucore::process::ChildExt; -use uucore::signals::{Signal, signal_by_name_or_value}; +use uucore::signals::signal_by_name_or_value; - -static NAME: &str = "timeout"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static ABOUT: &str = "Start COMMAND, and kill it if still running after DURATION."; + +fn get_usage() -> String { + format!("{0} [OPTION]... [FILE]...", executable!()) +} const ERR_EXIT_STATUS: i32 = 125; @@ -40,70 +43,68 @@ pub mod options { struct Config { foreground: bool, - kill_after: Option, - signal: Option, - version: bool, + kill_after: Duration, + signal: usize, duration: Duration, - preserve_status: bool + preserve_status: bool, command: String, - command_args: &[String] + command_args: Vec, } impl Config { - fn from(options: Clap::ArgMatches) -> Config { - let timeout_signal = match options.value_of(options::SIGNAL) { - Some(signal_) => - { + fn from(options: clap::ArgMatches) -> Config { + let signal = match options.value_of(options::SIGNAL) { + Some(signal_) => { let signal_result = signal_by_name_or_value(&signal_); - match signal_result{ + match signal_result { None => { - show_error!("invalid signal '{}'", signal_); - return ERR_EXIT_STATUS; - }, - _ => Some(signal_result) + unreachable!("invalid signal '{}'", signal_); + } + Some(signal_value) => signal_value, } - }, - _ => None + } + _ => uucore::signals::signal_by_name_or_value("TERM").unwrap(), }; - let kill_after: Option = - match options.value_of(options::KILL_AFTER) { - Some(time) => Some(uucore::parse_time::from_str(&time)), - None => None - }; + let kill_after: Duration = match options.value_of(options::KILL_AFTER) { + Some(time) => uucore::parse_time::from_str(&time).unwrap(), + None => Duration::new(0, 0), + }; - let duration: Duration = uucore::parse_time::from_str( - options.value_of(options::DURATION) - ); + let duration: Duration = + uucore::parse_time::from_str(options.value_of(options::DURATION).unwrap()).unwrap(); let preserve_status: bool = options.is_present(options::PRESERVE_STATUS); + let foreground = options.is_present(options::FOREGROUND); - let command: String = options.value_of(options::COMMAND).to_str(); - let command_args: &[String] = options.values_of(options::ARGS) - .map(|x| x.as_str()); + let command: String = options.value_of(options::COMMAND).unwrap().to_string(); + let command_args: Vec = options + .values_of(options::ARGS) + .unwrap() + .map(|x| x.to_owned()) + .collect(); Config { - foreground: options.is_present(options::FOREGROUND), + foreground, kill_after, - signal: timeout_signal, + signal, duration, preserve_status, command, - command_args + command_args, } } } pub fn uumain(args: impl uucore::Args) -> i32 { let args = args.collect_str(); + let usage = get_usage(); - let program = args[0].clone(); - - let mut opts = getopts::Options::new(); - - let mut app = App::new("timeout") + let app = App::new("timeout") .version(VERSION) + .usage(&usage[..]) + .about(ABOUT) .arg( Arg::with_name(options::FOREGROUND) .long(options::FOREGROUND) @@ -143,13 +144,14 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = app.get_matches_from(args); let config = Config::from(matches); - timeout(config.command, - config.command_args, - config.duration, - config.signal, - config.kill_after, - config.foreground, - config.preserve_status + timeout( + &config.command, + &config.command_args, + config.duration, + config.signal, + config.kill_after, + config.foreground, + config.preserve_status, ) } From 8232c527a365050d91a6ee9d8931c0455d417474 Mon Sep 17 00:00:00 2001 From: Ricardo Iglesias Date: Tue, 6 Apr 2021 23:30:15 -0700 Subject: [PATCH 120/132] timeout: tests passing. Forgot to handle the case where no arguments were passed to the COMMAND. Because ARGS can be empty, we need two separate cases for handling options.values_of(options::ARGS) --- src/uu/timeout/src/timeout.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/uu/timeout/src/timeout.rs b/src/uu/timeout/src/timeout.rs index bd340a122..23e2ec842 100644 --- a/src/uu/timeout/src/timeout.rs +++ b/src/uu/timeout/src/timeout.rs @@ -79,11 +79,11 @@ impl Config { let foreground = options.is_present(options::FOREGROUND); let command: String = options.value_of(options::COMMAND).unwrap().to_string(); - let command_args: Vec = options - .values_of(options::ARGS) - .unwrap() - .map(|x| x.to_owned()) - .collect(); + + let command_args: Vec = match options.values_of(options::ARGS) { + Some(values) => values.map(|x| x.to_owned()).collect(), + None => vec![], + }; Config { foreground, @@ -137,7 +137,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .required(true) ) .arg( - Arg::with_name(options::ARGS).required(true).multiple(true) + Arg::with_name(options::ARGS).multiple(true) ) .setting(AppSettings::TrailingVarArg); From 52706372aa23f3433a5fe05e226a2fb6d9f57c01 Mon Sep 17 00:00:00 2001 From: paulotten Date: Wed, 7 Apr 2021 02:41:04 -0400 Subject: [PATCH 121/132] Replace outdated time 0.1 dependancy with latest version of chrono (#2044) * Replace outdated time 0.1 dependancy with latest version of chrono I also noticed that times are being miscalculated on linux, so I fixed that. * Add time test for issue #2042 * Cleanup use declarations * Tie time test to `touch` feature - if we compile with the right OS feature flag then we should have it, even on Windows --- Cargo.lock | 2 +- src/uu/du/Cargo.toml | 2 +- src/uu/du/src/du.rs | 17 +++++++++-------- tests/by-util/test_du.rs | 18 ++++++++++++++++++ 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f65ba3dff..41a384ea4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1777,7 +1777,7 @@ dependencies = [ name = "uu_du" version = "0.0.6" dependencies = [ - "time", + "chrono", "uucore", "uucore_procs", "winapi 0.3.9", diff --git a/src/uu/du/Cargo.toml b/src/uu/du/Cargo.toml index eb7b23f8b..3ce9d8361 100644 --- a/src/uu/du/Cargo.toml +++ b/src/uu/du/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/du.rs" [dependencies] -time = "0.1.40" +chrono = "0.4" uucore = { version=">=0.0.8", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } winapi = { version="0.3", features=[] } diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 9c8bb9794..615b66a4e 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -10,6 +10,8 @@ #[macro_use] extern crate uucore; +use chrono::prelude::DateTime; +use chrono::Local; use std::collections::HashSet; use std::env; use std::fs; @@ -22,7 +24,7 @@ use std::os::windows::fs::MetadataExt; #[cfg(windows)] use std::os::windows::io::AsRawHandle; use std::path::PathBuf; -use time::Timespec; +use std::time::{Duration, UNIX_EPOCH}; #[cfg(windows)] use winapi::shared::minwindef::{DWORD, LPVOID}; #[cfg(windows)] @@ -118,7 +120,7 @@ impl Stat { // https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html#tymethod.creation_time // "The returned 64-bit value [...] which represents the number of 100-nanosecond intervals since January 1, 1601 (UTC)." fn windows_time_to_unix_time(win_time: u64) -> u64 { - win_time / 10_000 - 11_644_473_600_000 + win_time / 10_000_000 - 11_644_473_600 } #[cfg(windows)] @@ -555,8 +557,8 @@ Try '{} --help' for more information.", }; if matches.opt_present("time") { let tm = { - let (secs, nsecs) = { - let time = match matches.opt_str("time") { + let secs = { + match matches.opt_str("time") { Some(s) => match &s[..] { "accessed" => stat.accessed, "created" => stat.created, @@ -573,13 +575,12 @@ Try '{} --help' for more information.", } }, None => stat.modified, - }; - ((time / 1000) as i64, (time % 1000 * 1_000_000) as i32) + } }; - time::at(Timespec::new(secs, nsecs)) + DateTime::::from(UNIX_EPOCH + Duration::from_secs(secs)) }; if !summarize || index == len - 1 { - let time_str = tm.strftime(time_format_str).unwrap(); + let time_str = tm.format(time_format_str).to_string(); print!( "{}\t{}\t{}{}", convert_size(size), diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index b3b1b3465..30dcd9bb3 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -172,3 +172,21 @@ fn test_du_h_flag_empty_file() { assert_eq!(result.stderr, ""); assert_eq!(result.stdout, "0\tempty.txt\n"); } + +#[cfg(feature = "touch")] +#[test] +fn test_du_time() { + let ts = TestScenario::new("du"); + + let touch = ts.ccmd("touch").arg("-a").arg("-m").arg("-t").arg("201505150000").arg("date_test").run(); + assert!(touch.success); + + let result = ts.ucmd().arg("--time").arg("date_test").run(); + + // cleanup by removing test file + ts.cmd("rm").arg("date_test").run(); + + assert!(result.success); + assert_eq!(result.stderr, ""); + assert_eq!(result.stdout, "0\t2015-05-15 00:00\tdate_test\n"); +} From 2997413d6446ab2c414496ad39bc6e9a8d757be1 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Wed, 7 Apr 2021 11:48:01 +0200 Subject: [PATCH 122/132] ls: refactor tests --- tests/by-util/test_ls.rs | 722 ++++++++++++++++++--------------------- 1 file changed, 324 insertions(+), 398 deletions(-) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 64f8f57bf..f0db7ca9c 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -43,26 +43,22 @@ fn test_ls_a() { let at = &scene.fixtures; at.touch(".test-1"); - let result = scene.ucmd().run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(!result.stdout.contains(".test-1")); - assert!(!result.stdout.contains("..")); + let result = scene.ucmd().succeeds(); + let stdout = result.stdout_str(); + assert!(!stdout.contains(".test-1")); + assert!(!stdout.contains("..")); - let result = scene.ucmd().arg("-a").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(result.stdout.contains(".test-1")); - assert!(result.stdout.contains("..")); + scene + .ucmd() + .arg("-a") + .succeeds() + .stdout_contains(&".test-1") + .stdout_contains(&".."); - let result = scene.ucmd().arg("-A").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(result.stdout.contains(".test-1")); - assert!(!result.stdout.contains("..")); + let result = scene.ucmd().arg("-A").succeeds(); + result.stdout_contains(".test-1"); + let stdout = result.stdout_str(); + assert!(!stdout.contains("..")); } #[test] @@ -75,29 +71,19 @@ fn test_ls_width() { at.touch(&at.plus_as_string("test-width-4")); for option in &["-w 100", "-w=100", "--width=100", "--width 100"] { - let result = scene + scene .ucmd() .args(&option.split(" ").collect::>()) - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert_eq!( - result.stdout, - "test-width-1 test-width-2 test-width-3 test-width-4\n", - ) + .succeeds() + .stdout_only("test-width-1 test-width-2 test-width-3 test-width-4\n"); } for option in &["-w 50", "-w=50", "--width=50", "--width 50"] { - let result = scene + scene .ucmd() .args(&option.split(" ").collect::>()) - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert_eq!( - result.stdout, - "test-width-1 test-width-3\ntest-width-2 test-width-4\n", - ) + .succeeds() + .stdout_only("test-width-1 test-width-3\ntest-width-2 test-width-4\n"); } for option in &[ @@ -110,16 +96,11 @@ fn test_ls_width() { "--width=0", "--width 0", ] { - let result = scene + scene .ucmd() .args(&option.split(" ").collect::>()) - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert_eq!( - result.stdout, - "test-width-1\ntest-width-2\ntest-width-3\ntest-width-4\n", - ) + .succeeds() + .stdout_only("test-width-1\ntest-width-2\ntest-width-3\ntest-width-4\n"); } } @@ -133,48 +114,28 @@ fn test_ls_columns() { at.touch(&at.plus_as_string("test-columns-4")); // Columns is the default - let result = scene.ucmd().run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + let result = scene.ucmd().succeeds(); #[cfg(not(windows))] - assert_eq!( - result.stdout, - "test-columns-1\ntest-columns-2\ntest-columns-3\ntest-columns-4\n" - ); + result.stdout_only("test-columns-1\ntest-columns-2\ntest-columns-3\ntest-columns-4\n"); #[cfg(windows)] - assert_eq!( - result.stdout, - "test-columns-1 test-columns-2 test-columns-3 test-columns-4\n" - ); + result.stdout_only("test-columns-1 test-columns-2 test-columns-3 test-columns-4\n"); for option in &["-C", "--format=columns"] { - let result = scene.ucmd().arg(option).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + let result = scene.ucmd().arg(option).succeeds(); #[cfg(not(windows))] - assert_eq!( - result.stdout, - "test-columns-1\ntest-columns-2\ntest-columns-3\ntest-columns-4\n" - ); + result.stdout_only("test-columns-1\ntest-columns-2\ntest-columns-3\ntest-columns-4\n"); #[cfg(windows)] - assert_eq!( - result.stdout, - "test-columns-1 test-columns-2 test-columns-3 test-columns-4\n" - ); + result.stdout_only("test-columns-1 test-columns-2 test-columns-3 test-columns-4\n"); } for option in &["-C", "--format=columns"] { - let result = scene.ucmd().arg("-w=40").arg(option).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert_eq!( - result.stdout, - "test-columns-1 test-columns-3\ntest-columns-2 test-columns-4\n" - ); + scene + .ucmd() + .arg("-w=40") + .arg(option) + .succeeds() + .stdout_only("test-columns-1 test-columns-3\ntest-columns-2 test-columns-4\n"); } } @@ -191,31 +152,22 @@ fn test_ls_across() { let result = scene.ucmd().arg(option).succeeds(); // Because the test terminal has width 0, this is the same output as // the columns option. - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); if cfg!(unix) { - assert_eq!( - result.stdout, - "test-across-1\ntest-across-2\ntest-across-3\ntest-across-4\n" - ); + result.stdout_only("test-across-1\ntest-across-2\ntest-across-3\ntest-across-4\n"); } else { - assert_eq!( - result.stdout, - "test-across-1 test-across-2 test-across-3 test-across-4\n" - ); + result.stdout_only("test-across-1 test-across-2 test-across-3 test-across-4\n"); } } for option in &["-x", "--format=across"] { - let result = scene.ucmd().arg("-w=30").arg(option).run(); // Because the test terminal has width 0, this is the same output as // the columns option. - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert_eq!( - result.stdout, - "test-across-1 test-across-2\ntest-across-3 test-across-4\n" - ); + scene + .ucmd() + .arg("-w=30") + .arg(option) + .succeeds() + .stdout_only("test-across-1 test-across-2\ntest-across-3 test-across-4\n"); } } @@ -231,31 +183,27 @@ fn test_ls_commas() { for option in &["-m", "--format=commas"] { let result = scene.ucmd().arg(option).succeeds(); if cfg!(unix) { - assert_eq!( - result.stdout, - "test-commas-1,\ntest-commas-2,\ntest-commas-3,\ntest-commas-4\n" - ); + result.stdout_only("test-commas-1,\ntest-commas-2,\ntest-commas-3,\ntest-commas-4\n"); } else { - assert_eq!( - result.stdout, - "test-commas-1, test-commas-2, test-commas-3, test-commas-4\n" - ); + result.stdout_only("test-commas-1, test-commas-2, test-commas-3, test-commas-4\n"); } } for option in &["-m", "--format=commas"] { - let result = scene.ucmd().arg("-w=30").arg(option).succeeds(); - assert_eq!( - result.stdout, - "test-commas-1, test-commas-2,\ntest-commas-3, test-commas-4\n" - ); + scene + .ucmd() + .arg("-w=30") + .arg(option) + .succeeds() + .stdout_only("test-commas-1, test-commas-2,\ntest-commas-3, test-commas-4\n"); } for option in &["-m", "--format=commas"] { - let result = scene.ucmd().arg("-w=45").arg(option).succeeds(); - assert_eq!( - result.stdout, - "test-commas-1, test-commas-2, test-commas-3,\ntest-commas-4\n" - ); + scene + .ucmd() + .arg("-w=45") + .arg(option) + .succeeds() + .stdout_only("test-commas-1, test-commas-2, test-commas-3,\ntest-commas-4\n"); } } @@ -279,13 +227,11 @@ fn test_ls_long() { for arg in &["-l", "--long", "--format=long", "--format=verbose"] { let result = scene.ucmd().arg(arg).arg("test-long").succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); #[cfg(not(windows))] - assert!(result.stdout.contains("-rw-rw-r--")); + result.stdout_contains("-rw-rw-r--"); #[cfg(windows)] - assert!(result.stdout.contains("---------- 1 somebody somegroup")); + result.stdout_contains("---------- 1 somebody somegroup"); } #[cfg(not(windows))] @@ -331,20 +277,16 @@ fn test_ls_long_formats() { .arg("-l") .arg("--author") .arg("test-long-formats") - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_three.is_match(&result.stdout)); + .succeeds(); + assert!(re_three.is_match(result.stdout_str())); let result = scene .ucmd() .arg("-l1") .arg("--author") .arg("test-long-formats") - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_three.is_match(&result.stdout)); + .succeeds(); + assert!(re_three.is_match(&result.stdout_str())); #[cfg(unix)] { @@ -354,9 +296,7 @@ fn test_ls_long_formats() { .arg("--author") .arg("test-long-formats") .succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_three_num.is_match(&result.stdout)); + assert!(re_three_num.is_match(result.stdout_str())); } for arg in &[ @@ -371,9 +311,7 @@ fn test_ls_long_formats() { .args(&arg.split(" ").collect::>()) .arg("test-long-formats") .succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_two.is_match(&result.stdout)); + assert!(re_two.is_match(result.stdout_str())); #[cfg(unix)] { @@ -383,9 +321,7 @@ fn test_ls_long_formats() { .args(&arg.split(" ").collect::>()) .arg("test-long-formats") .succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_two_num.is_match(&result.stdout)); + assert!(re_two_num.is_match(result.stdout_str())); } } @@ -404,9 +340,7 @@ fn test_ls_long_formats() { .args(&arg.split(" ").collect::>()) .arg("test-long-formats") .succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_one.is_match(&result.stdout)); + assert!(re_one.is_match(result.stdout_str())); #[cfg(unix)] { @@ -416,9 +350,7 @@ fn test_ls_long_formats() { .args(&arg.split(" ").collect::>()) .arg("test-long-formats") .succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_one_num.is_match(&result.stdout)); + assert!(re_one_num.is_match(result.stdout_str())); } } @@ -440,9 +372,7 @@ fn test_ls_long_formats() { .args(&arg.split(" ").collect::>()) .arg("test-long-formats") .succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_zero.is_match(&result.stdout)); + assert!(re_zero.is_match(result.stdout_str())); #[cfg(unix)] { @@ -452,9 +382,7 @@ fn test_ls_long_formats() { .args(&arg.split(" ").collect::>()) .arg("test-long-formats") .succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_zero.is_match(&result.stdout)); + assert!(re_zero.is_match(result.stdout_str())); } } } @@ -469,11 +397,11 @@ fn test_ls_oneline() { // Bit of a weird situation: in the tests oneline and columns have the same output, // except on Windows. for option in &["-1", "--format=single-column"] { - let result = scene.ucmd().arg(option).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert_eq!(result.stdout, "test-oneline-1\ntest-oneline-2\n"); + scene + .ucmd() + .arg(option) + .succeeds() + .stdout_only("test-oneline-1\ntest-oneline-2\n"); } } @@ -494,11 +422,8 @@ fn test_ls_deref() { .arg("--color=never") .arg("test-long") .arg("test-long.link") - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(re.is_match(&result.stdout.trim())); + .succeeds(); + assert!(re.is_match(result.stdout_str().trim())); let result = scene .ucmd() @@ -506,11 +431,8 @@ fn test_ls_deref() { .arg("--color=never") .arg("test-long") .arg("test-long.link") - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(!re.is_match(&result.stdout.trim())); + .succeeds(); + assert!(!re.is_match(result.stdout_str().trim())); } #[test] @@ -528,28 +450,19 @@ fn test_ls_order_size() { at.touch("test-4"); at.append("test-4", "4444"); - let result = scene.ucmd().arg("-al").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + scene.ucmd().arg("-al").succeeds(); - let result = scene.ucmd().arg("-S").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + let result = scene.ucmd().arg("-S").succeeds(); #[cfg(not(windows))] - assert_eq!(result.stdout, "test-4\ntest-3\ntest-2\ntest-1\n"); + result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n"); #[cfg(windows)] - assert_eq!(result.stdout, "test-4 test-3 test-2 test-1\n"); + result.stdout_only("test-4 test-3 test-2 test-1\n"); - let result = scene.ucmd().arg("-S").arg("-r").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + let result = scene.ucmd().arg("-S").arg("-r").succeeds(); #[cfg(not(windows))] - assert_eq!(result.stdout, "test-1\ntest-2\ntest-3\ntest-4\n"); + result.stdout_only("test-1\ntest-2\ntest-3\ntest-4\n"); #[cfg(windows)] - assert_eq!(result.stdout, "test-1 test-2 test-3 test-4\n"); + result.stdout_only("test-1 test-2 test-3 test-4\n"); } #[test] @@ -562,9 +475,9 @@ fn test_ls_long_ctime() { // Should show the time on Unix, but question marks on windows. #[cfg(unix)] - assert!(result.stdout.contains(":")); + result.stdout_contains(":"); #[cfg(not(unix))] - assert!(result.stdout.contains("???")); + result.stdout_contains("???"); } #[test] @@ -596,51 +509,41 @@ fn test_ls_order_time() { ) .unwrap(); - let result = scene.ucmd().arg("-al").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + scene.ucmd().arg("-al").succeeds(); // ctime was changed at write, so the order is 4 3 2 1 - let result = scene.ucmd().arg("-t").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + let result = scene.ucmd().arg("-t").succeeds(); #[cfg(not(windows))] - assert_eq!(result.stdout, "test-4\ntest-3\ntest-2\ntest-1\n"); + result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n"); #[cfg(windows)] - assert_eq!(result.stdout, "test-4 test-3 test-2 test-1\n"); + result.stdout_only("test-4 test-3 test-2 test-1\n"); - let result = scene.ucmd().arg("-tr").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + let result = scene.ucmd().arg("-tr").succeeds(); #[cfg(not(windows))] - assert_eq!(result.stdout, "test-1\ntest-2\ntest-3\ntest-4\n"); + result.stdout_only("test-1\ntest-2\ntest-3\ntest-4\n"); #[cfg(windows)] - assert_eq!(result.stdout, "test-1 test-2 test-3 test-4\n"); + result.stdout_only("test-1 test-2 test-3 test-4\n"); // 3 was accessed last in the read // So the order should be 2 3 4 1 - let result = scene.ucmd().arg("-tu").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + let result = scene.ucmd().arg("-tu").succeeds(); let file3_access = at.open("test-3").metadata().unwrap().accessed().unwrap(); let file4_access = at.open("test-4").metadata().unwrap().accessed().unwrap(); + + // It seems to be dependent on the platform whether the access time is actually set if file3_access > file4_access { if cfg!(not(windows)) { - assert_eq!(result.stdout, "test-3\ntest-4\ntest-2\ntest-1\n"); + result.stdout_only("test-3\ntest-4\ntest-2\ntest-1\n"); } else { - assert_eq!(result.stdout, "test-3 test-4 test-2 test-1\n"); + result.stdout_only("test-3 test-4 test-2 test-1\n"); } } else { // Access time does not seem to be set on Windows and some other // systems so the order is 4 3 2 1 if cfg!(not(windows)) { - assert_eq!(result.stdout, "test-4\ntest-3\ntest-2\ntest-1\n"); + result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n"); } else { - assert_eq!(result.stdout, "test-4 test-3 test-2 test-1\n"); + result.stdout_only("test-4 test-3 test-2 test-1\n"); } } @@ -648,11 +551,8 @@ fn test_ls_order_time() { // So the order should be 2 4 3 1 #[cfg(unix)] { - let result = scene.ucmd().arg("-tc").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert_eq!(result.stdout, "test-2\ntest-4\ntest-3\ntest-1\n"); + let result = scene.ucmd().arg("-tc").succeeds(); + result.stdout_only("test-2\ntest-4\ntest-3\ntest-1\n"); } } @@ -676,18 +576,21 @@ fn test_ls_files_dirs() { scene.ucmd().arg("a/a").succeeds(); scene.ucmd().arg("a").arg("z").succeeds(); - let result = scene.ucmd().arg("doesntexist").fails(); // Doesn't exist - assert!(result - .stderr - .contains("error: 'doesntexist': No such file or directory")); + scene + .ucmd() + .arg("doesntexist") + .fails() + .stderr_contains(&"error: 'doesntexist': No such file or directory"); - let result = scene.ucmd().arg("a").arg("doesntexist").fails(); // One exists, the other doesn't - assert!(result - .stderr - .contains("error: 'doesntexist': No such file or directory")); - assert!(result.stdout.contains("a:")); + scene + .ucmd() + .arg("a") + .arg("doesntexist") + .fails() + .stderr_contains(&"error: 'doesntexist': No such file or directory") + .stdout_contains(&"a:"); } #[test] @@ -711,13 +614,10 @@ fn test_ls_recursive() { .arg("z") .succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); #[cfg(not(windows))] - assert!(result.stdout.contains("a/b:\nb")); + result.stdout_contains(&"a/b:\nb"); #[cfg(windows)] - assert!(result.stdout.contains("a\\b:\nb")); + result.stdout_contains(&"a\\b:\nb"); } #[cfg(unix)] @@ -737,41 +637,53 @@ fn test_ls_ls_color() { // Color is disabled by default let result = scene.ucmd().succeeds(); - assert!(!result.stdout.contains(a_with_colors)); - assert!(!result.stdout.contains(z_with_colors)); + assert!(!result.stdout_str().contains(a_with_colors)); + assert!(!result.stdout_str().contains(z_with_colors)); // Color should be enabled - let result = scene.ucmd().arg("--color").succeeds(); - assert!(result.stdout.contains(a_with_colors)); - assert!(result.stdout.contains(z_with_colors)); + scene + .ucmd() + .arg("--color") + .succeeds() + .stdout_contains(a_with_colors) + .stdout_contains(z_with_colors); // Color should be enabled - let result = scene.ucmd().arg("--color=always").succeeds(); - assert!(result.stdout.contains(a_with_colors)); - assert!(result.stdout.contains(z_with_colors)); + scene + .ucmd() + .arg("--color=always") + .succeeds() + .stdout_contains(a_with_colors) + .stdout_contains(z_with_colors); // Color should be disabled let result = scene.ucmd().arg("--color=never").succeeds(); - assert!(!result.stdout.contains(a_with_colors)); - assert!(!result.stdout.contains(z_with_colors)); + assert!(!result.stdout_str().contains(a_with_colors)); + assert!(!result.stdout_str().contains(z_with_colors)); // Nested dir should be shown and colored - let result = scene.ucmd().arg("--color").arg("a").succeeds(); - assert!(result.stdout.contains(nested_dir_with_colors)); + scene + .ucmd() + .arg("--color") + .arg("a") + .succeeds() + .stdout_contains(nested_dir_with_colors); // Color has no effect - let result = scene + scene .ucmd() .arg("--color=always") .arg("a/nested_file") - .succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.stdout.contains("a/nested_file\n")); + .succeeds() + .stdout_contains("a/nested_file\n"); // No output - let result = scene.ucmd().arg("--color=never").arg("z").succeeds(); - assert_eq!(result.stdout, ""); + scene + .ucmd() + .arg("--color=never") + .arg("z") + .succeeds() + .stdout_only(""); } #[cfg(unix)] @@ -786,39 +698,31 @@ fn test_ls_inode() { let re_short = Regex::new(r" *(\d+) test_inode").unwrap(); let re_long = Regex::new(r" *(\d+) [xrw-]{10} \d .+ test_inode").unwrap(); - let result = scene.ucmd().arg("test_inode").arg("-i").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_short.is_match(&result.stdout)); + let result = scene.ucmd().arg("test_inode").arg("-i").succeeds(); + assert!(re_short.is_match(result.stdout_str())); let inode_short = re_short - .captures(&result.stdout) + .captures(result.stdout_str()) .unwrap() .get(1) .unwrap() .as_str(); - let result = scene.ucmd().arg("test_inode").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(!re_short.is_match(&result.stdout)); - assert!(!result.stdout.contains(inode_short)); + let result = scene.ucmd().arg("test_inode").succeeds(); + assert!(!re_short.is_match(result.stdout_str())); + assert!(!result.stdout_str().contains(inode_short)); - let result = scene.ucmd().arg("-li").arg("test_inode").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(re_long.is_match(&result.stdout)); + let result = scene.ucmd().arg("-li").arg("test_inode").succeeds(); + assert!(re_long.is_match(result.stdout_str())); let inode_long = re_long - .captures(&result.stdout) + .captures(result.stdout_str()) .unwrap() .get(1) .unwrap() .as_str(); - let result = scene.ucmd().arg("-l").arg("test_inode").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(!re_long.is_match(&result.stdout)); - assert!(!result.stdout.contains(inode_long)); + let result = scene.ucmd().arg("-l").arg("test_inode").succeeds(); + assert!(!re_long.is_match(result.stdout_str())); + assert!(!result.stdout_str().contains(inode_long)); assert_eq!(inode_short, inode_long) } @@ -844,27 +748,33 @@ fn test_ls_indicator_style() { let options = vec!["classify", "file-type", "slash"]; for opt in options { // Verify that classify and file-type both contain indicators for symlinks. - let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run(); - println!("stdout = {:?}", result.stdout); - assert!(result.stdout.contains("/")); + scene + .ucmd() + .arg(format!("--indicator-style={}", opt)) + .succeeds() + .stdout_contains(&"/"); } // Same test as above, but with the alternate flags. let options = vec!["--classify", "--file-type", "-p"]; for opt in options { - let result = scene.ucmd().arg(format!("{}", opt)).run(); - println!("stdout = {:?}", result.stdout); - assert!(result.stdout.contains("/")); + scene + .ucmd() + .arg(format!("{}", opt)) + .succeeds() + .stdout_contains(&"/"); } // Classify and File-Type all contain indicators for pipes and links. let options = vec!["classify", "file-type"]; for opt in options { // Verify that classify and file-type both contain indicators for symlinks. - let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run(); - println!("stdout = {}", result.stdout); - assert!(result.stdout.contains("@")); - assert!(result.stdout.contains("|")); + scene + .ucmd() + .arg(format!("--indicator-style={}", opt)) + .succeeds() + .stdout_contains(&"@") + .stdout_contains(&"|"); } // Test sockets. Because the canonical way of making sockets to test is with @@ -906,26 +816,32 @@ fn test_ls_indicator_style() { let options = vec!["classify", "file-type", "slash"]; for opt in options { // Verify that classify and file-type both contain indicators for symlinks. - let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run(); - println!("stdout = {:?}", result.stdout); - assert!(result.stdout.contains("/")); + let result = scene + .ucmd() + .arg(format!("--indicator-style={}", opt)) + .succeeds() + .stdout_contains(&"/"); } // Same test as above, but with the alternate flags. let options = vec!["--classify", "--file-type", "-p"]; for opt in options { - let result = scene.ucmd().arg(format!("{}", opt)).run(); - println!("stdout = {:?}", result.stdout); - assert!(result.stdout.contains("/")); + let result = scene + .ucmd() + .arg(format!("{}", opt)) + .succeeds() + .stdout_contains(&"/"); } // Classify and File-Type all contain indicators for pipes and links. let options = vec!["classify", "file-type"]; for opt in options { // Verify that classify and file-type both contain indicators for symlinks. - let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run(); - println!("stdout = {}", result.stdout); - assert!(result.stdout.contains("@")); + let result = scene + .ucmd() + .arg(format!("--indicator-style={}", opt)) + .succeeds() + .stdout_contains(&"@"); } } @@ -934,26 +850,27 @@ fn test_ls_indicator_style() { fn test_ls_human_si() { let scene = TestScenario::new(util_name!()); let file1 = "test_human-1"; - let result = scene + scene .cmd("truncate") .arg("-s") .arg("+1000") .arg(file1) - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); + .succeeds(); - let result = scene.ucmd().arg("-hl").arg(file1).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(result.stdout.contains(" 1000 ")); + scene + .ucmd() + .arg("-hl") + .arg(file1) + .succeeds() + .stdout_contains(" 1000 "); - let result = scene.ucmd().arg("-l").arg("--si").arg(file1).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(result.stdout.contains(" 1.0k ")); + scene + .ucmd() + .arg("-l") + .arg("--si") + .arg(file1) + .succeeds() + .stdout_contains(" 1.0k "); scene .cmd("truncate") @@ -962,63 +879,68 @@ fn test_ls_human_si() { .arg(file1) .run(); - let result = scene.ucmd().arg("-hl").arg(file1).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(result.stdout.contains(" 1001K ")); + scene + .ucmd() + .arg("-hl") + .arg(file1) + .succeeds() + .stdout_contains(" 1001K "); - let result = scene.ucmd().arg("-l").arg("--si").arg(file1).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(result.stdout.contains(" 1.1M ")); + scene + .ucmd() + .arg("-l") + .arg("--si") + .arg(file1) + .succeeds() + .stdout_contains(" 1.1M "); let file2 = "test-human-2"; - let result = scene + scene .cmd("truncate") .arg("-s") .arg("+12300k") .arg(file2) - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - let result = scene.ucmd().arg("-hl").arg(file2).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - // GNU rounds up, so we must too. - assert!(result.stdout.contains(" 13M ")); + .succeeds(); - let result = scene.ucmd().arg("-l").arg("--si").arg(file2).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); // GNU rounds up, so we must too. - assert!(result.stdout.contains(" 13M ")); + scene + .ucmd() + .arg("-hl") + .arg(file2) + .succeeds() + .stdout_contains(" 13M "); + + // GNU rounds up, so we must too. + scene + .ucmd() + .arg("-l") + .arg("--si") + .arg(file2) + .succeeds() + .stdout_contains(" 13M "); let file3 = "test-human-3"; - let result = scene + scene .cmd("truncate") .arg("-s") .arg("+9999") .arg(file3) - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); + .succeeds(); - let result = scene.ucmd().arg("-hl").arg(file3).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(result.stdout.contains(" 9.8K ")); + scene + .ucmd() + .arg("-hl") + .arg(file3) + .succeeds() + .stdout_contains(" 9.8K "); - let result = scene.ucmd().arg("-l").arg("--si").arg(file3).run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(result.stdout.contains(" 10k ")); + scene + .ucmd() + .arg("-l") + .arg("--si") + .arg(file3) + .succeeds() + .stdout_contains(" 10k "); } #[cfg(windows)] @@ -1035,16 +957,11 @@ fn test_ls_hidden_windows() { .arg("+S") .arg("+r") .arg(file) - .run(); - let result = scene.ucmd().run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - let result = scene.ucmd().arg("-a").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert!(result.success); - assert!(result.stdout.contains(file)); + .succeeds(); + + let result = scene.ucmd().succeeds(); + assert!(!result.stdout_str().contains(file)); + let result = scene.ucmd().arg("-a").succeeds().stdout_contains(file); } #[test] @@ -1104,25 +1021,25 @@ fn test_ls_version_sort() { "", // because of '\n' at the end of the output ]; - let result = scene.ucmd().arg("-1v").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); + let result = scene.ucmd().arg("-1v").succeeds(); + assert_eq!( + result.stdout_str().split('\n').collect::>(), + expected + ); - assert_eq!(result.stdout.split('\n').collect::>(), expected); - - let result = scene.ucmd().arg("-1").arg("--sort=version").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - - assert_eq!(result.stdout.split('\n').collect::>(), expected); - - let result = scene.ucmd().arg("-a1v").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); + let result = scene.ucmd().arg("-1").arg("--sort=version").succeeds(); + assert_eq!( + result.stdout_str().split('\n').collect::>(), + expected + ); + let result = scene.ucmd().arg("-a1v").succeeds(); expected.insert(0, ".."); expected.insert(0, "."); - assert_eq!(result.stdout.split('\n').collect::>(), expected,) + assert_eq!( + result.stdout_str().split('\n').collect::>(), + expected, + ) } #[test] @@ -1138,8 +1055,11 @@ fn test_ls_quoting_style() { { at.touch("one\ntwo"); // Default is shell-escape - let result = scene.ucmd().arg("one\ntwo").succeeds(); - assert_eq!(result.stdout, "'one'$'\\n''two'\n"); + scene + .ucmd() + .arg("one\ntwo") + .succeeds() + .stdout_only("'one'$'\\n''two'\n"); for (arg, correct) in &[ ("--quoting-style=literal", "one?two"), @@ -1156,10 +1076,12 @@ fn test_ls_quoting_style() { ("--quoting-style=shell", "one?two"), ("--quoting-style=shell-always", "'one?two'"), ] { - let result = scene.ucmd().arg(arg).arg("one\ntwo").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert_eq!(result.stdout, format!("{}\n", correct)); + scene + .ucmd() + .arg(arg) + .arg("one\ntwo") + .succeeds() + .stdout_only(format!("{}\n", correct)); } for (arg, correct) in &[ @@ -1169,15 +1091,13 @@ fn test_ls_quoting_style() { ("--quoting-style=shell", "one?two"), ("--quoting-style=shell-always", "'one?two'"), ] { - let result = scene + scene .ucmd() .arg(arg) .arg("--hide-control-chars") .arg("one\ntwo") - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert_eq!(result.stdout, format!("{}\n", correct)); + .succeeds() + .stdout_only(format!("{}\n", correct)); } for (arg, correct) in &[ @@ -1187,20 +1107,21 @@ fn test_ls_quoting_style() { ("--quoting-style=shell", "one\ntwo"), ("--quoting-style=shell-always", "'one\ntwo'"), ] { - let result = scene + scene .ucmd() .arg(arg) .arg("--show-control-chars") .arg("one\ntwo") - .run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert_eq!(result.stdout, format!("{}\n", correct)); + .succeeds() + .stdout_only(format!("{}\n", correct)); } } - let result = scene.ucmd().arg("one two").succeeds(); - assert_eq!(result.stdout, "'one two'\n"); + scene + .ucmd() + .arg("one two") + .succeeds() + .stdout_only("'one two'\n"); for (arg, correct) in &[ ("--quoting-style=literal", "one two"), @@ -1217,14 +1138,15 @@ fn test_ls_quoting_style() { ("--quoting-style=shell", "'one two'"), ("--quoting-style=shell-always", "'one two'"), ] { - let result = scene.ucmd().arg(arg).arg("one two").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert_eq!(result.stdout, format!("{}\n", correct)); + scene + .ucmd() + .arg(arg) + .arg("one two") + .succeeds() + .stdout_only(format!("{}\n", correct)); } - let result = scene.ucmd().arg("one").succeeds(); - assert_eq!(result.stdout, "one\n"); + scene.ucmd().arg("one").succeeds().stdout_only("one\n"); for (arg, correct) in &[ ("--quoting-style=literal", "one"), @@ -1239,10 +1161,12 @@ fn test_ls_quoting_style() { ("--quoting-style=shell", "one"), ("--quoting-style=shell-always", "'one'"), ] { - let result = scene.ucmd().arg(arg).arg("one").run(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - assert_eq!(result.stdout, format!("{}\n", correct)); + scene + .ucmd() + .arg(arg) + .arg("one") + .succeeds() + .stdout_only(format!("{}\n", correct)); } } @@ -1262,7 +1186,7 @@ fn test_ls_ignore_hide() { .arg("*") .arg("-1") .succeeds() - .stdout_is(""); + .stdout_only(""); scene .ucmd() @@ -1270,7 +1194,7 @@ fn test_ls_ignore_hide() { .arg("*") .arg("-1") .succeeds() - .stdout_is(""); + .stdout_only(""); scene .ucmd() @@ -1278,7 +1202,7 @@ fn test_ls_ignore_hide() { .arg("irrelevant pattern") .arg("-1") .succeeds() - .stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); + .stdout_only("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); scene .ucmd() @@ -1286,7 +1210,7 @@ fn test_ls_ignore_hide() { .arg("README*.md") .arg("-1") .succeeds() - .stdout_is("CONTRIBUTING.md\nsome_other_file\n"); + .stdout_only("CONTRIBUTING.md\nsome_other_file\n"); scene .ucmd() @@ -1294,7 +1218,7 @@ fn test_ls_ignore_hide() { .arg("README*.md") .arg("-1") .succeeds() - .stdout_is("CONTRIBUTING.md\nsome_other_file\n"); + .stdout_only("CONTRIBUTING.md\nsome_other_file\n"); scene .ucmd() @@ -1302,7 +1226,7 @@ fn test_ls_ignore_hide() { .arg("*.md") .arg("-1") .succeeds() - .stdout_is("some_other_file\n"); + .stdout_only("some_other_file\n"); scene .ucmd() @@ -1311,7 +1235,7 @@ fn test_ls_ignore_hide() { .arg("*.md") .arg("-1") .succeeds() - .stdout_is(".\n..\nsome_other_file\n"); + .stdout_only(".\n..\nsome_other_file\n"); scene .ucmd() @@ -1320,7 +1244,7 @@ fn test_ls_ignore_hide() { .arg("*.md") .arg("-1") .succeeds() - .stdout_is(".\n..\nCONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); + .stdout_only(".\n..\nCONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); scene .ucmd() @@ -1329,7 +1253,7 @@ fn test_ls_ignore_hide() { .arg("*.md") .arg("-1") .succeeds() - .stdout_is("some_other_file\n"); + .stdout_only("some_other_file\n"); scene .ucmd() @@ -1338,7 +1262,7 @@ fn test_ls_ignore_hide() { .arg("*.md") .arg("-1") .succeeds() - .stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); + .stdout_only("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); // Stacking multiple patterns scene @@ -1349,7 +1273,7 @@ fn test_ls_ignore_hide() { .arg("CONTRIBUTING*") .arg("-1") .succeeds() - .stdout_is("some_other_file\n"); + .stdout_only("some_other_file\n"); scene .ucmd() @@ -1359,7 +1283,7 @@ fn test_ls_ignore_hide() { .arg("CONTRIBUTING*") .arg("-1") .succeeds() - .stdout_is("some_other_file\n"); + .stdout_only("some_other_file\n"); scene .ucmd() @@ -1369,7 +1293,7 @@ fn test_ls_ignore_hide() { .arg("CONTRIBUTING*") .arg("-1") .succeeds() - .stdout_is("some_other_file\n"); + .stdout_only("some_other_file\n"); // Invalid patterns scene @@ -1378,7 +1302,8 @@ fn test_ls_ignore_hide() { .arg("READ[ME") .arg("-1") .succeeds() - .stderr_contains(&"Invalid pattern"); + .stderr_contains(&"Invalid pattern") + .stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); scene .ucmd() @@ -1386,5 +1311,6 @@ fn test_ls_ignore_hide() { .arg("READ[ME") .arg("-1") .succeeds() - .stderr_contains(&"Invalid pattern"); + .stderr_contains(&"Invalid pattern") + .stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n"); } From c65483f4bedc76160ce9aa009662199d45d12d0a Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Wed, 7 Apr 2021 11:48:21 +0200 Subject: [PATCH 123/132] tests: improve docstrings a bit --- tests/common/util.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/common/util.rs b/tests/common/util.rs index 708b8dbba..8a09b71c1 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -165,8 +165,8 @@ impl CmdResult { /// asserts that the command resulted in empty (zero-length) stderr stream output /// generally, it's better to use stdout_only() instead, /// but you might find yourself using this function if - /// 1. you can not know exactly what stdout will be - /// or 2. you know that stdout will also be empty + /// 1. you can not know exactly what stdout will be or + /// 2. you know that stdout will also be empty pub fn no_stderr(&self) -> &CmdResult { assert!(self.stderr.is_empty()); self @@ -176,8 +176,8 @@ impl CmdResult { /// unless asserting there was neither stdout or stderr, stderr_only is usually a better choice /// generally, it's better to use stderr_only() instead, /// but you might find yourself using this function if - /// 1. you can not know exactly what stderr will be - /// or 2. you know that stderr will also be empty + /// 1. you can not know exactly what stderr will be or + /// 2. you know that stderr will also be empty pub fn no_stdout(&self) -> &CmdResult { assert!(self.stdout.is_empty()); self @@ -223,9 +223,9 @@ impl CmdResult { } /// asserts that - /// 1. the command resulted in stdout stream output that equals the - /// passed in value, when both are trimmed of trailing whitespace - /// and 2. the command resulted in empty (zero-length) stderr stream output + /// 1. the command resulted in stdout stream output that equals the + /// passed in value + /// 2. the command resulted in empty (zero-length) stderr stream output pub fn stdout_only>(&self, msg: T) -> &CmdResult { self.no_stderr().stdout_is(msg) } @@ -245,9 +245,9 @@ impl CmdResult { } /// asserts that - /// 1. the command resulted in stderr stream output that equals the - /// passed in value, when both are trimmed of trailing whitespace - /// and 2. the command resulted in empty (zero-length) stdout stream output + /// 1. the command resulted in stderr stream output that equals the + /// passed in value, when both are trimmed of trailing whitespace + /// 2. the command resulted in empty (zero-length) stdout stream output pub fn stderr_only>(&self, msg: T) -> &CmdResult { self.no_stdout().stderr_is(msg) } From 04235854fa5f3f184eded4c34f6552a717395420 Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Wed, 7 Apr 2021 20:17:52 -0500 Subject: [PATCH 124/132] docs/README ~ fix markdown lint complaints (no-trailing-spaces) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b2257b3fd..ad4a3393a 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Why? Many GNU, Linux and other utilities are useful, and obviously [some](http://gnuwin32.sourceforge.net) [effort](http://unxutils.sourceforge.net) has been spent in the past to port them to Windows. However, those projects -are written in platform-specific C, a language considered unsafe compared to Rust, and +are written in platform-specific C, a language considered unsafe compared to Rust, and have other issues. Rust provides a good, platform-agnostic way of writing systems utilities that are easy From 26937b5d692f950df55b941aafba01ff9b1fe91d Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Wed, 7 Apr 2021 20:20:48 -0500 Subject: [PATCH 125/132] docs/README ~ fix markdown lint complaints (heading-style) --- README.md | 56 ++++++++++++++++++++++--------------------------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index ad4a3393a..ce257002d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -uutils coreutils -================ +# uutils coreutils [![Crates.io](https://img.shields.io/crates/v/coreutils.svg)](https://crates.io/crates/coreutils) [![Discord](https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat)](https://discord.gg/wQVJbvJ) @@ -17,8 +16,7 @@ uutils is an attempt at writing universal (as in cross-platform) CLI utilities in [Rust](http://www.rust-lang.org). This repository is intended to aggregate GNU coreutils rewrites. -Why? ----- +## Why? Many GNU, Linux and other utilities are useful, and obviously [some](http://gnuwin32.sourceforge.net) [effort](http://unxutils.sourceforge.net) @@ -29,23 +27,21 @@ have other issues. Rust provides a good, platform-agnostic way of writing systems utilities that are easy to compile anywhere, and this is as good a way as any to try and learn it. -Requirements ------------- +## Requirements * Rust (`cargo`, `rustc`) * GNU Make (required to build documentation) * [Sphinx](http://www.sphinx-doc.org/) (for documentation) * gzip (for installing documentation) -### Rust Version ### +### Rust Version uutils follows Rust's release channels and is tested against stable, beta and nightly. The current oldest supported version of the Rust compiler is `1.40.0`. On both Windows and Redox, only the nightly version is tested currently. -Build Instructions ------------------- +## Build Instructions There are currently two methods to build uutils: GNU Make and Cargo. However, while there may be two methods, both systems are required to build on Unix @@ -57,7 +53,7 @@ $ git clone https://github.com/uutils/coreutils $ cd coreutils ``` -### Cargo ### +### Cargo Building uutils using Cargo is easy because the process is the same as for every other Rust program: @@ -87,7 +83,7 @@ build the utilities as individual binaries, that is possible too. For example: $ cargo build -p uu_base32 -p uu_cat -p uu_echo -p uu_rm ``` -### GNU Make ### +### GNU Make Building using `make` is a simple process as well. @@ -106,10 +102,9 @@ To build only a few of the available utilities: $ make UTILS='UTILITY_1 UTILITY_2' ``` -Installation Instructions -------------------------- +## Installation Instructions -### Cargo ### +### Cargo Likewise, installing can simply be done using: ```bash @@ -118,7 +113,7 @@ $ cargo install --path . This command will install uutils into Cargo's *bin* folder (*e.g.* `$HOME/.cargo/bin`). -### GNU Make ### +### GNU Make To install all available utilities: ```bash @@ -156,7 +151,7 @@ Set install parent directory (default value is /usr/local): $ make PREFIX=/my/path install ``` -### NixOS ### +### NixOS The [standard package set](https://nixos.org/nixpkgs/manual/) of [NixOS](https://nixos.org/) provides this package out of the box since 18.03: @@ -165,21 +160,20 @@ provides this package out of the box since 18.03: nix-env -iA nixos.uutils-coreutils ``` -Uninstallation Instructions ---------------------------- +## Uninstallation Instructions Uninstallation differs depending on how you have installed uutils. If you used Cargo to install, use Cargo to uninstall. If you used GNU Make to install, use Make to uninstall. -### Cargo ### +### Cargo To uninstall uutils: ```bash $ cargo uninstall uutils ``` -### GNU Make ### +### GNU Make To uninstall all utilities: ```bash @@ -202,12 +196,11 @@ To uninstall from a custom parent directory: $ make PREFIX=/my/path uninstall ``` -Test Instructions ------------------ +## Test Instructions Testing can be done using either Cargo or `make`. -### Cargo ### +### Cargo Just like with building, we follow the standard procedure for testing using Cargo: @@ -238,7 +231,7 @@ $ gdb --args target/debug/coreutils ls (gdb) run ``` -### GNU Make ### +### GNU Make To simply test all available utilities: ```bash @@ -260,8 +253,7 @@ To include tests for unimplemented behavior: $ make UTILS='UTILITY_1 UTILITY_2' SPEC=y test ``` -Run Busybox Tests ------------------ +## Run Busybox Tests This testing functionality is only available on *nix operating systems and requires `make`. @@ -281,13 +273,11 @@ To pass an argument like "-v" to the busybox test runtime $ make UTILS='UTILITY_1 UTILITY_2' RUNTEST_ARGS='-v' busytest ``` -Contribute ----------- +## Contribute To contribute to uutils, please see [CONTRIBUTING](CONTRIBUTING.md). -Utilities ---------- +## Utilities | Done | Semi-Done | To Do | |-----------|-----------|--------| @@ -377,8 +367,7 @@ Utilities | whoami | | | | yes | | | -Targets that compile -------- +## Targets that compile This is an auto-generated table showing which binaries compile for each target-triple. Note that this **does not** indicate that they are fully implemented, or that the tests pass. @@ -405,8 +394,7 @@ This is an auto-generated table showing which binaries compile for each target-t |fuchsia|aarch64| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |fuchsia|x86_64| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | -License -------- +## License uutils is licensed under the MIT License - see the `LICENSE` file for details From a309c7cab08a29273b2f74b9e35e2654802caa8d Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Wed, 7 Apr 2021 20:22:33 -0500 Subject: [PATCH 126/132] docs/README ~ fix markdown lint complaints (blanks-around-fences) --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index ce257002d..2eacbf173 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ while there may be two methods, both systems are required to build on Unix (only Cargo is required on Windows). First, for both methods, we need to fetch the repository: + ```bash $ git clone https://github.com/uutils/coreutils $ cd coreutils @@ -57,6 +58,7 @@ $ cd coreutils Building uutils using Cargo is easy because the process is the same as for every other Rust program: + ```bash # to keep debug information, compile without --release $ cargo build --release @@ -65,6 +67,7 @@ $ cargo build --release Because the above command attempts to build utilities that only work on Unix-like platforms at the moment, to build on Windows, you must do the following: + ```bash # to keep debug information, compile without --release $ cargo build --release --no-default-features --features windows @@ -73,12 +76,14 @@ $ cargo build --release --no-default-features --features windows If you don't want to build every utility available on your platform into the multicall binary (the Busybox-esque binary), you can also specify which ones you want to build manually. For example: + ```bash $ cargo build --features "base32 cat echo rm" --no-default-features ``` If you don't even want to build the multicall binary and would prefer to just build the utilities as individual binaries, that is possible too. For example: + ```bash $ cargo build -p uu_base32 -p uu_cat -p uu_echo -p uu_rm ``` @@ -88,16 +93,19 @@ $ cargo build -p uu_base32 -p uu_cat -p uu_echo -p uu_rm Building using `make` is a simple process as well. To simply build all available utilities: + ```bash $ make ``` To build all but a few of the available utilities: + ```bash $ make SKIP_UTILS='UTILITY_1 UTILITY_2' ``` To build only a few of the available utilities: + ```bash $ make UTILS='UTILITY_1 UTILITY_2' ``` @@ -107,6 +115,7 @@ $ make UTILS='UTILITY_1 UTILITY_2' ### Cargo Likewise, installing can simply be done using: + ```bash $ cargo install --path . ``` @@ -116,36 +125,43 @@ This command will install uutils into Cargo's *bin* folder (*e.g.* `$HOME/.cargo ### GNU Make To install all available utilities: + ```bash $ make install ``` To install using `sudo` switch `-E` must be used: + ```bash $ sudo -E make install ``` To install all but a few of the available utilities: + ```bash $ make SKIP_UTILS='UTILITY_1 UTILITY_2' install ``` To install only a few of the available utilities: + ```bash $ make UTILS='UTILITY_1 UTILITY_2' install ``` To install every program with a prefix (e.g. uu-echo uu-cat): + ```bash $ make PROG_PREFIX=PREFIX_GOES_HERE install ``` To install the multicall binary: + ```bash $ make MULTICALL=y install ``` Set install parent directory (default value is /usr/local): + ```bash # DESTDIR is also supported $ make PREFIX=/my/path install @@ -169,6 +185,7 @@ Make to uninstall. ### Cargo To uninstall uutils: + ```bash $ cargo uninstall uutils ``` @@ -176,21 +193,25 @@ $ cargo uninstall uutils ### GNU Make To uninstall all utilities: + ```bash $ make uninstall ``` To uninstall every program with a set prefix: + ```bash $ make PROG_PREFIX=PREFIX_GOES_HERE uninstall ``` To uninstall the multicall binary: + ```bash $ make MULTICALL=y uninstall ``` To uninstall from a custom parent directory: + ```bash # DESTDIR is also supported $ make PREFIX=/my/path uninstall @@ -204,27 +225,32 @@ Testing can be done using either Cargo or `make`. Just like with building, we follow the standard procedure for testing using Cargo: + ```bash $ cargo test ``` By default, `cargo test` only runs the common programs. To run also platform specific tests, run: + ```bash $ cargo test --features unix ``` If you would prefer to test a select few utilities: + ```bash $ cargo test --features "chmod mv tail" --no-default-features ``` If you also want to test the core utilities: + ```bash $ cargo test -p uucore -p coreutils ``` To debug: + ```bash $ gdb --args target/debug/coreutils ls (gdb) b ls.rs:79 @@ -234,21 +260,25 @@ $ gdb --args target/debug/coreutils ls ### GNU Make To simply test all available utilities: + ```bash $ make test ``` To test all but a few of the available utilities: + ```bash $ make SKIP_UTILS='UTILITY_1 UTILITY_2' test ``` To test only a few of the available utilities: + ```bash $ make UTILS='UTILITY_1 UTILITY_2' test ``` To include tests for unimplemented behavior: + ```bash $ make UTILS='UTILITY_1 UTILITY_2' SPEC=y test ``` @@ -259,16 +289,19 @@ This testing functionality is only available on *nix operating systems and requires `make`. To run busybox's tests for all utilities for which busybox has tests + ```bash $ make busytest ``` To run busybox's tests for a few of the available utilities + ```bash $ make UTILS='UTILITY_1 UTILITY_2' busytest ``` To pass an argument like "-v" to the busybox test runtime + ```bash $ make UTILS='UTILITY_1 UTILITY_2' RUNTEST_ARGS='-v' busytest ``` From bf81f93be3aa03e3572c06b9405bf184ae504550 Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Wed, 7 Apr 2021 20:29:43 -0500 Subject: [PATCH 127/132] docs/README ~ fix markdown lint complaints (fenced-code-language) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2eacbf173..230b08d3b 100644 --- a/README.md +++ b/README.md @@ -172,8 +172,8 @@ $ make PREFIX=/my/path install The [standard package set](https://nixos.org/nixpkgs/manual/) of [NixOS](https://nixos.org/) provides this package out of the box since 18.03: -``` -nix-env -iA nixos.uutils-coreutils +```shell +$ nix-env -iA nixos.uutils-coreutils ``` ## Uninstallation Instructions From 6551d29a6e896caa2c829ab0c1c9b560c325ffaa Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Wed, 7 Apr 2021 20:32:58 -0500 Subject: [PATCH 128/132] docs/README ~ fix markdown lint complaints (*disable* commands-show-output & no-duplicate-heading) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 230b08d3b..c485c5c63 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ ----------------------------------------------- + + uutils is an attempt at writing universal (as in cross-platform) CLI utilities in [Rust](http://www.rust-lang.org). This repository is intended to aggregate GNU coreutils rewrites. From d0abe9e6c9756b49875b7d2923c1f4584e4050f5 Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Wed, 7 Apr 2021 20:36:51 -0500 Subject: [PATCH 129/132] docs/README ~ fix spelling (words and exceptions) --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c485c5c63..5bad664c1 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,12 @@ [![Build Status](https://api.travis-ci.org/uutils/coreutils.svg?branch=master)](https://travis-ci.org/uutils/coreutils) [![Build Status (FreeBSD)](https://api.cirrus-ci.com/github/uutils/coreutils.svg)](https://cirrus-ci.com/github/uutils/coreutils/master) -[![codecov](https://codecov.io/gh/uutils/coreutils/branch/master/graph/badge.svg)](https://codecov.io/gh/uutils/coreutils) +[![CodeCov](https://codecov.io/gh/uutils/coreutils/branch/master/graph/badge.svg)](https://codecov.io/gh/uutils/coreutils) ----------------------------------------------- + uutils is an attempt at writing universal (as in cross-platform) CLI utilities in [Rust](http://www.rust-lang.org). This repository is intended to @@ -178,9 +179,9 @@ provides this package out of the box since 18.03: $ nix-env -iA nixos.uutils-coreutils ``` -## Uninstallation Instructions +## Un-installation Instructions -Uninstallation differs depending on how you have installed uutils. If you used +Un-installation differs depending on how you have installed uutils. If you used Cargo to install, use Cargo to uninstall. If you used GNU Make to install, use Make to uninstall. From 8d7d1b0f355dc576f41083a13d02ad40b83444c9 Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Wed, 7 Apr 2021 20:59:40 -0500 Subject: [PATCH 130/132] docs/README ~ revise build instructions for binaries --- README.md | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 5bad664c1..76ea92ab5 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ----------------------------------------------- - + uutils is an attempt at writing universal (as in cross-platform) CLI utilities in [Rust](http://www.rust-lang.org). This repository is intended to @@ -46,11 +46,13 @@ On both Windows and Redox, only the nightly version is tested currently. ## Build Instructions -There are currently two methods to build uutils: GNU Make and Cargo. However, -while there may be two methods, both systems are required to build on Unix -(only Cargo is required on Windows). +There are currently two methods to build the uutils binaries: either Cargo +or GNU Make. -First, for both methods, we need to fetch the repository: +> Building the full package, including all documentation, requires both Cargo +> and Gnu Make on a Unix platform. + +For either method, we first need to fetch the repository: ```bash $ git clone https://github.com/uutils/coreutils @@ -63,29 +65,37 @@ Building uutils using Cargo is easy because the process is the same as for every other Rust program: ```bash -# to keep debug information, compile without --release $ cargo build --release ``` -Because the above command attempts to build utilities that only work on -Unix-like platforms at the moment, to build on Windows, you must do the -following: +This command builds the most portable common core set of uutils into a multicall +(BusyBox-type) binary, named 'coreutils', on most Rust-supported platforms. + +Additional platform-specific uutils are often available. Building these +expanded sets of uutils for a platform (on that platform) is as simple as +specifying it as a feature: ```bash -# to keep debug information, compile without --release -$ cargo build --release --no-default-features --features windows +$ cargo build --release --features macos +# or ... +$ cargo build --release --features windows +# or ... +$ cargo build --release --features unix ``` If you don't want to build every utility available on your platform into the -multicall binary (the Busybox-esque binary), you can also specify which ones -you want to build manually. For example: +final binary, you can also specify which ones you want to build manually. +For example: ```bash $ cargo build --features "base32 cat echo rm" --no-default-features ``` -If you don't even want to build the multicall binary and would prefer to just -build the utilities as individual binaries, that is possible too. For example: +If you don't want to build the multicall binary and would prefer to build +the utilities as individual binaries, that is also possible. Each utility +is contained in it's own package within the main repository, named +"uu_UTILNAME". To build individual utilities, use cargo to build just the +specific packages (using the `--package` [aka `-p`] option). For example: ```bash $ cargo build -p uu_base32 -p uu_cat -p uu_echo -p uu_rm From 8474249e5f301068565c2d62f04b04d40b0b5817 Mon Sep 17 00:00:00 2001 From: electricboogie <32370782+electricboogie@users.noreply.github.com> Date: Thu, 8 Apr 2021 15:07:09 -0500 Subject: [PATCH 131/132] Sort: Implement stable sort, ignore non-printing, month sort dedup, auto parallel sort through rayon, zero terminated sort, check silent (#2008) --- Cargo.lock | 20 +- src/uu/sort/Cargo.toml | 3 +- src/uu/sort/src/sort.rs | 582 +++++++++++++----- tests/by-util/test_sort.rs | 272 ++++++-- .../sort/exponents-positive-general.expected | 12 + .../sort/exponents-positive-general.txt | 12 + .../sort/exponents-positive-numeric.expected | 12 + .../sort/exponents-positive-numeric.txt | 12 + .../sort/human-mixed-inputs-reverse.expected | 37 ++ .../sort/human-mixed-inputs-reverse.txt | 37 ++ .../sort/human-mixed-inputs-stable.expected | 37 ++ .../sort/human-mixed-inputs-stable.txt | 37 ++ .../sort/human-mixed-inputs-unique.expected | 13 + .../sort/human-mixed-inputs-unique.txt | 37 ++ .../fixtures/sort/human-mixed-inputs.expected | 37 ++ tests/fixtures/sort/human-mixed-inputs.txt | 46 ++ .../mixed_floats_ints_chars_numeric.expected | 30 + .../sort/mixed_floats_ints_chars_numeric.txt | 30 + ...floats_ints_chars_numeric_reverse.expected | 30 + ...ints_chars_numeric_reverse_stable.expected | 30 + ...oats_ints_chars_numeric_reverse_stable.txt | 30 + ..._floats_ints_chars_numeric_stable.expected | 30 + ...mixed_floats_ints_chars_numeric_stable.txt | 30 + ..._floats_ints_chars_numeric_unique.expected | 20 + ...mixed_floats_ints_chars_numeric_unique.txt | 30 + ...ints_chars_numeric_unique_reverse.expected | 20 + ...oats_ints_chars_numeric_unique_reverse.txt | 30 + ..._ints_chars_numeric_unique_stable.expected | 20 + ...loats_ints_chars_numeric_unique_stable.txt | 30 + tests/fixtures/sort/months-dedup.expected | 6 + tests/fixtures/sort/months-dedup.txt | 37 ++ .../sort/numeric-floats-with-nan2.expected | 23 + .../sort/numeric-floats-with-nan2.txt | 23 + tests/fixtures/sort/zero-terminated.expected | 1 + tests/fixtures/sort/zero-terminated.txt | 1 + 35 files changed, 1444 insertions(+), 213 deletions(-) create mode 100644 tests/fixtures/sort/exponents-positive-general.expected create mode 100644 tests/fixtures/sort/exponents-positive-general.txt create mode 100644 tests/fixtures/sort/exponents-positive-numeric.expected create mode 100644 tests/fixtures/sort/exponents-positive-numeric.txt create mode 100644 tests/fixtures/sort/human-mixed-inputs-reverse.expected create mode 100644 tests/fixtures/sort/human-mixed-inputs-reverse.txt create mode 100644 tests/fixtures/sort/human-mixed-inputs-stable.expected create mode 100644 tests/fixtures/sort/human-mixed-inputs-stable.txt create mode 100644 tests/fixtures/sort/human-mixed-inputs-unique.expected create mode 100644 tests/fixtures/sort/human-mixed-inputs-unique.txt create mode 100644 tests/fixtures/sort/human-mixed-inputs.expected create mode 100644 tests/fixtures/sort/human-mixed-inputs.txt create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric.expected create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric.txt create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse.expected create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse_stable.expected create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse_stable.txt create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_stable.expected create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_stable.txt create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique.expected create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique.txt create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_reverse.expected create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_reverse.txt create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_stable.expected create mode 100644 tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_stable.txt create mode 100644 tests/fixtures/sort/months-dedup.expected create mode 100644 tests/fixtures/sort/months-dedup.txt create mode 100644 tests/fixtures/sort/numeric-floats-with-nan2.expected create mode 100644 tests/fixtures/sort/numeric-floats-with-nan2.txt create mode 100644 tests/fixtures/sort/zero-terminated.expected create mode 100644 tests/fixtures/sort/zero-terminated.txt diff --git a/Cargo.lock b/Cargo.lock index 9c73674c8..e094f1f48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1362,12 +1362,6 @@ dependencies = [ "maybe-uninit", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "strsim" version = "0.8.0" @@ -1522,17 +1516,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "twox-hash" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" -dependencies = [ - "cfg-if 0.1.10", - "rand 0.7.3", - "static_assertions", -] - [[package]] name = "typenum" version = "1.13.0" @@ -2301,10 +2284,11 @@ name = "uu_sort" version = "0.0.6" dependencies = [ "clap", + "fnv", "itertools 0.8.2", "rand 0.7.3", + "rayon", "semver", - "twox-hash", "uucore", "uucore_procs", ] diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index 7a6f95c41..814e4bbba 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -15,9 +15,10 @@ edition = "2018" path = "src/sort.rs" [dependencies] +rayon = "1.5" rand = "0.7" clap = "2.33" -twox-hash = "1.6.0" +fnv = "1.0.7" itertools = "0.8.0" semver = "0.9.0" uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["fs"] } diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 6c29ad98d..36e6ad71e 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -7,23 +7,29 @@ // * file that was distributed with this source code. #![allow(dead_code)] +// Although these links don't always seem to describe reality, check out the POSIX and GNU specs: +// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html +// https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html + // spell-checker:ignore (ToDO) outfile nondictionary #[macro_use] extern crate uucore; use clap::{App, Arg}; +use fnv::FnvHasher; use itertools::Itertools; use rand::distributions::Alphanumeric; use rand::{thread_rng, Rng}; +use rayon::prelude::*; use semver::Version; use std::cmp::Ordering; use std::collections::BinaryHeap; +use std::env; use std::fs::File; use std::hash::{Hash, Hasher}; use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Lines, Read, Write}; use std::mem::replace; use std::path::Path; -use twox_hash::XxHash64; use uucore::fs::is_stdin_interactive; // for Iterator::dedup() static NAME: &str = "sort"; @@ -33,27 +39,37 @@ static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_HUMAN_NUMERIC_SORT: &str = "human-numeric-sort"; static OPT_MONTH_SORT: &str = "month-sort"; static OPT_NUMERIC_SORT: &str = "numeric-sort"; +static OPT_GENERAL_NUMERIC_SORT: &str = "general-numeric-sort"; static OPT_VERSION_SORT: &str = "version-sort"; static OPT_DICTIONARY_ORDER: &str = "dictionary-order"; static OPT_MERGE: &str = "merge"; static OPT_CHECK: &str = "check"; +static OPT_CHECK_SILENT: &str = "check-silent"; static OPT_IGNORE_CASE: &str = "ignore-case"; static OPT_IGNORE_BLANKS: &str = "ignore-blanks"; +static OPT_IGNORE_NONPRINTING: &str = "ignore-nonprinting"; static OPT_OUTPUT: &str = "output"; static OPT_REVERSE: &str = "reverse"; static OPT_STABLE: &str = "stable"; static OPT_UNIQUE: &str = "unique"; static OPT_RANDOM: &str = "random-sort"; +static OPT_ZERO_TERMINATED: &str = "zero-terminated"; +static OPT_PARALLEL: &str = "parallel"; +static OPT_FILES0_FROM: &str = "files0-from"; static ARG_FILES: &str = "files"; static DECIMAL_PT: char = '.'; static THOUSANDS_SEP: char = ','; +static NEGATIVE: char = '-'; +static POSITIVE: char = '+'; + #[derive(Eq, Ord, PartialEq, PartialOrd)] enum SortMode { Numeric, HumanNumeric, + GeneralNumeric, Month, Version, Default, @@ -67,10 +83,13 @@ struct Settings { stable: bool, unique: bool, check: bool, + check_silent: bool, random: bool, - compare_fns: Vec Ordering>, + compare_fn: fn(&str, &str) -> Ordering, transform_fns: Vec String>, + threads: String, salt: String, + zero_terminated: bool, } impl Default for Settings { @@ -83,10 +102,13 @@ impl Default for Settings { stable: false, unique: false, check: false, + check_silent: false, random: false, - compare_fns: Vec::new(), + compare_fn: default_compare, transform_fns: Vec::new(), + threads: String::new(), salt: String::new(), + zero_terminated: false, } } } @@ -206,6 +228,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_NUMERIC_SORT) .help("compare according to string numerical value"), ) + .arg( + Arg::with_name(OPT_GENERAL_NUMERIC_SORT) + .short("g") + .long(OPT_GENERAL_NUMERIC_SORT) + .help("compare according to string general numerical value"), + ) .arg( Arg::with_name(OPT_VERSION_SORT) .short("V") @@ -230,12 +258,24 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_CHECK) .help("check for sorted input; do not sort"), ) + .arg( + Arg::with_name(OPT_CHECK_SILENT) + .short("C") + .long(OPT_CHECK_SILENT) + .help("exit successfully if the given file is already sorted, and exit with status 1 otherwise. "), + ) .arg( Arg::with_name(OPT_IGNORE_CASE) .short("f") .long(OPT_IGNORE_CASE) .help("fold lower case to upper case characters"), ) + .arg( + Arg::with_name(OPT_IGNORE_NONPRINTING) + .short("-i") + .long(OPT_IGNORE_NONPRINTING) + .help("ignore nonprinting characters"), + ) .arg( Arg::with_name(OPT_IGNORE_BLANKS) .short("b") @@ -274,18 +314,65 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .long(OPT_UNIQUE) .help("output only the first of an equal run"), ) + .arg( + Arg::with_name(OPT_ZERO_TERMINATED) + .short("z") + .long(OPT_ZERO_TERMINATED) + .help("line delimiter is NUL, not newline"), + ) + .arg( + Arg::with_name(OPT_PARALLEL) + .long(OPT_PARALLEL) + .help("change the number of threads running concurrently to N") + .takes_value(true) + .value_name("NUM_THREADS"), + ) + .arg( + Arg::with_name(OPT_FILES0_FROM) + .long(OPT_FILES0_FROM) + .help("read input from the files specified by NUL-terminated NUL_FILES") + .takes_value(true) + .value_name("NUL_FILES") + .multiple(true), + ) .arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true)) .get_matches_from(args); - let mut files: Vec = matches - .values_of(ARG_FILES) - .map(|v| v.map(ToString::to_string).collect()) - .unwrap_or_default(); + // check whether user specified a zero terminated list of files for input, otherwise read files from args + let mut files: Vec = if matches.is_present(OPT_FILES0_FROM) { + let files0_from: Vec = matches + .values_of(OPT_FILES0_FROM) + .map(|v| v.map(ToString::to_string).collect()) + .unwrap_or_default(); + + let mut files = Vec::new(); + for path in &files0_from { + let (reader, _) = open(path.as_str()).expect("Could not read from file specified."); + let buf_reader = BufReader::new(reader); + for line in buf_reader.split(b'\0') { + if let Ok(n) = line { + files.push( + std::str::from_utf8(&n) + .expect("Could not parse zero terminated string from input.") + .to_string(), + ); + } + } + } + files + } else { + matches + .values_of(ARG_FILES) + .map(|v| v.map(ToString::to_string).collect()) + .unwrap_or_default() + }; settings.mode = if matches.is_present(OPT_HUMAN_NUMERIC_SORT) { SortMode::HumanNumeric } else if matches.is_present(OPT_MONTH_SORT) { SortMode::Month + } else if matches.is_present(OPT_GENERAL_NUMERIC_SORT) { + SortMode::GeneralNumeric } else if matches.is_present(OPT_NUMERIC_SORT) { SortMode::Numeric } else if matches.is_present(OPT_VERSION_SORT) { @@ -294,12 +381,29 @@ pub fn uumain(args: impl uucore::Args) -> i32 { SortMode::Default }; - if matches.is_present(OPT_DICTIONARY_ORDER) { - settings.transform_fns.push(remove_nondictionary_chars); + if matches.is_present(OPT_PARALLEL) { + // "0" is default - threads = num of cores + settings.threads = matches + .value_of(OPT_PARALLEL) + .map(String::from) + .unwrap_or("0".to_string()); + env::set_var("RAYON_NUM_THREADS", &settings.threads); } + if matches.is_present(OPT_DICTIONARY_ORDER) { + settings.transform_fns.push(remove_nondictionary_chars); + } else if matches.is_present(OPT_IGNORE_NONPRINTING) { + settings.transform_fns.push(remove_nonprinting_chars); + } + + settings.zero_terminated = matches.is_present(OPT_ZERO_TERMINATED); settings.merge = matches.is_present(OPT_MERGE); + settings.check = matches.is_present(OPT_CHECK); + if matches.is_present(OPT_CHECK_SILENT) { + settings.check_silent = matches.is_present(OPT_CHECK_SILENT); + settings.check = true; + }; if matches.is_present(OPT_IGNORE_CASE) { settings.transform_fns.push(|s| s.to_uppercase()); @@ -327,20 +431,14 @@ pub fn uumain(args: impl uucore::Args) -> i32 { crash!(1, "sort: extra operand `{}' not allowed with -c", files[1]) } - settings.compare_fns.push(match settings.mode { + settings.compare_fn = match settings.mode { SortMode::Numeric => numeric_compare, + SortMode::GeneralNumeric => general_numeric_compare, SortMode::HumanNumeric => human_numeric_size_compare, SortMode::Month => month_compare, SortMode::Version => version_compare, SortMode::Default => default_compare, - }); - - if !settings.stable { - match settings.mode { - SortMode::Default => {} - _ => settings.compare_fns.push(default_compare), - } - } + }; exec(files, &mut settings) } @@ -359,67 +457,79 @@ fn exec(files: Vec, settings: &mut Settings) -> i32 { if settings.merge { file_merger.push_file(buf_reader.lines()); - } else if settings.check { - return exec_check_file(buf_reader.lines(), &settings); + } else if settings.zero_terminated { + for line in buf_reader.split(b'\0') { + if let Ok(n) = line { + lines.push( + std::str::from_utf8(&n) + .expect("Could not parse string from zero terminated input.") + .to_string(), + ); + } + } } else { for line in buf_reader.lines() { if let Ok(n) = line { lines.push(n); - } else { - break; } } } } - sort_by(&mut lines, &settings); + if settings.check { + return exec_check_file(lines, &settings); + } else { + sort_by(&mut lines, &settings); + } if settings.merge { if settings.unique { - print_sorted(file_merger.dedup(), &settings.outfile) + print_sorted(file_merger.dedup(), &settings) } else { - print_sorted(file_merger, &settings.outfile) + print_sorted(file_merger, &settings) } - } else if settings.unique && settings.mode == SortMode::Numeric { + } else if settings.mode == SortMode::Month && settings.unique { print_sorted( lines .iter() - .dedup_by(|a, b| num_sort_dedup(a) == num_sort_dedup(b)), - &settings.outfile, + .dedup_by(|a, b| get_months_dedup(a) == get_months_dedup(b)), + &settings, ) } else if settings.unique { - print_sorted(lines.iter().dedup(), &settings.outfile) + print_sorted( + lines + .iter() + .dedup_by(|a, b| get_nums_dedup(a) == get_nums_dedup(b)), + &settings, + ) } else { - print_sorted(lines.iter(), &settings.outfile) + print_sorted(lines.iter(), &settings) } 0 } -fn exec_check_file(lines: Lines>>, settings: &Settings) -> i32 { +fn exec_check_file(unwrapped_lines: Vec, settings: &Settings) -> i32 { // errors yields the line before each disorder, // plus the last line (quirk of .coalesce()) - let unwrapped_lines = lines.filter_map(|maybe_line| { - if let Ok(line) = maybe_line { - Some(line) - } else { - None - } - }); - let mut errors = unwrapped_lines - .enumerate() - .coalesce(|(last_i, last_line), (i, line)| { - if compare_by(&last_line, &line, &settings) == Ordering::Greater { - Err(((last_i, last_line), (i, line))) - } else { - Ok((i, line)) - } - }); + let mut errors = + unwrapped_lines + .iter() + .enumerate() + .coalesce(|(last_i, last_line), (i, line)| { + if compare_by(&last_line, &line, &settings) == Ordering::Greater { + Err(((last_i, last_line), (i, line))) + } else { + Ok((i, line)) + } + }); if let Some((first_error_index, _line)) = errors.next() { // Check for a second "error", as .coalesce() always returns the last // line, no matter what our merging function does. if let Some(_last_line_or_next_error) = errors.next() { - println!("sort: disorder in line {}", first_error_index); + if !settings.check_silent { + println!("sort: disorder in line {}", first_error_index); + }; 1 } else { // first "error" was actually the last line. @@ -431,8 +541,9 @@ fn exec_check_file(lines: Lines>>, settings: &Settings) } } +#[inline(always)] fn transform(line: &str, settings: &Settings) -> String { - let mut transformed = line.to_string(); + let mut transformed = line.to_owned(); for transform_fn in &settings.transform_fns { transformed = transform_fn(&transformed); } @@ -440,8 +551,9 @@ fn transform(line: &str, settings: &Settings) -> String { transformed } +#[inline(always)] fn sort_by(lines: &mut Vec, settings: &Settings) { - lines.sort_by(|a, b| compare_by(a, b, &settings)) + lines.par_sort_by(|a, b| compare_by(a, b, &settings)) } fn compare_by(a: &str, b: &str, settings: &Settings) -> Ordering { @@ -454,72 +566,198 @@ fn compare_by(a: &str, b: &str, settings: &Settings) -> Ordering { (a, b) }; - for compare_fn in &settings.compare_fns { - let cmp: Ordering = if settings.random { - random_shuffle(a, b, settings.salt.clone()) + // 1st Compare + let mut cmp: Ordering = if settings.random { + random_shuffle(a, b, settings.salt.clone()) + } else { + (settings.compare_fn)(a, b) + }; + + // Call "last resort compare" on any equal + if cmp == Ordering::Equal { + if settings.random || settings.stable || settings.unique { + cmp = Ordering::Equal } else { - compare_fn(a, b) + cmp = default_compare(a, b) }; - if cmp != Ordering::Equal { - if settings.reverse { - return cmp.reverse(); - } else { - return cmp; - } - } + }; + + if settings.reverse { + return cmp.reverse(); + } else { + return cmp; } - Ordering::Equal } +// Test output against BSDs and GNU with their locale +// env var set to lc_ctype=utf-8 to enjoy the exact same output. +#[inline(always)] fn default_compare(a: &str, b: &str) -> Ordering { a.cmp(b) } -fn get_leading_number(a: &str) -> &str { +// This function does the initial detection of numeric lines. +// Lines starting with a number or positive or negative sign. +// It also strips the string of any thing that could never +// be a number for the purposes of any type of numeric comparison. +#[inline(always)] +fn leading_num_common(a: &str) -> &str { let mut s = ""; - for c in a.chars() { - if !c.is_numeric() && !c.eq(&'-') && !c.eq(&' ') && !c.eq(&'.') && !c.eq(&',') { - s = a.trim().split(c).next().unwrap(); + for (idx, c) in a.char_indices() { + // check whether char is numeric, whitespace or decimal point or thousand seperator + if !c.is_numeric() + && !c.is_whitespace() + && !c.eq(&DECIMAL_PT) + && !c.eq(&THOUSANDS_SEP) + // check for e notation + && !c.eq(&'e') + && !c.eq(&'E') + // check whether first char is + or - + && !a.chars().nth(0).unwrap_or('\0').eq(&POSITIVE) + && !a.chars().nth(0).unwrap_or('\0').eq(&NEGATIVE) + { + // Strip string of non-numeric trailing chars + s = &a[..idx]; break; } - s = a.trim(); + // If line is not a number line, return the line as is + s = a; } - return s; + s } -// Matches GNU behavior, see: -// https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html -// Specifically *not* the same as sort -n | uniq -fn num_sort_dedup(a: &str) -> &str { - // Empty lines are dumped - if a.is_empty() { - return "0"; - // And lines that don't begin numerically are dumped - } else if !a.trim().chars().nth(0).unwrap_or('\0').is_numeric() { - return "0"; - } else { - // Prepare lines for comparison of only the numerical leading numbers - return get_leading_number(a); +// This function cleans up the initial comparison done by leading_num_common for a numeric compare. +// GNU sort does its numeric comparison through strnumcmp. However, we don't have or +// may not want to use libc. Instead we emulate the GNU sort numeric compare by ignoring +// those leading number lines GNU sort would not recognize. GNU numeric compare would +// not recognize a positive sign or scientific/E notation so we strip those elements here. +fn get_leading_num(a: &str) -> &str { + let mut s = ""; + let b = leading_num_common(a); + + // GNU numeric sort doesn't recognize '+' or 'e' notation so we strip + for (idx, c) in b.char_indices() { + if c.eq(&'e') || c.eq(&'E') || b.chars().nth(0).unwrap_or('\0').eq(&POSITIVE) { + s = &b[..idx]; + break; + } + // If no further processing needed to be done, return the line as-is to be sorted + s = b; + } + + // And empty number or non-number lines are to be treated as ‘0’ but only for numeric sort + // All '0'-ed lines will be sorted later, but only amongst themselves, during the so-called 'last resort comparison.' + if s.is_empty() { + s = "0"; }; + s +} + +// This function cleans up the initial comparison done by leading_num_common for a general numeric compare. +// In contrast to numeric compare, GNU general numeric/FP sort *should* recognize positive signs and +// scientific notation, so we strip those lines only after the end of the following numeric string. +// For example, 5e10KFD would be 5e10 or 5x10^10 and +10000HFKJFK would become 10000. +fn get_leading_gen(a: &str) -> String { + // Make this iter peekable to see if next char is numeric + let mut p_iter = leading_num_common(a).chars().peekable(); + let mut r = String::new(); + // Cleanup raw stripped strings + for c in p_iter.to_owned() { + let next_char_numeric = p_iter.peek().unwrap_or(&'\0').is_numeric(); + // Only general numeric recognizes e notation and, see block below, the '+' sign + if (c.eq(&'e') && !next_char_numeric) + || (c.eq(&'E') && !next_char_numeric) + { + r = a.split(c).next().unwrap_or("").to_owned(); + break; + // If positive sign and next char is not numeric, split at postive sign at keep trailing numbers + // There is a more elegant way to do this in Rust 1.45, std::str::strip_prefix + } else if c.eq(&POSITIVE) && !next_char_numeric { + let mut v: Vec<&str> = a.split(c).collect(); + let x = v.split_off(1); + r = x.join(""); + break; + // If no further processing needed to be done, return the line as-is to be sorted + } else { + r = a.to_owned(); + } + } + r +} + +fn get_months_dedup(a: &str) -> String { + let pattern = if a.trim().len().ge(&3) { + // Split at 3rd char and get first element of tuple ".0" + a.split_at(3).0 + } else { + "" + }; + + let month = match pattern.to_uppercase().as_ref() { + "JAN" => Month::January, + "FEB" => Month::February, + "MAR" => Month::March, + "APR" => Month::April, + "MAY" => Month::May, + "JUN" => Month::June, + "JUL" => Month::July, + "AUG" => Month::August, + "SEP" => Month::September, + "OCT" => Month::October, + "NOV" => Month::November, + "DEC" => Month::December, + _ => Month::Unknown, + }; + + if month == Month::Unknown { + "".to_owned() + } else { + pattern.to_uppercase() + } +} + +// *For all dedups/uniques we must compare leading numbers* +// Also note numeric compare and unique output is specifically *not* the same as a "sort | uniq" +// See: https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html +fn get_nums_dedup(a: &str) -> &str { + // Trim and remove any leading zeros + let s = a.trim().trim_start_matches('0'); + + // Get first char + let c = s.chars().nth(0).unwrap_or('\0'); + + // Empty lines and non-number lines are treated as the same for dedup + if s.is_empty() { + "" + } else if !c.eq(&NEGATIVE) && !c.is_numeric() { + "" + // Prepare lines for comparison of only the numerical leading numbers + } else { + get_leading_num(s) + } } /// Parse the beginning string into an f64, returning -inf instead of NaN on errors. +#[inline(always)] fn permissive_f64_parse(a: &str) -> f64 { + // Remove thousands seperators + let a = a.replace(THOUSANDS_SEP, ""); + // GNU sort treats "NaN" as non-number in numeric, so it needs special care. - match a.parse::() { + // *Keep this trim before parse* despite what POSIX may say about -b and -n + // because GNU and BSD both seem to require it to match their behavior + match a.trim().parse::() { Ok(a) if a.is_nan() => std::f64::NEG_INFINITY, Ok(a) => a, Err(_) => std::f64::NEG_INFINITY, } } -/// Compares two floats, with errors and non-numerics assumed to be -inf. -/// Stops coercing at the first non-numeric char. fn numeric_compare(a: &str, b: &str) -> Ordering { #![allow(clippy::comparison_chain)] - let sa = get_leading_number(a); - let sb = get_leading_number(b); + let sa = get_leading_num(a); + let sb = get_leading_num(b); let fa = permissive_f64_parse(sa); let fb = permissive_f64_parse(sb); @@ -534,27 +772,17 @@ fn numeric_compare(a: &str, b: &str) -> Ordering { } } -fn human_numeric_convert(a: &str) -> f64 { - let int_str = get_leading_number(a); - let (_, s) = a.split_at(int_str.len()); - let int_part = permissive_f64_parse(int_str); - let suffix: f64 = match s.parse().unwrap_or('\0') { - 'K' => 1000f64, - 'M' => 1E6, - 'G' => 1E9, - 'T' => 1E12, - 'P' => 1E15, - _ => 1f64, - }; - int_part * suffix -} - -/// Compare two strings as if they are human readable sizes. -/// AKA 1M > 100k -fn human_numeric_size_compare(a: &str, b: &str) -> Ordering { +/// Compares two floats, with errors and non-numerics assumed to be -inf. +/// Stops coercing at the first non-numeric char. +fn general_numeric_compare(a: &str, b: &str) -> Ordering { #![allow(clippy::comparison_chain)] - let fa = human_numeric_convert(a); - let fb = human_numeric_convert(b); + + let sa = get_leading_gen(a); + let sb = get_leading_gen(b); + + let fa = permissive_f64_parse(&sa); + let fb = permissive_f64_parse(&sb); + // f64::cmp isn't implemented (due to NaN issues); implement directly instead if fa > fb { Ordering::Greater @@ -565,14 +793,46 @@ fn human_numeric_size_compare(a: &str, b: &str) -> Ordering { } } -fn random_shuffle(a: &str, b: &str, salt: String) -> Ordering { +// GNU/BSD does not handle converting numbers to an equal scale +// properly. GNU/BSD simply recognize that there is a human scale and sorts +// those numbers ahead of other number inputs. There are perhaps limits +// to the type of behavior we should emulate, and this might be such a limit. +// Properly handling these units seems like a value add to me. And when sorting +// these types of numbers, we rarely care about pure performance. +fn human_numeric_convert(a: &str) -> f64 { + let num_str = get_leading_num(a); + let suffix = a.trim_start_matches(num_str); + let num_part = permissive_f64_parse(num_str); + let suffix: f64 = match suffix.parse().unwrap_or('\0') { + // SI Units + 'K' => 1E3, + 'M' => 1E6, + 'G' => 1E9, + 'T' => 1E12, + 'P' => 1E15, + 'E' => 1E18, + 'Z' => 1E21, + 'Y' => 1E24, + _ => 1f64, + }; + num_part * suffix +} + +/// Compare two strings as if they are human readable sizes. +/// AKA 1M > 100k +fn human_numeric_size_compare(a: &str, b: &str) -> Ordering { #![allow(clippy::comparison_chain)] - let salt_slice = salt.as_str(); + let fa = human_numeric_convert(a); + let fb = human_numeric_convert(b); - let da = hash(&[a, salt_slice].concat()); - let db = hash(&[b, salt_slice].concat()); - - da.cmp(&db) + // f64::cmp isn't implemented (due to NaN issues); implement directly instead + if fa > fb { + Ordering::Greater + } else if fa < fb { + Ordering::Less + } else { + Ordering::Equal + } } fn get_rand_string() -> String { @@ -583,12 +843,22 @@ fn get_rand_string() -> String { .collect::() } -fn hash(t: &T) -> u64 { - let mut s: XxHash64 = Default::default(); +fn get_hash(t: &T) -> u64 { + let mut s: FnvHasher = Default::default(); t.hash(&mut s); s.finish() } +fn random_shuffle(a: &str, b: &str, x: String) -> Ordering { + #![allow(clippy::comparison_chain)] + let salt_slice = x.as_str(); + + let da = get_hash(&[a, salt_slice].concat()); + let db = get_hash(&[b, salt_slice].concat()); + + da.cmp(&db) +} + #[derive(Eq, Ord, PartialEq, PartialOrd)] enum Month { Unknown, @@ -608,13 +878,15 @@ enum Month { /// Parse the beginning string into a Month, returning Month::Unknown on errors. fn month_parse(line: &str) -> Month { - match line - .split_whitespace() - .next() - .unwrap() - .to_uppercase() - .as_ref() - { + // GNU splits at any 3 letter match "JUNNNN" is JUN + let pattern = if line.trim().len().ge(&3) { + // Split a 3 and get first element of tuple ".0" + line.split_at(3).0 + } else { + "" + }; + + match pattern.to_uppercase().as_ref() { "JAN" => Month::January, "FEB" => Month::February, "MAR" => Month::March, @@ -632,7 +904,16 @@ fn month_parse(line: &str) -> Month { } fn month_compare(a: &str, b: &str) -> Ordering { - month_parse(a).cmp(&month_parse(b)) + let ma = month_parse(a); + let mb = month_parse(b); + + if ma > mb { + Ordering::Greater + } else if ma < mb { + Ordering::Less + } else { + Ordering::Equal + } } fn version_compare(a: &str, b: &str) -> Ordering { @@ -650,19 +931,26 @@ fn version_compare(a: &str, b: &str) -> Ordering { } fn remove_nondictionary_chars(s: &str) -> String { - // Using 'is_ascii_whitespace()' instead of 'is_whitespace()', because it - // uses only symbols compatible with UNIX sort (space, tab, newline). - // 'is_whitespace()' uses more symbols as whitespace (e.g. vertical tab). + // According to GNU, dictionary chars are those of ASCII + // and a blank is a space or a tab s.chars() - .filter(|c| c.is_alphanumeric() || c.is_ascii_whitespace()) + .filter(|c| c.is_ascii_alphanumeric() || c.is_ascii_whitespace()) .collect::() } -fn print_sorted>(iter: T, outfile: &Option) +fn remove_nonprinting_chars(s: &str) -> String { + // However, GNU says nonprinting chars are more permissive. + // All of ASCII except control chars ie, escape, newline + s.chars() + .filter(|c| c.is_ascii() && !c.is_ascii_control()) + .collect::() +} + +fn print_sorted>(iter: T, settings: &Settings) where S: std::fmt::Display, { - let mut file: Box = match *outfile { + let mut file: Box = match settings.outfile { Some(ref filename) => match File::create(Path::new(&filename)) { Ok(f) => Box::new(BufWriter::new(f)) as Box, Err(e) => { @@ -673,9 +961,16 @@ where None => Box::new(stdout()) as Box, }; - for line in iter { - let str = format!("{}\n", line); - crash_if_err!(1, file.write_all(str.as_bytes())) + if settings.zero_terminated { + for line in iter { + let str = format!("{}\0", line); + crash_if_err!(1, file.write_all(str.as_bytes())); + } + } else { + for line in iter { + let str = format!("{}\n", line); + crash_if_err!(1, file.write_all(str.as_bytes())); + } } } @@ -700,6 +995,22 @@ mod tests { use super::*; + #[test] + fn test_get_hash() { + let a = "Ted".to_string(); + + assert_eq!(2646829031758483623, get_hash(&a)); + } + + #[test] + fn test_random_shuffle() { + let a = "Ted"; + let b = "Ted"; + let c = get_rand_string(); + + assert_eq!(Ordering::Equal, random_shuffle(a, b, c)); + } + #[test] fn test_default_compare() { let a = "your own"; @@ -746,13 +1057,4 @@ mod tests { assert_eq!(Ordering::Less, version_compare(a, b)); } - - #[test] - fn test_random_compare() { - let a = "9"; - let b = "9"; - let c = get_rand_string(); - - assert_eq!(Ordering::Equal, random_shuffle(a, b, c)); - } } diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index 2bac71def..43aaf1da1 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -1,44 +1,82 @@ use crate::common::util::*; +#[test] +fn test_check_zero_terminated_failure() { + new_ucmd!() + .arg("-z") + .arg("-c") + .arg("zero-terminated.txt") + .fails() + .stdout_is("sort: disorder in line 0\n"); +} + +#[test] +fn test_check_zero_terminated_success() { + new_ucmd!() + .arg("-z") + .arg("-c") + .arg("zero-terminated.expected") + .succeeds(); +} + +#[test] +fn test_random_shuffle_len() { + // check whether output is the same length as the input + const FILE: &'static str = "default_unsorted_ints.expected"; + let (at, _ucmd) = at_and_ucmd!(); + let result = new_ucmd!().arg("-R").arg(FILE).run().stdout; + let expected = at.read(FILE); + + assert_ne!(result, expected); + assert_eq!(result.len(), expected.len()); +} + +#[test] +fn test_random_shuffle_contains_all_lines() { + // check whether lines of input are all in output + const FILE: &'static str = "default_unsorted_ints.expected"; + let (at, _ucmd) = at_and_ucmd!(); + let result = new_ucmd!().arg("-R").arg(FILE).run().stdout; + let expected = at.read(FILE); + let result_sorted = new_ucmd!().pipe_in(result.clone()).run().stdout; + + assert_ne!(result, expected); + assert_eq!(result_sorted, expected); +} + +#[test] +fn test_random_shuffle_contains_two_runs_not_the_same() { + // check to verify that two random shuffles are not equal; this has the + // potential to fail in the unlikely event that random order is the same + // as the starting order, or if both random sorts end up having the same order. + const FILE: &'static str = "default_unsorted_ints.expected"; + let (at, _ucmd) = at_and_ucmd!(); + let result = new_ucmd!().arg("-R").arg(FILE).run().stdout; + let expected = at.read(FILE); + let unexpected = new_ucmd!().arg("-R").arg(FILE).run().stdout; + + assert_ne!(result, expected); + assert_ne!(result, unexpected); +} + #[test] fn test_numeric_floats_and_ints() { - for numeric_sort_param in vec!["-n", "--numeric-sort"] { - let input = "1.444\n8.013\n1\n-8\n1.04\n-1"; - new_ucmd!() - .arg(numeric_sort_param) - .pipe_in(input) - .succeeds() - .stdout_only("-8\n-1\n1\n1.04\n1.444\n8.013\n"); - } + test_helper("numeric_floats_and_ints", "-n"); } #[test] fn test_numeric_floats() { - for numeric_sort_param in vec!["-n", "--numeric-sort"] { - let input = "1.444\n8.013\n1.58590\n-8.90880\n1.040000000\n-.05"; - new_ucmd!() - .arg(numeric_sort_param) - .pipe_in(input) - .succeeds() - .stdout_only("-8.90880\n-.05\n1.040000000\n1.444\n1.58590\n8.013\n"); - } + test_helper("numeric_floats", "-n"); } #[test] fn test_numeric_floats_with_nan() { - for numeric_sort_param in vec!["-n", "--numeric-sort"] { - let input = "1.444\n1.0/0.0\n1.58590\n-8.90880\n1.040000000\n-.05"; - new_ucmd!() - .arg(numeric_sort_param) - .pipe_in(input) - .succeeds() - .stdout_only("-8.90880\n-.05\n1.0/0.0\n1.040000000\n1.444\n1.58590\n"); - } + test_helper("numeric_floats_with_nan", "-n"); } #[test] fn test_numeric_unfixed_floats() { - test_helper("numeric_fixed_floats", "-n"); + test_helper("numeric_unfixed_floats", "-n"); } #[test] @@ -53,26 +91,12 @@ fn test_numeric_unsorted_ints() { #[test] fn test_human_block_sizes() { - for human_numeric_sort_param in vec!["-h", "--human-numeric-sort"] { - let input = "8981K\n909991M\n-8T\n21G\n0.8M"; - new_ucmd!() - .arg(human_numeric_sort_param) - .pipe_in(input) - .succeeds() - .stdout_only("-8T\n0.8M\n8981K\n21G\n909991M\n"); - } + test_helper("human_block_sizes", "-h"); } #[test] fn test_month_default() { - for month_sort_param in vec!["-M", "--month-sort"] { - let input = "JAn\nMAY\n000may\nJun\nFeb"; - new_ucmd!() - .arg(month_sort_param) - .pipe_in(input) - .succeeds() - .stdout_only("000may\nJAn\nFeb\nMAY\nJun\n"); - } + test_helper("month_default", "-M"); } #[test] @@ -82,23 +106,12 @@ fn test_month_stable() { #[test] fn test_default_unsorted_ints() { - let input = "9\n1909888\n000\n1\n2"; - new_ucmd!() - .pipe_in(input) - .succeeds() - .stdout_only("000\n1\n1909888\n2\n9\n"); + test_helper("default_unsorted_ints", ""); } #[test] fn test_numeric_unique_ints() { - for numeric_unique_sort_param in vec!["-nu"] { - let input = "9\n9\n8\n1\n"; - new_ucmd!() - .arg(numeric_unique_sort_param) - .pipe_in(input) - .succeeds() - .stdout_only("1\n8\n9\n"); - } + test_helper("numeric_unsorted_ints_unique", "-nu"); } #[test] @@ -116,6 +129,148 @@ fn test_dictionary_order() { test_helper("dictionary_order", "-d"); } +#[test] +fn test_dictionary_order2() { + for non_dictionary_order2_param in vec!["-d"] { + new_ucmd!() + .pipe_in("a👦🏻aa b\naaaa b") + .arg(non_dictionary_order2_param) + .succeeds() + .stdout_only("a👦🏻aa b\naaaa b\n"); + } +} + +#[test] +fn test_non_printing_chars() { + for non_printing_chars_param in vec!["-i"] { + new_ucmd!() + .pipe_in("a👦🏻aa b\naaaa b") + .arg(non_printing_chars_param) + .succeeds() + .stdout_only("aaaa b\na👦🏻aa b\n"); + } +} + +#[test] +fn test_exponents_positive_general_fixed() { + for exponents_positive_general_param in vec!["-g"] { + new_ucmd!() + .pipe_in("100E6\n\n50e10\n+100000\n\n10000K78\n10E\n\n\n1000EDKLD\n\n\n100E6\n\n50e10\n+100000\n\n") + .arg(exponents_positive_general_param) + .succeeds() + .stdout_only("\n\n\n\n\n\n\n\n10000K78\n1000EDKLD\n10E\n+100000\n+100000\n100E6\n100E6\n50e10\n50e10\n"); + } +} + +#[test] +fn test_exponents_positive_numeric() { + test_helper("exponents-positive-numeric", "-n"); +} + +#[test] +fn test_months_dedup() { + test_helper("months-dedup", "-Mu"); +} + +#[test] +fn test_mixed_floats_ints_chars_numeric() { + test_helper("mixed_floats_ints_chars_numeric", "-n"); +} + +#[test] +fn test_mixed_floats_ints_chars_numeric_unique() { + test_helper("mixed_floats_ints_chars_numeric_unique", "-nu"); +} + +#[test] +fn test_mixed_floats_ints_chars_numeric_reverse() { + test_helper("mixed_floats_ints_chars_numeric_unique_reverse", "-nur"); +} + +#[test] +fn test_mixed_floats_ints_chars_numeric_stable() { + test_helper("mixed_floats_ints_chars_numeric_stable", "-ns"); +} + +#[test] +fn test_numeric_floats_and_ints2() { + for numeric_sort_param in vec!["-n", "--numeric-sort"] { + let input = "1.444\n8.013\n1\n-8\n1.04\n-1"; + new_ucmd!() + .arg(numeric_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("-8\n-1\n1\n1.04\n1.444\n8.013\n"); + } +} + +#[test] +fn test_numeric_floats2() { + for numeric_sort_param in vec!["-n", "--numeric-sort"] { + let input = "1.444\n8.013\n1.58590\n-8.90880\n1.040000000\n-.05"; + new_ucmd!() + .arg(numeric_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("-8.90880\n-.05\n1.040000000\n1.444\n1.58590\n8.013\n"); + } +} + +#[test] +fn test_numeric_floats_with_nan2() { + test_helper("numeric-floats-with-nan2", "-n"); +} + +#[test] +fn test_human_block_sizes2() { + for human_numeric_sort_param in vec!["-h", "--human-numeric-sort"] { + let input = "8981K\n909991M\n-8T\n21G\n0.8M"; + new_ucmd!() + .arg(human_numeric_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("-8T\n0.8M\n8981K\n21G\n909991M\n"); + } +} + +#[test] +fn test_month_default2() { + for month_sort_param in vec!["-M", "--month-sort"] { + let input = "JAn\nMAY\n000may\nJun\nFeb"; + new_ucmd!() + .arg(month_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("000may\nJAn\nFeb\nMAY\nJun\n"); + } +} + +#[test] +fn test_default_unsorted_ints2() { + let input = "9\n1909888\n000\n1\n2"; + new_ucmd!() + .pipe_in(input) + .succeeds() + .stdout_only("000\n1\n1909888\n2\n9\n"); +} + +#[test] +fn test_numeric_unique_ints2() { + for numeric_unique_sort_param in vec!["-nu"] { + let input = "9\n9\n8\n1\n"; + new_ucmd!() + .arg(numeric_unique_sort_param) + .pipe_in(input) + .succeeds() + .stdout_only("1\n8\n9\n"); + } +} + +#[test] +fn test_zero_terminated() { + test_helper("zero-terminated", "-z"); +} + #[test] fn test_multiple_files() { new_ucmd!() @@ -192,6 +347,15 @@ fn test_check() { .stdout_is(""); } +#[test] +fn test_check_silent() { + new_ucmd!() + .arg("-C") + .arg("check_fail.txt") + .fails() + .stdout_is(""); +} + fn test_helper(file_name: &str, args: &str) { new_ucmd!() .arg(args) diff --git a/tests/fixtures/sort/exponents-positive-general.expected b/tests/fixtures/sort/exponents-positive-general.expected new file mode 100644 index 000000000..3dbc92fe5 --- /dev/null +++ b/tests/fixtures/sort/exponents-positive-general.expected @@ -0,0 +1,12 @@ + + + + + + +10E +1000EDKLD +10000K78 ++100000 +100E6 +50e10 diff --git a/tests/fixtures/sort/exponents-positive-general.txt b/tests/fixtures/sort/exponents-positive-general.txt new file mode 100644 index 000000000..23ea52771 --- /dev/null +++ b/tests/fixtures/sort/exponents-positive-general.txt @@ -0,0 +1,12 @@ +10000K78 +10E + + +1000EDKLD + + +100E6 + +50e10 ++100000 + diff --git a/tests/fixtures/sort/exponents-positive-numeric.expected b/tests/fixtures/sort/exponents-positive-numeric.expected new file mode 100644 index 000000000..174088f63 --- /dev/null +++ b/tests/fixtures/sort/exponents-positive-numeric.expected @@ -0,0 +1,12 @@ + + + + + + ++100000 +10E +50e10 +100E6 +1000EDKLD +10000K78 diff --git a/tests/fixtures/sort/exponents-positive-numeric.txt b/tests/fixtures/sort/exponents-positive-numeric.txt new file mode 100644 index 000000000..23ea52771 --- /dev/null +++ b/tests/fixtures/sort/exponents-positive-numeric.txt @@ -0,0 +1,12 @@ +10000K78 +10E + + +1000EDKLD + + +100E6 + +50e10 ++100000 + diff --git a/tests/fixtures/sort/human-mixed-inputs-reverse.expected b/tests/fixtures/sort/human-mixed-inputs-reverse.expected new file mode 100644 index 000000000..463f44a2a --- /dev/null +++ b/tests/fixtures/sort/human-mixed-inputs-reverse.expected @@ -0,0 +1,37 @@ +.2T +2G +100M +7800900K +51887300- +1890777 +56908-90078 +6780.0009866 +6780.000986 +789----009999 90-0 90-0 +1 +0001 +apr +MAY +JUNNNN +JAN +AUG +APR +0000000 +00 + + + + + + + + + + + + + + + + +-1.4 diff --git a/tests/fixtures/sort/human-mixed-inputs-reverse.txt b/tests/fixtures/sort/human-mixed-inputs-reverse.txt new file mode 100644 index 000000000..ebef388b9 --- /dev/null +++ b/tests/fixtures/sort/human-mixed-inputs-reverse.txt @@ -0,0 +1,37 @@ +JAN + +0000000 + +00 + +0001 + +1 + +-1.4 + +JUNNNN +AUG + +apr + +APR + + +MAY +1890777 + +56908-90078 + +51887300- + +6780.0009866 + +789----009999 90-0 90-0 + +6780.000986 + +100M +7800900K +2G +.2T diff --git a/tests/fixtures/sort/human-mixed-inputs-stable.expected b/tests/fixtures/sort/human-mixed-inputs-stable.expected new file mode 100644 index 000000000..e1c85b8ce --- /dev/null +++ b/tests/fixtures/sort/human-mixed-inputs-stable.expected @@ -0,0 +1,37 @@ +-1.4 +JAN + +0000000 + +00 + + + + +JUNNNN +AUG + +apr + +APR + + +MAY + + + + + + +0001 +1 +789----009999 90-0 90-0 +6780.000986 +6780.0009866 +56908-90078 +1890777 +51887300- +7800900K +100M +2G +.2T diff --git a/tests/fixtures/sort/human-mixed-inputs-stable.txt b/tests/fixtures/sort/human-mixed-inputs-stable.txt new file mode 100644 index 000000000..ebef388b9 --- /dev/null +++ b/tests/fixtures/sort/human-mixed-inputs-stable.txt @@ -0,0 +1,37 @@ +JAN + +0000000 + +00 + +0001 + +1 + +-1.4 + +JUNNNN +AUG + +apr + +APR + + +MAY +1890777 + +56908-90078 + +51887300- + +6780.0009866 + +789----009999 90-0 90-0 + +6780.000986 + +100M +7800900K +2G +.2T diff --git a/tests/fixtures/sort/human-mixed-inputs-unique.expected b/tests/fixtures/sort/human-mixed-inputs-unique.expected new file mode 100644 index 000000000..50f53b6a0 --- /dev/null +++ b/tests/fixtures/sort/human-mixed-inputs-unique.expected @@ -0,0 +1,13 @@ +-1.4 +JAN +0001 +789----009999 90-0 90-0 +6780.000986 +6780.0009866 +56908-90078 +1890777 +51887300- +7800900K +100M +2G +.2T diff --git a/tests/fixtures/sort/human-mixed-inputs-unique.txt b/tests/fixtures/sort/human-mixed-inputs-unique.txt new file mode 100644 index 000000000..ebef388b9 --- /dev/null +++ b/tests/fixtures/sort/human-mixed-inputs-unique.txt @@ -0,0 +1,37 @@ +JAN + +0000000 + +00 + +0001 + +1 + +-1.4 + +JUNNNN +AUG + +apr + +APR + + +MAY +1890777 + +56908-90078 + +51887300- + +6780.0009866 + +789----009999 90-0 90-0 + +6780.000986 + +100M +7800900K +2G +.2T diff --git a/tests/fixtures/sort/human-mixed-inputs.expected b/tests/fixtures/sort/human-mixed-inputs.expected new file mode 100644 index 000000000..3f5692b7b --- /dev/null +++ b/tests/fixtures/sort/human-mixed-inputs.expected @@ -0,0 +1,37 @@ +-1.4 + + + + + + + + + + + + + + + + +00 +0000000 +APR +AUG +JAN +JUNNNN +MAY +apr +0001 +1 +789----009999 90-0 90-0 +6780.000986 +6780.0009866 +56908-90078 +1890777 +51887300- +7800900K +100M +2G +.2T diff --git a/tests/fixtures/sort/human-mixed-inputs.txt b/tests/fixtures/sort/human-mixed-inputs.txt new file mode 100644 index 000000000..ce5986d6e --- /dev/null +++ b/tests/fixtures/sort/human-mixed-inputs.txt @@ -0,0 +1,46 @@ +JAN + +0000000 + +00 + +0001 + +1 + +-1.4 + +JUNNNN +AUG + +apr + +APR + + +MAY +1890777 + +56908-90078 + +51887300- + +6780.0009866 + +789----009999 90-0 90-0 + +6780.000986 + +1M +10M +100M +1000M +10000M + +7800900K +780090K +78009K +7800K +780K +2G +.2T diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric.expected b/tests/fixtures/sort/mixed_floats_ints_chars_numeric.expected new file mode 100644 index 000000000..a781a36bb --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric.expected @@ -0,0 +1,30 @@ +-2028789030 +-896689 +-8.90880 +-1 +-.05 + + + + + + + + +000 +CARAvan +00000001 +1 +1.040000000 +1.444 +1.58590 +8.013 +45 +46.89 + 4567. + 37800 +576,446.88800000 +576,446.890 +4798908.340000000000 +4798908.45 +4798908.8909800 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric.txt b/tests/fixtures/sort/mixed_floats_ints_chars_numeric.txt new file mode 100644 index 000000000..a5813ea3a --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric.txt @@ -0,0 +1,30 @@ +576,446.890 +576,446.88800000 + + + 4567. +45 +46.89 +-1 +1 +00000001 +4798908.340000000000 +4798908.45 +4798908.8909800 + + + 37800 + +-2028789030 +-896689 +CARAvan + +-8.90880 +-.05 +1.444 +1.58590 +1.040000000 + +8.013 + +000 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse.expected b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse.expected new file mode 100644 index 000000000..6b024210b --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse.expected @@ -0,0 +1,30 @@ +4798908.8909800 +4798908.45 +4798908.340000000000 +576,446.890 +576,446.88800000 + 37800 + 4567. +46.89 +45 +8.013 +1.58590 +1.444 +1.040000000 +1 +00000001 +CARAvan +000 + + + + + + + + +-.05 +-1 +-8.90880 +-896689 +-2028789030 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse_stable.expected b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse_stable.expected new file mode 100644 index 000000000..cb1028f0e --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse_stable.expected @@ -0,0 +1,30 @@ +4798908.8909800 +4798908.45 +4798908.340000000000 +576,446.890 +576,446.88800000 + 37800 + 4567. +46.89 +45 +8.013 +1.58590 +1.444 +1.040000000 +1 +00000001 + + + + + +CARAvan + + + +000 +-.05 +-1 +-8.90880 +-896689 +-2028789030 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse_stable.txt b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse_stable.txt new file mode 100644 index 000000000..a5813ea3a --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_reverse_stable.txt @@ -0,0 +1,30 @@ +576,446.890 +576,446.88800000 + + + 4567. +45 +46.89 +-1 +1 +00000001 +4798908.340000000000 +4798908.45 +4798908.8909800 + + + 37800 + +-2028789030 +-896689 +CARAvan + +-8.90880 +-.05 +1.444 +1.58590 +1.040000000 + +8.013 + +000 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_stable.expected b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_stable.expected new file mode 100644 index 000000000..63a3e646d --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_stable.expected @@ -0,0 +1,30 @@ +-2028789030 +-896689 +-8.90880 +-1 +-.05 + + + + + +CARAvan + + + +000 +1 +00000001 +1.040000000 +1.444 +1.58590 +8.013 +45 +46.89 + 4567. + 37800 +576,446.88800000 +576,446.890 +4798908.340000000000 +4798908.45 +4798908.8909800 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_stable.txt b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_stable.txt new file mode 100644 index 000000000..a5813ea3a --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_stable.txt @@ -0,0 +1,30 @@ +576,446.890 +576,446.88800000 + + + 4567. +45 +46.89 +-1 +1 +00000001 +4798908.340000000000 +4798908.45 +4798908.8909800 + + + 37800 + +-2028789030 +-896689 +CARAvan + +-8.90880 +-.05 +1.444 +1.58590 +1.040000000 + +8.013 + +000 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique.expected b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique.expected new file mode 100644 index 000000000..cb27c6664 --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique.expected @@ -0,0 +1,20 @@ +-2028789030 +-896689 +-8.90880 +-1 +-.05 + +1 +1.040000000 +1.444 +1.58590 +8.013 +45 +46.89 + 4567. + 37800 +576,446.88800000 +576,446.890 +4798908.340000000000 +4798908.45 +4798908.8909800 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique.txt b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique.txt new file mode 100644 index 000000000..a5813ea3a --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique.txt @@ -0,0 +1,30 @@ +576,446.890 +576,446.88800000 + + + 4567. +45 +46.89 +-1 +1 +00000001 +4798908.340000000000 +4798908.45 +4798908.8909800 + + + 37800 + +-2028789030 +-896689 +CARAvan + +-8.90880 +-.05 +1.444 +1.58590 +1.040000000 + +8.013 + +000 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_reverse.expected b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_reverse.expected new file mode 100644 index 000000000..bbce16934 --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_reverse.expected @@ -0,0 +1,20 @@ +4798908.8909800 +4798908.45 +4798908.340000000000 +576,446.890 +576,446.88800000 + 37800 + 4567. +46.89 +45 +8.013 +1.58590 +1.444 +1.040000000 +1 + +-.05 +-1 +-8.90880 +-896689 +-2028789030 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_reverse.txt b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_reverse.txt new file mode 100644 index 000000000..a5813ea3a --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_reverse.txt @@ -0,0 +1,30 @@ +576,446.890 +576,446.88800000 + + + 4567. +45 +46.89 +-1 +1 +00000001 +4798908.340000000000 +4798908.45 +4798908.8909800 + + + 37800 + +-2028789030 +-896689 +CARAvan + +-8.90880 +-.05 +1.444 +1.58590 +1.040000000 + +8.013 + +000 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_stable.expected b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_stable.expected new file mode 100644 index 000000000..bbce16934 --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_stable.expected @@ -0,0 +1,20 @@ +4798908.8909800 +4798908.45 +4798908.340000000000 +576,446.890 +576,446.88800000 + 37800 + 4567. +46.89 +45 +8.013 +1.58590 +1.444 +1.040000000 +1 + +-.05 +-1 +-8.90880 +-896689 +-2028789030 diff --git a/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_stable.txt b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_stable.txt new file mode 100644 index 000000000..a5813ea3a --- /dev/null +++ b/tests/fixtures/sort/mixed_floats_ints_chars_numeric_unique_stable.txt @@ -0,0 +1,30 @@ +576,446.890 +576,446.88800000 + + + 4567. +45 +46.89 +-1 +1 +00000001 +4798908.340000000000 +4798908.45 +4798908.8909800 + + + 37800 + +-2028789030 +-896689 +CARAvan + +-8.90880 +-.05 +1.444 +1.58590 +1.040000000 + +8.013 + +000 diff --git a/tests/fixtures/sort/months-dedup.expected b/tests/fixtures/sort/months-dedup.expected new file mode 100644 index 000000000..dfb693492 --- /dev/null +++ b/tests/fixtures/sort/months-dedup.expected @@ -0,0 +1,6 @@ + +JAN +apr +MAY +JUNNNN +AUG diff --git a/tests/fixtures/sort/months-dedup.txt b/tests/fixtures/sort/months-dedup.txt new file mode 100644 index 000000000..ebef388b9 --- /dev/null +++ b/tests/fixtures/sort/months-dedup.txt @@ -0,0 +1,37 @@ +JAN + +0000000 + +00 + +0001 + +1 + +-1.4 + +JUNNNN +AUG + +apr + +APR + + +MAY +1890777 + +56908-90078 + +51887300- + +6780.0009866 + +789----009999 90-0 90-0 + +6780.000986 + +100M +7800900K +2G +.2T diff --git a/tests/fixtures/sort/numeric-floats-with-nan2.expected b/tests/fixtures/sort/numeric-floats-with-nan2.expected new file mode 100644 index 000000000..51c9985c3 --- /dev/null +++ b/tests/fixtures/sort/numeric-floats-with-nan2.expected @@ -0,0 +1,23 @@ +-8.90880 +-.05 + + + + + + + + + + + + + + +Karma +1 +1.0/0.0 +1.040000000 +1.2 +1.444 +1.58590 diff --git a/tests/fixtures/sort/numeric-floats-with-nan2.txt b/tests/fixtures/sort/numeric-floats-with-nan2.txt new file mode 100644 index 000000000..9b78741fe --- /dev/null +++ b/tests/fixtures/sort/numeric-floats-with-nan2.txt @@ -0,0 +1,23 @@ +Karma + +1.0/0.0 + + +-8.90880 + + +-.05 + + +1.040000000 + +1.444 + + +1.58590 + + +1 + +1.2 + diff --git a/tests/fixtures/sort/zero-terminated.expected b/tests/fixtures/sort/zero-terminated.expected new file mode 100644 index 000000000..4e53b304b --- /dev/null +++ b/tests/fixtures/sort/zero-terminated.expected @@ -0,0 +1 @@ +../..../../by-util../../common../../fixtures../../fixtures/cat../../fixtures/cksum../../fixtures/comm../../fixtures/cp../../fixtures/cp/dir_with_mount../../fixtures/cp/dir_with_mount/copy_me../../fixtures/cp/hello_dir../../fixtures/cp/hello_dir_with_file../../fixtures/csplit../../fixtures/cut../../fixtures/cut/sequences../../fixtures/dircolors../../fixtures/du../../fixtures/du/subdir../../fixtures/du/subdir/deeper../../fixtures/du/subdir/links../../fixtures/env../../fixtures/expand../../fixtures/fmt../../fixtures/fold../../fixtures/hashsum../../fixtures/head../../fixtures/join../../fixtures/mv../../fixtures/nl../../fixtures/numfmt../../fixtures/od../../fixtures/paste../../fixtures/ptx../../fixtures/shuf../../fixtures/sort../../fixtures/sum../../fixtures/tac../../fixtures/tail../../fixtures/tsort../../fixtures/unexpand../../fixtures/uniq../../fixtures/wc \ No newline at end of file diff --git a/tests/fixtures/sort/zero-terminated.txt b/tests/fixtures/sort/zero-terminated.txt new file mode 100644 index 000000000..5c547c851 --- /dev/null +++ b/tests/fixtures/sort/zero-terminated.txt @@ -0,0 +1 @@ +../../fixtures/paste../../fixtures/du../../fixtures/fold../../fixtures../../fixtures/cp/dir_with_mount/copy_me../../fixtures/sum../../fixtures/expand../../fixtures/mv../../fixtures/shuf../../fixtures/od../../fixtures/env../../fixtures/cut../../fixtures/cp/hello_dir../../fixtures/hashsum../../common../../fixtures/du/subdir/links../../fixtures/dircolors../../fixtures/nl../../fixtures/wc../../fixtures/cut/sequences../../fixtures/numfmt../../fixtures/comm../../fixtures/du/subdir../../fixtures/cp/hello_dir_with_file../../fixtures/ptx../../fixtures/cp/dir_with_mount../../fixtures/cat../../fixtures/cp../..../../fixtures/tail../../fixtures/du/subdir/deeper../../fixtures/head../../fixtures/join../../by-util../../fixtures/csplit../../fixtures/cksum../../fixtures/fmt../../fixtures/tsort../../fixtures/tac../../fixtures/unexpand../../fixtures/uniq../../fixtures/sort \ No newline at end of file From 9ae4928b7b4f43495921fe8ac6128ea226d20dbd Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 9 Apr 2021 10:14:41 +0200 Subject: [PATCH 132/132] Ignore a test (#2053) * Disable chksum: test_arg_overrides_stdin fails often with: ---- test_cksum::test_arg_overrides_stdin stdout ---- current_directory_resolved: touch: /tmp/.tmpv9hydc/a run: /target/x86_64-unknown-linux-gnu/debug/coreutils cksum a thread 'test_cksum::test_arg_overrides_stdin' panicked at 'Broken pipe (os error 32)', tests/common/util.rs:742:37 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace * rustfmt the recent change --- src/uu/sort/src/sort.rs | 6 ++---- src/uu/stdbuf/src/stdbuf.rs | 3 +-- tests/by-util/test_cksum.rs | 1 + 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 36e6ad71e..4e0e25d65 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -665,9 +665,7 @@ fn get_leading_gen(a: &str) -> String { for c in p_iter.to_owned() { let next_char_numeric = p_iter.peek().unwrap_or(&'\0').is_numeric(); // Only general numeric recognizes e notation and, see block below, the '+' sign - if (c.eq(&'e') && !next_char_numeric) - || (c.eq(&'E') && !next_char_numeric) - { + if (c.eq(&'e') && !next_char_numeric) || (c.eq(&'E') && !next_char_numeric) { r = a.split(c).next().unwrap_or("").to_owned(); break; // If positive sign and next char is not numeric, split at postive sign at keep trailing numbers @@ -813,7 +811,7 @@ fn human_numeric_convert(a: &str) -> f64 { 'E' => 1E18, 'Z' => 1E21, 'Y' => 1E24, - _ => 1f64, + _ => 1f64, }; num_part * suffix } diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index a61ba967b..67ed9a838 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -80,8 +80,7 @@ fn print_version() { fn print_usage(opts: &Options) { let brief = "Run COMMAND, with modified buffering operations for its standard streams\n \ Mandatory arguments to long options are mandatory for short options too."; - let explanation = - "If MODE is 'L' the corresponding stream will be line buffered.\n \ + let explanation = "If MODE is 'L' the corresponding stream will be line buffered.\n \ This option is invalid with standard input.\n\n \ If MODE is '0' the corresponding stream will be unbuffered.\n\n \ Otherwise MODE is a number which may be followed by one of the following:\n\n \ diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 8c8a551a0..8b41c782c 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -35,6 +35,7 @@ fn test_empty() { } #[test] +#[ignore] fn test_arg_overrides_stdin() { let (at, mut ucmd) = at_and_ucmd!(); let input = "foobarfoobar";