From a4b723233a26e51220d1c0287f4c31994b02f59b Mon Sep 17 00:00:00 2001 From: tilakpatidar Date: Sun, 6 Jan 2019 14:49:32 +0530 Subject: [PATCH] pr: add more tests for form feed and include page_width option W --- src/pr/pr.rs | 109 +++++++++++++------ tests/fixtures/pr/3a3f-0F | 3 +- tests/fixtures/pr/3f-0F | 52 +-------- tests/fixtures/pr/W20l24f-ll | 106 ++++++++++++++++++ tests/fixtures/pr/a3-0F | 6 +- tests/fixtures/pr/a3f-0F | 8 +- tests/fixtures/pr/l24-FF | 202 ++++++++++++++++++++++++++--------- tests/fixtures/pr/tFFt-ll | 56 ++++++++++ tests/test_pr.rs | 1 + 9 files changed, 400 insertions(+), 143 deletions(-) create mode 100644 tests/fixtures/pr/W20l24f-ll create mode 100644 tests/fixtures/pr/tFFt-ll diff --git a/src/pr/pr.rs b/src/pr/pr.rs index 2de3a663f..f463a9890 100644 --- a/src/pr/pr.rs +++ b/src/pr/pr.rs @@ -54,6 +54,7 @@ static SUPPRESS_PRINTING_ERROR: &str = "r"; static FORM_FEED_OPTION: &str = "F"; static FORM_FEED_OPTION_SMALL: &str = "f"; static COLUMN_WIDTH_OPTION: &str = "w"; +static PAGE_WIDTH_OPTION: &str = "W"; static ACROSS_OPTION: &str = "a"; static COLUMN_OPTION: &str = "column"; static COLUMN_SEPARATOR_OPTION: &str = "s"; @@ -62,6 +63,7 @@ static OFFSET_SPACES_OPTION: &str = "o"; static FILE_STDIN: &str = "-"; static READ_BUFFER_SIZE: usize = 1024 * 64; static DEFAULT_COLUMN_WIDTH: usize = 72; +static DEFAULT_COLUMN_WIDTH_WITH_S_OPTION: usize = 512; static DEFAULT_COLUMN_SEPARATOR: &char = &TAB; static BLANK_STRING: &str = ""; static FF: u8 = 0x0C as u8; @@ -84,6 +86,7 @@ struct OutputOptions { merge_files_print: Option, offset_spaces: usize, form_feed_used: bool, + page_width: Option, } struct FileLine { @@ -247,9 +250,9 @@ pub fn uumain(args: Vec) -> i32 { opts.opt( PAGE_LENGTH_OPTION, "length", - "Override the 66-line default and reset the page length to lines. If lines is not greater than the sum of both + "Override the 66-line default (default number of lines of text 56, and with -F 63) and reset the page length to lines. If lines is not greater than the sum of both the header and trailer depths (in lines), the pr utility shall suppress both the header and trailer, as if the - -t option were in effect.", + -t option were in effect. ", "lines", HasArg::Yes, Occur::Optional, @@ -306,6 +309,17 @@ pub fn uumain(args: Vec) -> i32 { Occur::Optional, ); + opts.opt( + PAGE_WIDTH_OPTION, + "page-width", + "set page width to PAGE_WIDTH (72) characters always, + truncate lines, except -J option is set, no interference + with -S or -s", + "[width]", + HasArg::Yes, + Occur::Optional, + ); + opts.opt( ACROSS_OPTION, "across", @@ -498,6 +512,9 @@ fn build_options( paths: &Vec, free_args: String, ) -> Result { + let form_feed_used = + matches.opt_present(FORM_FEED_OPTION) || matches.opt_present(FORM_FEED_OPTION_SMALL); + let invalid_pages_map = |i: String| { let unparsed_value: String = matches.opt_str(PAGE_RANGE_OPTION).unwrap(); i.parse::().map_err(|_e| { @@ -657,8 +674,10 @@ fn build_options( ))); } + let default_lines_per_page = if form_feed_used { 63 } else { LINES_PER_PAGE }; + let page_length: usize = - parse_usize(matches, PAGE_LENGTH_OPTION).unwrap_or(Ok(LINES_PER_PAGE))?; + parse_usize(matches, PAGE_LENGTH_OPTION).unwrap_or(Ok(default_lines_per_page))?; let page_length_le_ht: bool = page_length < (HEADER_LINES_PER_PAGE + TRAILER_LINES_PER_PAGE); @@ -678,15 +697,27 @@ fn build_options( NEW_LINE.to_string() }; - let column_width: usize = - parse_usize(matches, COLUMN_WIDTH_OPTION).unwrap_or(Ok(DEFAULT_COLUMN_WIDTH))?; - let across_mode: bool = matches.opt_present(ACROSS_OPTION); let column_separator: String = matches .opt_str(COLUMN_SEPARATOR_OPTION) .unwrap_or(DEFAULT_COLUMN_SEPARATOR.to_string()); + let default_column_width = if matches.opt_present(COLUMN_WIDTH_OPTION) + && matches.opt_present(COLUMN_SEPARATOR_OPTION) + { + DEFAULT_COLUMN_WIDTH_WITH_S_OPTION + } else { + DEFAULT_COLUMN_WIDTH + }; + + let column_width: usize = + parse_usize(matches, COLUMN_WIDTH_OPTION).unwrap_or(Ok(default_column_width))?; + let page_width: Option = match parse_usize(matches, PAGE_WIDTH_OPTION) { + Some(res) => Some(res?), + None => None, + }; + let re_col = Regex::new(r"\s*-(\d+)\s*").unwrap(); let start_column_option: Option = match re_col.captures(&free_args).map(|i| { @@ -717,8 +748,6 @@ fn build_options( }; let offset_spaces: usize = parse_usize(matches, OFFSET_SPACES_OPTION).unwrap_or(Ok(0))?; - let form_feed_used = - matches.opt_present(FORM_FEED_OPTION) || matches.opt_present(FORM_FEED_OPTION_SMALL); Ok(OutputOptions { number: numbering_options, header, @@ -736,6 +765,7 @@ fn build_options( merge_files_print, offset_spaces, form_feed_used, + page_width, }) } @@ -834,11 +864,12 @@ fn pr(path: &String, options: &OutputOptions) -> Result { if file_line.line_content.is_err() { return Err(file_line.line_content.unwrap_err().into()); } - feed_line_present = is_form_feed_used; + let form_feeds_after: usize = file_line.form_feeds_after; + page_lines.push(file_line); - if page_lines.len() == lines_needed_per_page || file_line.form_feeds_after > 0 { - if file_line.form_feeds_after > 1 { + if page_lines.len() == lines_needed_per_page || form_feeds_after > 0 { + if form_feeds_after > 1 { print_page( &page_lines, options, @@ -849,15 +880,20 @@ fn pr(path: &String, options: &OutputOptions) -> Result { )?; page_lines.clear(); page_number += 1; - print_page( - &page_lines, - options, - &page_number, - &start_page, - &last_page, - feed_line_present, - )?; - page_number += 1; + + // insert empty pages + let empty_pages_required = form_feeds_after - 1; + for _i in 0..empty_pages_required { + print_page( + &page_lines, + options, + &page_number, + &start_page, + &last_page, + feed_line_present, + )?; + page_number += 1; + } } else { print_page( &page_lines, @@ -871,18 +907,17 @@ fn pr(path: &String, options: &OutputOptions) -> Result { } page_lines.clear(); } - if file_line.form_feeds_after == 0 { - page_lines.push(file_line); - } } - print_page( - &page_lines, - options, - &page_number, - &start_page, - &last_page, - feed_line_present, - )?; + if page_lines.len() != 0 { + print_page( + &page_lines, + options, + &page_number, + &start_page, + &last_page, + feed_line_present, + )?; + } return Ok(0); } @@ -1131,6 +1166,8 @@ fn write_columns( .unwrap_or(None), ); + let page_width: Option = options.page_width; + let across_mode = options .column_mode_options .as_ref() @@ -1178,6 +1215,7 @@ fn write_columns( is_number_mode, &options.merge_files_print, &i, + page_width ) ); out.write(trimmed_line.as_bytes())?; @@ -1204,6 +1242,7 @@ fn get_line_for_printing( is_number_mode: bool, merge_files_print: &Option, index: &usize, + page_width: Option, ) -> String { let should_show_line_number_merge_file = merge_files_print.is_none() || index == &usize::min_value(); @@ -1224,7 +1263,13 @@ fn get_line_for_printing( let display_length = complete_line.len() + (tab_count * 7); // TODO Adjust the width according to -n option // TODO actual len of the string vs display len of string because of tabs - col_width + + let width: Option = match col_width { + Some(x) => Some(x), + None => page_width, + }; + + width .map(|i| { let min_width = (i - (columns - 1)) / columns; if display_length < min_width { diff --git a/tests/fixtures/pr/3a3f-0F b/tests/fixtures/pr/3a3f-0F index a2535574f..6097374c7 100644 --- a/tests/fixtures/pr/3a3f-0F +++ b/tests/fixtures/pr/3a3f-0F @@ -12,7 +12,8 @@ 8 9 3456789 ab 20 DEFGHI 123 1 2 3 4 5 6 -27 no truncation before 28 no trunc +27 no truncation before 28 no trunc + {last_modified_time} {file_name} Page 5 diff --git a/tests/fixtures/pr/3f-0F b/tests/fixtures/pr/3f-0F index 06e47aa66..d32c1f8f6 100644 --- a/tests/fixtures/pr/3f-0F +++ b/tests/fixtures/pr/3f-0F @@ -22,6 +22,7 @@ 6 12345678 27 no truncation before FF; (r_l-test): 28 no trunc + {last_modified_time} {file_name} Page 5 @@ -32,55 +33,4 @@ 1 12345678 2 3456789 abcdefghi 3 12345678 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/fixtures/pr/W20l24f-ll b/tests/fixtures/pr/W20l24f-ll new file mode 100644 index 000000000..d95c04c37 --- /dev/null +++ b/tests/fixtures/pr/W20l24f-ll @@ -0,0 +1,106 @@ + + +{last_modified_time} {file_name} Page 1 + + +1<<< -Test: FF's in +2<<< -b -3 / -a -3 +3<<< >>> +4<<< 123456789 1234 + +6<<< -Arangements: +7<<< \f\f\n; text\f +8<<< f\f\n; \f\n\f\ +9<<< >>> +10<<< >>> +1<<< >>> +2<<< >>> +3<<< truncation bef +14<<< 123456789 123 + + +{last_modified_time} {file_name} Page 2 + + + + +{last_modified_time} {file_name} Page 3 + + +15<<< xyzxyzxyz XYZ +16<<< 123456789 xyz +7<<< >>> +8<<< >>> +9<<< >>> +20<<< >>> +1<<< >>> + + +4<<< >>> +5<<< >>> +6<<< >>> +27<<< truncation be +28<<< trunc + + +{last_modified_time} {file_name} Page 4 + + + + +{last_modified_time} {file_name} Page 5 + + +29<<>> +2<<< abcdefghi >>> +3<<< >>> +4<<< >>> +5<<< >>> +6<<< >>> +7<<< >>> +8<<< >>> +9<<< abcdefghi >>> +40<<< 123456789 >> +41<<< XYZXYZXYZ abc +42<<< 123456789 abc + + +{last_modified_time} {file_name} Page 6 + + + + +{last_modified_time} {file_name} Page 7 + + + + +{last_modified_time} {file_name} Page 8 + + +43<<< xyzxyzxyz XYZ +44<<< 123456789 xyz +5<<< >>> +6<<< >>> +7<<< >>> +8<<< >>> +9<<< >>> +50<<< >>> +1<<< >>> +2<<< >>> +3<<< >>> +4<<< >>> +55<<< XYZXYZXYZ abc +56<<< 123456789 abc + + +{last_modified_time} {file_name} Page 9 + + +57<<< xyzxyzxyz XYZ +58<<< 123456789 xyz +9<<< >>> +60<<< 123456789 >> + \ No newline at end of file diff --git a/tests/fixtures/pr/a3-0F b/tests/fixtures/pr/a3-0F index 8f0b06290..58aeb07c2 100644 --- a/tests/fixtures/pr/a3-0F +++ b/tests/fixtures/pr/a3-0F @@ -3,7 +3,7 @@ {last_modified_time} {file_name} Page 1 - + @@ -73,7 +73,7 @@ 4 3456789 123456789 123 5 3 Columns downwards 6 FF-Arangements: Emp 7 \ftext; \f\ntext; 8 \f\ftext; \f\f\ntex 9 3456789 123456789 123 10 zzzzzzzzzzzzzzzzzzz 1 2 -3 line truncation befor 14 456789 123456789 123 +3 line truncation befor 14 456789 123456789 123 @@ -205,7 +205,7 @@ 8 9 3456789 ab 20 DEFGHI 123 1 2 3 4 5 6 -27 no truncation before 28 no trunc +27 no truncation before 28 no trunc diff --git a/tests/fixtures/pr/a3f-0F b/tests/fixtures/pr/a3f-0F index 9da2bb439..24939c004 100644 --- a/tests/fixtures/pr/a3f-0F +++ b/tests/fixtures/pr/a3f-0F @@ -3,7 +3,7 @@ {last_modified_time} {file_name} Page 1 - + {last_modified_time} {file_name} Page 2 @@ -12,7 +12,8 @@ 4 3456789 123456789 123 5 3 Columns downwards 6 FF-Arangements: Emp 7 \ftext; \f\ntext; 8 \f\ftext; \f\f\ntex 9 3456789 123456789 123 10 zzzzzzzzzzzzzzzzzzz 1 2 -3 line truncation befor 14 456789 123456789 123 +3 line truncation befor 14 456789 123456789 123 + {last_modified_time} {file_name} Page 3 @@ -26,7 +27,8 @@ 8 9 3456789 ab 20 DEFGHI 123 1 2 3 4 5 6 -27 no truncation before 28 no trunc +27 no truncation before 28 no trunc + {last_modified_time} {file_name} Page 5 diff --git a/tests/fixtures/pr/l24-FF b/tests/fixtures/pr/l24-FF index 497d2f33a..de219b2fb 100644 --- a/tests/fixtures/pr/l24-FF +++ b/tests/fixtures/pr/l24-FF @@ -51,6 +51,30 @@ {last_modified_time} {file_name} Page 3 + + + + + + + + + + + + + + + + + + + + + +{last_modified_time} {file_name} Page 4 + + 15 xyzxyzxyz XYZXYZXYZ abcabcab 16 456789 123456789 xyzxyzxyz XYZXYZXYZ 7 12345678 @@ -69,50 +93,26 @@ - - - -{last_modified_time} {file_name} Page 4 - - - - - - - - - - - - - - - - - - - - {last_modified_time} {file_name} Page 5 -29 xyzxyzxyz XYZXYZXYZ abcabcab -30 456789 123456789 xyzxyzxyz XYZXYZXYZ -1 12345678 -2 3456789 abcdefghi -3 12345678 -4 12345678 -5 12345678 -6 12345678 -7 12345678 -8 12345678 -9 3456789 abcdefghi -40 DEFGHI 123456789 -41 yzxyzxyz XYZXYZXYZ abcabcab -42 456789 123456789 abcdefghi ABCDEDFHI + + + + + + + + + + + + + + @@ -147,20 +147,20 @@ {last_modified_time} {file_name} Page 7 - - - - - - - - - - - - - - +29 xyzxyzxyz XYZXYZXYZ abcabcab +30 456789 123456789 xyzxyzxyz XYZXYZXYZ +1 12345678 +2 3456789 abcdefghi +3 12345678 +4 12345678 +5 12345678 +6 12345678 +7 12345678 +8 12345678 +9 3456789 abcdefghi +40 DEFGHI 123456789 +41 yzxyzxyz XYZXYZXYZ abcabcab +42 456789 123456789 abcdefghi ABCDEDFHI @@ -171,6 +171,78 @@ {last_modified_time} {file_name} Page 8 + + + + + + + + + + + + + + + + + + + + + +{last_modified_time} {file_name} Page 9 + + + + + + + + + + + + + + + + + + + + + + + +{last_modified_time} {file_name} Page 10 + + + + + + + + + + + + + + + + + + + + + + + +{last_modified_time} {file_name} Page 11 + + 43 xyzxyzxyz XYZXYZXYZ abcabcab 44 456789 123456789 xyzxyzxyz XYZXYZXYZ 5 12345678 @@ -192,7 +264,31 @@ -{last_modified_time} {file_name} Page 9 +{last_modified_time} {file_name} Page 12 + + + + + + + + + + + + + + + + + + + + + + + +{last_modified_time} {file_name} Page 13 57 xyzxyzxyz XYZXYZXYZ abcabcab diff --git a/tests/fixtures/pr/tFFt-ll b/tests/fixtures/pr/tFFt-ll new file mode 100644 index 000000000..39eca655f --- /dev/null +++ b/tests/fixtures/pr/tFFt-ll @@ -0,0 +1,56 @@ +1<<< -Test: FF's in Text >>> +2<<< -b -3 / -a -3 / ... >>> +3<<< >>> +4<<< 123456789 123456789 123456789 123456789 123456789 123456789 123456789 >>> + +6<<< -Arangements: One Empty Page >>> +7<<< \f\f\n; text\f\n\ftext; \f\ftext; >>> +8<<< f\f\n; \f\n\f\n; >>> +9<<< >>> +10<<< >>> +1<<< >>> +2<<< >>> +3<<< truncation before FF; r_r_o_l-test: >>> +14<<< 123456789 123456789 123456789 >>> 15<<< xyzxyzxyz XYZXYZXYZ abcabcab >>> +16<<< 123456789 xyzxyzxyz XYZXYZXYZ >>> +7<<< >>> +8<<< >>> +9<<< >>> +20<<< >>> +1<<< >>> + + +4<<< >>> +5<<< >>> +6<<< >>> +27<<< truncation before FF; (r_l-test): >>> +28<<< trunc 29<<>> +30<<< 123456789 xyzxyzxyz XYZXYZXYZ >>> +1<<< >>> +2<<< abcdefghi >>> +3<<< >>> +4<<< >>> +5<<< >>> +6<<< >>> +7<<< >>> +8<<< >>> +9<<< abcdefghi >>> +40<<< 123456789 >>> +41<<< XYZXYZXYZ abcabcab >>> +42<<< 123456789 abcdefghi ABCDEDFHI >>> 43<<< xyzxyzxyz XYZXYZXYZ abcabcab >>> +44<<< 123456789 xyzxyzxyz XYZXYZXYZ >>> +5<<< >>> +6<<< >>> +7<<< >>> +8<<< >>> +9<<< >>> +50<<< >>> +1<<< >>> +2<<< >>> +3<<< >>> +4<<< >>> +55<<< XYZXYZXYZ abcabcab >>> +56<<< 123456789 abcdefghi ABCDEDFHI >>> 57<<< xyzxyzxyz XYZXYZXYZ abcabcab >>> +58<<< 123456789 xyzxyzxyz XYZXYZXYZ >>> +9<<< >>> +60<<< 123456789 >>> diff --git a/tests/test_pr.rs b/tests/test_pr.rs index 863486878..1026b77a9 100644 --- a/tests/test_pr.rs +++ b/tests/test_pr.rs @@ -492,6 +492,7 @@ fn test_with_pr_core_utils_tests() { ("-a -3 -f", vec!["0Fnt"], vec!["a3f-0F"], 0), ("+3 -a -3 -f", vec!["0Ft"], vec!["3a3f-0F"], 0), ("-l 24", vec!["FnFn"], vec!["l24-FF"], 0), + ("-W 20 -l24 -f", vec!["tFFt-ll"], vec!["W20l24f-ll"], 0), ]; for test_case in test_cases {