1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 03:27:44 +00:00

pr: add more tests for form feed and include page_width option W

This commit is contained in:
tilakpatidar 2019-01-06 14:49:32 +05:30 committed by Max Semenik
parent 4bf5b86cde
commit a4b723233a
9 changed files with 400 additions and 143 deletions

View file

@ -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<usize>,
offset_spaces: usize,
form_feed_used: bool,
page_width: Option<usize>,
}
struct FileLine {
@ -247,7 +250,7 @@ pub fn uumain(args: Vec<String>) -> 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. ",
"lines",
@ -306,6 +309,17 @@ pub fn uumain(args: Vec<String>) -> 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<String>,
free_args: String,
) -> Result<OutputOptions, PrError> {
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::<usize>().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<usize> = 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<usize> = 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<i32, PrError> {
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,6 +880,10 @@ fn pr(path: &String, options: &OutputOptions) -> Result<i32, PrError> {
)?;
page_lines.clear();
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,
@ -858,6 +893,7 @@ fn pr(path: &String, options: &OutputOptions) -> Result<i32, PrError> {
feed_line_present,
)?;
page_number += 1;
}
} else {
print_page(
&page_lines,
@ -871,10 +907,8 @@ fn pr(path: &String, options: &OutputOptions) -> Result<i32, PrError> {
}
page_lines.clear();
}
if file_line.form_feeds_after == 0 {
page_lines.push(file_line);
}
}
if page_lines.len() != 0 {
print_page(
&page_lines,
options,
@ -883,6 +917,7 @@ fn pr(path: &String, options: &OutputOptions) -> Result<i32, PrError> {
&last_page,
feed_line_present,
)?;
}
return Ok(0);
}
@ -1131,6 +1166,8 @@ fn write_columns(
.unwrap_or(None),
);
let page_width: Option<usize> = 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<usize>,
index: &usize,
page_width: Option<usize>,
) -> 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<usize> = 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 {

View file

@ -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

View file

@ -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

106
tests/fixtures/pr/W20l24f-ll vendored Normal file
View file

@ -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<<<xyzxyzxyz XYZXY
30<<< 123456789 xyz
1<<< >>>
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 >>

View file

@ -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

View file

@ -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

56
tests/fixtures/pr/tFFt-ll vendored Normal file
View file

@ -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<<<xyzxyzxyz XYZXYZXYZ abcabcab >>>
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 >>>

View file

@ -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 {