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

pr: fix form feed

pr: fix form feed

pr: Rustfmt

pr: add test for ff and -l option
This commit is contained in:
tilakpatidar 2019-01-04 22:34:29 +05:30 committed by Max Semenik
parent 8f9b322897
commit 3be5dc6923
12 changed files with 1573 additions and 57 deletions

View file

@ -27,6 +27,7 @@ use regex::Regex;
use std::convert::From; use std::convert::From;
use std::fs::{metadata, File, Metadata}; use std::fs::{metadata, File, Metadata};
use std::io::{stderr, stdin, stdout, BufRead, BufReader, Lines, Read, Stdin, Stdout, Write}; use std::io::{stderr, stdin, stdout, BufRead, BufReader, Lines, Read, Stdin, Stdout, Write};
use std::iter::FlatMap;
use std::iter::{Enumerate, Map, SkipWhile, TakeWhile}; use std::iter::{Enumerate, Map, SkipWhile, TakeWhile};
use std::num::ParseIntError; use std::num::ParseIntError;
#[cfg(unix)] #[cfg(unix)]
@ -51,6 +52,7 @@ static NO_HEADER_TRAILER_OPTION: &str = "t";
static PAGE_LENGTH_OPTION: &str = "l"; static PAGE_LENGTH_OPTION: &str = "l";
static SUPPRESS_PRINTING_ERROR: &str = "r"; static SUPPRESS_PRINTING_ERROR: &str = "r";
static FORM_FEED_OPTION: &str = "F"; static FORM_FEED_OPTION: &str = "F";
static FORM_FEED_OPTION_SMALL: &str = "f";
static COLUMN_WIDTH_OPTION: &str = "w"; static COLUMN_WIDTH_OPTION: &str = "w";
static ACROSS_OPTION: &str = "a"; static ACROSS_OPTION: &str = "a";
static COLUMN_OPTION: &str = "column"; static COLUMN_OPTION: &str = "column";
@ -81,6 +83,7 @@ struct OutputOptions {
column_mode_options: Option<ColumnModeOptions>, column_mode_options: Option<ColumnModeOptions>,
merge_files_print: Option<usize>, merge_files_print: Option<usize>,
offset_spaces: usize, offset_spaces: usize,
form_feed_used: bool,
} }
struct FileLine { struct FileLine {
@ -89,6 +92,7 @@ struct FileLine {
page_number: usize, page_number: usize,
group_key: usize, group_key: usize,
line_content: Result<String, IOError>, line_content: Result<String, IOError>,
form_feeds_after: usize,
} }
impl AsRef<FileLine> for FileLine { impl AsRef<FileLine> for FileLine {
@ -127,6 +131,19 @@ impl Default for NumberingMode {
} }
} }
impl Default for FileLine {
fn default() -> FileLine {
FileLine {
file_id: 0,
line_number: 0,
page_number: 0,
group_key: 0,
line_content: Ok(BLANK_STRING.to_string()),
form_feeds_after: 0,
}
}
}
impl From<IOError> for PrError { impl From<IOError> for PrError {
fn from(err: IOError) -> Self { fn from(err: IOError) -> Self {
PrError::EncounteredErrors(err.to_string()) PrError::EncounteredErrors(err.to_string())
@ -255,6 +272,15 @@ pub fn uumain(args: Vec<String>) -> i32 {
HasArg::No, HasArg::No,
Occur::Optional, Occur::Optional,
); );
opts.opt(
FORM_FEED_OPTION_SMALL,
"form-feed",
"Same as -F but pause before beginning the first page if standard output is a
terminal.",
"",
HasArg::No,
Occur::Optional,
);
opts.opt( opts.opt(
"", "",
@ -572,7 +598,6 @@ fn build_options(
}; };
// +page option is less priority than --pages // +page option is less priority than --pages
let flags = &matches.free.join(" ");
let re = Regex::new(r"\s*\+(\d+)\s*").unwrap(); let re = Regex::new(r"\s*\+(\d+)\s*").unwrap();
let start_page_in_plus_option: usize = match re.captures(&free_args).map(|i| { let start_page_in_plus_option: usize = match re.captures(&free_args).map(|i| {
let unparsed_num = i.get(1).unwrap().as_str().trim(); let unparsed_num = i.get(1).unwrap().as_str().trim();
@ -677,7 +702,8 @@ fn build_options(
}; };
let offset_spaces: usize = parse_usize(matches, OFFSET_SPACES_OPTION).unwrap_or(Ok(0))?; 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 { Ok(OutputOptions {
number: numbering_options, number: numbering_options,
header, header,
@ -694,6 +720,7 @@ fn build_options(
column_mode_options, column_mode_options,
merge_files_print, merge_files_print,
offset_spaces, offset_spaces,
form_feed_used,
}) })
} }
@ -730,53 +757,117 @@ fn pr(path: &String, options: &OutputOptions) -> Result<i32, PrError> {
let start_line_number: usize = get_start_line_number(options); let start_line_number: usize = get_start_line_number(options);
let last_page: Option<&usize> = options.end_page.as_ref(); let last_page: Option<&usize> = options.end_page.as_ref();
let lines_needed_per_page: usize = lines_to_read_for_page(options); let lines_needed_per_page: usize = lines_to_read_for_page(options);
let start_line_index_of_start_page = (start_page - 1) * lines_needed_per_page; let is_form_feed_used = options.form_feed_used;
let file_line_groups: GroupBy< let lines: Map<Map<Enumerate<FlatMap<Map<Lines<BufReader<Box<Read>>>, _>, _, _>>, _>, _> =
usize, BufReader::with_capacity(READ_BUFFER_SIZE, open(path)?)
Map<TakeWhile<SkipWhile<Map<Enumerate<Lines<BufReader<Box<Read>>>>, _>, _>, _>, _>, .lines()
_, .map(|file_content: Result<String, IOError>| {
> = BufReader::with_capacity(READ_BUFFER_SIZE, open(path)?) file_content
.lines() .map(|content| {
.enumerate() let mut lines: Vec<FileLine> = Vec::new();
.map(|i: (usize, Result<String, IOError>)| FileLine { let mut f_occurred: usize = 0;
file_id: 0, let mut chunk: Vec<u8> = Vec::new();
line_number: i.0, for byte in content.as_bytes() {
line_content: i.1, if byte == &FF {
page_number: 0, f_occurred += 1;
group_key: 0, } else {
}) if f_occurred != 0 {
.skip_while(|file_line: &FileLine| { // First time byte occurred in the scan
// Skip the initial lines if not in page range lines.push(FileLine {
file_line.line_number < (start_line_index_of_start_page) line_content: Ok(String::from_utf8(chunk.clone()).unwrap()),
}) form_feeds_after: f_occurred,
.take_while(|file_line: &FileLine| { ..FileLine::default()
// Only read the file until provided last page reached });
last_page chunk.clear();
.map(|lp| file_line.line_number < ((*lp) * lines_needed_per_page)) }
.unwrap_or(true) chunk.push(*byte);
}) f_occurred = 0;
.map(|file_line: FileLine| { }
let page_number = }
((file_line.line_number + 1) as f64 / lines_needed_per_page as f64).ceil() as usize;
FileLine {
line_number: file_line.line_number + start_line_number,
page_number,
group_key: page_number,
..file_line
}
}) // get display line number with line content
.group_by(|file_line: &FileLine| file_line.group_key);
for (page_number, file_line_group) in file_line_groups.into_iter() { // First time byte occurred in the scan
let mut lines: Vec<FileLine> = Vec::new(); lines.push(FileLine {
for file_line in file_line_group { line_content: Ok(String::from_utf8(chunk.clone()).unwrap()),
if file_line.line_content.is_err() { form_feeds_after: f_occurred,
return Err(file_line.line_content.unwrap_err().into()); ..FileLine::default()
} });
lines.push(file_line);
lines
})
.unwrap_or_else(|e| {
vec![FileLine {
line_content: Err(e),
..FileLine::default()
}]
})
})
.flat_map(|i| i)
.enumerate()
.map(|i: (usize, FileLine)| FileLine {
line_number: i.0,
..i.1
})
.map(|file_line: FileLine| FileLine {
line_number: file_line.line_number + start_line_number,
..file_line
}); // get display line number with line content
let mut page_number = 1;
let mut page_lines: Vec<FileLine> = Vec::new();
let mut feed_line_present = false;
for file_line in lines {
if file_line.line_content.is_err() {
return Err(file_line.line_content.unwrap_err().into());
}
feed_line_present = is_form_feed_used;
if page_lines.len() == lines_needed_per_page || file_line.form_feeds_after > 0 {
if file_line.form_feeds_after > 1 {
print_page(
&page_lines,
options,
&page_number,
&start_page,
&last_page,
feed_line_present,
)?;
page_lines.clear();
page_number += 1;
print_page(
&page_lines,
options,
&page_number,
&start_page,
&last_page,
feed_line_present,
)?;
page_number += 1;
} else {
print_page(
&page_lines,
options,
&page_number,
&start_page,
&last_page,
feed_line_present,
)?;
page_number += 1;
}
page_lines.clear();
}
if file_line.form_feeds_after == 0 {
page_lines.push(file_line);
} }
print_page(&lines, options, &page_number)?;
} }
print_page(
&page_lines,
options,
&page_number,
&start_page,
&last_page,
feed_line_present,
)?;
return Ok(0); return Ok(0);
} }
@ -814,8 +905,7 @@ fn mpr(paths: &Vec<String>, options: &OutputOptions) -> Result<i32, PrError> {
file_id: indexed_path.0, file_id: indexed_path.0,
line_number: i.0, line_number: i.0,
line_content: i.1, line_content: i.1,
page_number: 0, ..FileLine::default()
group_key: 0,
}) })
.skip_while(move |file_line: &FileLine| { .skip_while(move |file_line: &FileLine| {
// Skip the initial lines if not in page range // Skip the initial lines if not in page range
@ -859,7 +949,14 @@ fn mpr(paths: &Vec<String>, options: &OutputOptions) -> Result<i32, PrError> {
let new_page_number = file_line.page_number; let new_page_number = file_line.page_number;
if page_counter != new_page_number { if page_counter != new_page_number {
fill_missing_lines(&mut lines, lines_needed_per_page, &nfiles, page_counter); fill_missing_lines(&mut lines, lines_needed_per_page, &nfiles, page_counter);
print_page(&lines, options, &page_counter)?; print_page(
&lines,
options,
&page_counter,
&start_page,
&last_page,
false,
)?;
lines = Vec::new(); lines = Vec::new();
} }
lines.push(file_line); lines.push(file_line);
@ -868,7 +965,14 @@ fn mpr(paths: &Vec<String>, options: &OutputOptions) -> Result<i32, PrError> {
} }
fill_missing_lines(&mut lines, lines_needed_per_page, &nfiles, page_counter); fill_missing_lines(&mut lines, lines_needed_per_page, &nfiles, page_counter);
print_page(&lines, options, &page_counter)?; print_page(
&lines,
options,
&page_counter,
&start_page,
&last_page,
false,
)?;
return Ok(0); return Ok(0);
} }
@ -904,7 +1008,7 @@ fn fill_missing_lines(
line_number: line_number_counter, line_number: line_number_counter,
line_content: Ok("".to_string()), line_content: Ok("".to_string()),
page_number, page_number,
group_key: 0, ..FileLine::default()
}, },
); );
line_number_counter += 1; line_number_counter += 1;
@ -918,7 +1022,7 @@ fn fill_missing_lines(
line_number: line_number_counter, line_number: line_number_counter,
line_content: Ok("".to_string()), line_content: Ok("".to_string()),
page_number, page_number,
group_key: 0, ..FileLine::default()
}, },
); );
} else { } else {
@ -933,7 +1037,13 @@ fn print_page(
lines: &Vec<FileLine>, lines: &Vec<FileLine>,
options: &OutputOptions, options: &OutputOptions,
page: &usize, page: &usize,
start_page: &usize,
last_page: &Option<&usize>,
feed_line_present: bool,
) -> Result<usize, IOError> { ) -> Result<usize, IOError> {
if (last_page.is_some() && page > last_page.unwrap()) || page < start_page {
return Ok(0);
}
let page_separator = options.page_separator_char.as_bytes(); let page_separator = options.page_separator_char.as_bytes();
let header: Vec<String> = header_content(options, page); let header: Vec<String> = header_content(options, page);
let trailer_content: Vec<String> = trailer_content(options); let trailer_content: Vec<String> = trailer_content(options);
@ -946,8 +1056,7 @@ fn print_page(
out.write(x.as_bytes())?; out.write(x.as_bytes())?;
out.write(line_separator)?; out.write(line_separator)?;
} }
let lines_written = write_columns(lines, options, out, feed_line_present)?;
let lines_written = write_columns(lines, options, out)?;
for index in 0..trailer_content.len() { for index in 0..trailer_content.len() {
let x: &String = trailer_content.get(index).unwrap(); let x: &String = trailer_content.get(index).unwrap();
@ -965,6 +1074,7 @@ fn write_columns(
lines: &Vec<FileLine>, lines: &Vec<FileLine>,
options: &OutputOptions, options: &OutputOptions,
out: &mut Stdout, out: &mut Stdout,
feed_line_present: bool,
) -> Result<usize, IOError> { ) -> Result<usize, IOError> {
let line_separator = options.content_line_separator.as_bytes(); let line_separator = options.content_line_separator.as_bytes();
let content_lines_per_page = if options.double_space { let content_lines_per_page = if options.double_space {
@ -1031,12 +1141,13 @@ fn write_columns(
}; };
let spaces = " ".repeat(*offset_spaces); let spaces = " ".repeat(*offset_spaces);
let mut not_found_break = false;
for fetch_index in fetch_indexes { for fetch_index in fetch_indexes {
let indexes = fetch_index.len(); let indexes = fetch_index.len();
for i in 0..indexes { for i in 0..indexes {
let index: usize = fetch_index[i]; let index: usize = fetch_index[i];
if lines.get(index).is_none() { if lines.get(index).is_none() {
not_found_break = true;
break; break;
} }
let file_line: &FileLine = lines.get(index).unwrap(); let file_line: &FileLine = lines.get(index).unwrap();
@ -1060,7 +1171,11 @@ fn write_columns(
} }
lines_printed += 1; lines_printed += 1;
} }
out.write(line_separator)?; if not_found_break && feed_line_present {
break;
} else {
out.write(line_separator)?;
}
} }
Ok(lines_printed) Ok(lines_printed)
} }
@ -1161,7 +1276,7 @@ fn current_time() -> String {
} }
fn trailer_content(options: &OutputOptions) -> Vec<String> { fn trailer_content(options: &OutputOptions) -> Vec<String> {
if options.as_ref().display_trailer { if options.as_ref().display_trailer && !options.form_feed_used {
vec![ vec![
BLANK_STRING.to_string(), BLANK_STRING.to_string(),
BLANK_STRING.to_string(), BLANK_STRING.to_string(),

330
tests/fixtures/pr/0F vendored Normal file
View file

@ -0,0 +1,330 @@
{last_modified_time} {file_name} Page 1
{last_modified_time} {file_name} Page 2
1 FF-Test: FF's at Start of File V
2 Options -b -3 / -a -3 / ...
3 --------------------------------------------
4 3456789 123456789 123456789 123456789 12345678
5 3 Columns downwards ..., <= 5 lines per page
6 FF-Arangements: Empty Pages at start
7 \ftext; \f\ntext;
8 \f\ftext; \f\f\ntext; \f\n\ftext; \f\n\f\n;
9 3456789 123456789 123456789
10 zzzzzzzzzzzzzzzzzzzzzzzzzz123456789
1 12345678
2 12345678
3 line truncation before FF; r_r_o_l-test:
14 456789 123456789 123456789 123456789
{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
8 12345678
9 3456789 ab
20 DEFGHI 123
1 12345678
2 12345678
3 12345678
4 12345678
5 12345678
6 12345678
27 no truncation before FF; (r_l-test):
28 no trunc
{last_modified_time} {file_name} Page 5
29 xyzxyzxyz XYZXYZXYZ abcabcab
30 456789 123456789 xyzxyzxyz XYZXYZXYZ
1 12345678
2 3456789 abcdefghi
3 12345678

36
tests/fixtures/pr/0Fnt vendored Normal file
View file

@ -0,0 +1,36 @@
1 FF-Test: FF's at Start of File V
2 Options -b -3 / -a -3 / ...
3 --------------------------------------------
4 3456789 123456789 123456789 123456789 12345678
5 3 Columns downwards ..., <= 5 lines per page
6 FF-Arangements: Empty Pages at start
7 \ftext; \f\ntext;
8 \f\ftext; \f\f\ntext; \f\n\ftext; \f\n\f\n;
9 3456789 123456789 123456789
10 zzzzzzzzzzzzzzzzzzzzzzzzzz123456789
1 12345678
2 12345678
3 line truncation before FF; r_r_o_l-test:
14 456789 123456789 123456789 123456789
15 xyzxyzxyz XYZXYZXYZ abcabcab
16 456789 123456789 xyzxyzxyz XYZXYZXYZ
7 12345678
8 12345678
9 3456789 ab
20 DEFGHI 123
1 12345678
2 12345678
3 12345678
4 12345678
5 12345678
6 12345678
27 no truncation before FF; (r_l-test):
28 no trunc
29 xyzxyzxyz XYZXYZXYZ abcabcab
30 456789 123456789 xyzxyzxyz XYZXYZXYZ
1 12345678
2 3456789 abcdefghi
3 12345678

35
tests/fixtures/pr/0Ft vendored Normal file
View file

@ -0,0 +1,35 @@
1 FF-Test: FF's at Start of File V
2 Options -b -3 / -a -3 / ...
3 --------------------------------------------
4 3456789 123456789 123456789 123456789 12345678
5 3 Columns downwards ..., <= 5 lines per page
6 FF-Arangements: Empty Pages at start
7 \ftext; \f\ntext;
8 \f\ftext; \f\f\ntext; \f\n\ftext; \f\n\f\n;
9 3456789 123456789 123456789
10 zzzzzzzzzzzzzzzzzzzzzzzzzz123456789
1 12345678
2 12345678
3 line truncation before FF; r_r_o_l-test:
14 456789 123456789 123456789 123456789
15 xyzxyzxyz XYZXYZXYZ abcabcab
16 456789 123456789 xyzxyzxyz XYZXYZXYZ
7 12345678
8 12345678
9 3456789 ab
20 DEFGHI 123
1 12345678
2 12345678
3 12345678
4 12345678
5 12345678
6 12345678
27 no truncation before FF; (r_l-test):
28 no trunc
29 xyzxyzxyz XYZXYZXYZ abcabcab
30 456789 123456789 xyzxyzxyz XYZXYZXYZ
1 12345678
2 3456789 abcdefghi
3 12345678

198
tests/fixtures/pr/3-0F vendored Normal file
View file

@ -0,0 +1,198 @@
{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
8 12345678
9 3456789 ab
20 DEFGHI 123
1 12345678
2 12345678
3 12345678
4 12345678
5 12345678
6 12345678
27 no truncation before FF; (r_l-test):
28 no trunc
{last_modified_time} {file_name} Page 5
29 xyzxyzxyz XYZXYZXYZ abcabcab
30 456789 123456789 xyzxyzxyz XYZXYZXYZ
1 12345678
2 3456789 abcdefghi
3 12345678

21
tests/fixtures/pr/3a3f-0F vendored Normal file
View file

@ -0,0 +1,21 @@
{last_modified_time} {file_name} Page 3
{last_modified_time} {file_name} Page 4
15 xyzxyzxyz XYZXYZXYZ 16 456789 123456789 xyz 7
8 9 3456789 ab 20 DEFGHI 123
1 2 3
4 5 6
27 no truncation before 28 no trunc
{last_modified_time} {file_name} Page 5
29 xyzxyzxyz XYZXYZXYZ 30 456789 123456789 xyz 1
2 3456789 abcdefghi 3

86
tests/fixtures/pr/3f-0F vendored Normal file
View file

@ -0,0 +1,86 @@
{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
8 12345678
9 3456789 ab
20 DEFGHI 123
1 12345678
2 12345678
3 12345678
4 12345678
5 12345678
6 12345678
27 no truncation before FF; (r_l-test):
28 no trunc
{last_modified_time} {file_name} Page 5
29 xyzxyzxyz XYZXYZXYZ abcabcab
30 456789 123456789 xyzxyzxyz XYZXYZXYZ
1 12345678
2 3456789 abcdefghi
3 12345678

68
tests/fixtures/pr/FnFn vendored Normal file
View file

@ -0,0 +1,68 @@
1 FF-Test: FF's in Text V
2 Options -b -3 / -a -3 / ...
3 --------------------------------------------
4 3456789 123456789 123456789 123456789 12345678
5 3 Columns downwards ..., <= 5 lines per page
6 FF-Arangements: One Empty Page
7 text\f\f\n; text\f\n\ftext; \f\ftext;
8 \f\f\n; \f\n\f\n;
9
10 zzzzzzzzzzzzzzzzzzzzzzzzzz123456789
1 12345678
2 12345678
3 line truncation before FF; r_r_o_l-test:
14 456789 123456789 123456789 123456789
15 xyzxyzxyz XYZXYZXYZ abcabcab
16 456789 123456789 xyzxyzxyz XYZXYZXYZ
7 12345678
8 12345678
9 3456789 ab
20 DEFGHI 123
1 12345678
2 12345678
3 12345678
4 12345678
5 12345678
6 12345678
27 no truncation before FF; (r_l-test):
28 no trunc
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
43 xyzxyzxyz XYZXYZXYZ abcabcab
44 456789 123456789 xyzxyzxyz XYZXYZXYZ
5 12345678
6 12345678
7 12345678
8 12345678
9 12345678
50 12345678
1 12345678
2 12345678
3 12345678
4 12345678
55 yzxyzxyz XYZXYZXYZ abcabcab
56 456789 123456789 abcdefghi ABCDEDFHI
57 xyzxyzxyz XYZXYZXYZ abcabcab
58 456789 123456789 xyzxyzxyz XYZXYZXYZ
9 12345678
60 DEFGHI 123456789

330
tests/fixtures/pr/a3-0F vendored Normal file
View file

@ -0,0 +1,330 @@
{last_modified_time} {file_name} Page 1
{last_modified_time} {file_name} Page 2
1 FF-Test: FF's at St 2 Options -b -3 / -a 3 -------------------
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
{last_modified_time} {file_name} Page 3
{last_modified_time} {file_name} Page 4
15 xyzxyzxyz XYZXYZXYZ 16 456789 123456789 xyz 7
8 9 3456789 ab 20 DEFGHI 123
1 2 3
4 5 6
27 no truncation before 28 no trunc
{last_modified_time} {file_name} Page 5
29 xyzxyzxyz XYZXYZXYZ 30 456789 123456789 xyz 1
2 3456789 abcdefghi 3

35
tests/fixtures/pr/a3f-0F vendored Normal file
View file

@ -0,0 +1,35 @@
{last_modified_time} {file_name} Page 1
{last_modified_time} {file_name} Page 2
1 FF-Test: FF's at St 2 Options -b -3 / -a 3 -------------------
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
{last_modified_time} {file_name} Page 3
{last_modified_time} {file_name} Page 4
15 xyzxyzxyz XYZXYZXYZ 16 456789 123456789 xyz 7
8 9 3456789 ab 20 DEFGHI 123
1 2 3
4 5 6
27 no truncation before 28 no trunc
{last_modified_time} {file_name} Page 5
29 xyzxyzxyz XYZXYZXYZ 30 456789 123456789 xyz 1
2 3456789 abcdefghi 3

216
tests/fixtures/pr/l24-FF vendored Normal file
View file

@ -0,0 +1,216 @@
{last_modified_time} {file_name} Page 1
1 FF-Test: FF's in Text V
2 Options -b -3 / -a -3 / ...
3 --------------------------------------------
4 3456789 123456789 123456789 123456789 12345678
5 3 Columns downwards ..., <= 5 lines per page
6 FF-Arangements: One Empty Page
7 text\f\f\n; text\f\n\ftext; \f\ftext;
8 \f\f\n; \f\n\f\n;
9
10 zzzzzzzzzzzzzzzzzzzzzzzzzz123456789
1 12345678
2 12345678
3 line truncation before FF; r_r_o_l-test:
14 456789 123456789 123456789 123456789
{last_modified_time} {file_name} Page 2
{last_modified_time} {file_name} Page 3
15 xyzxyzxyz XYZXYZXYZ abcabcab
16 456789 123456789 xyzxyzxyz XYZXYZXYZ
7 12345678
8 12345678
9 3456789 ab
20 DEFGHI 123
1 12345678
2 12345678
3 12345678
4 12345678
5 12345678
6 12345678
27 no truncation before FF; (r_l-test):
28 no trunc
{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
{last_modified_time} {file_name} Page 6
{last_modified_time} {file_name} Page 7
{last_modified_time} {file_name} Page 8
43 xyzxyzxyz XYZXYZXYZ abcabcab
44 456789 123456789 xyzxyzxyz XYZXYZXYZ
5 12345678
6 12345678
7 12345678
8 12345678
9 12345678
50 12345678
1 12345678
2 12345678
3 12345678
4 12345678
55 yzxyzxyz XYZXYZXYZ abcabcab
56 456789 123456789 abcdefghi ABCDEDFHI
{last_modified_time} {file_name} Page 9
57 xyzxyzxyz XYZXYZXYZ abcabcab
58 456789 123456789 xyzxyzxyz XYZXYZXYZ
9 12345678
60 DEFGHI 123456789

View file

@ -471,3 +471,49 @@ fn test_with_offset_space_option() {
vec![(&"{last_modified_time}".to_string(), &value)], vec![(&"{last_modified_time}".to_string(), &value)],
); );
} }
#[test]
fn test_with_pr_core_utils_tests() {
let test_cases = vec![
("", vec!["0Ft"], vec!["0F"], 0),
("", vec!["0Fnt"], vec!["0F"], 0),
("+3", vec!["0Ft"], vec!["3-0F"], 0),
("+3 -f", vec!["0Ft"], vec!["3f-0F"], 0),
("-a -3", vec!["0Ft"], vec!["a3-0F"], 0),
("-a -3 -f", vec!["0Ft"], vec!["a3f-0F"], 0),
("-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),
];
for test_case in test_cases {
let (flags, input_file, expected_file, return_code) = test_case;
let mut scenario = new_ucmd!();
let input_file_path = input_file.get(0).unwrap();
let test_file_path = expected_file.get(0).unwrap();
let value = file_last_modified_time(&scenario, test_file_path);
let mut arguments: Vec<&str> = flags
.split(' ')
.into_iter()
.filter(|i| i.trim() != "")
.collect::<Vec<&str>>();
arguments.extend(input_file.clone());
let mut scenario_with_args = scenario.args(&arguments);
let scenario_with_expected_status = if return_code == 0 {
scenario_with_args.succeeds()
} else {
scenario_with_args.fails()
};
scenario_with_expected_status.stdout_is_templated_fixture(
test_file_path,
vec![
(&"{last_modified_time}".to_string(), &value),
(&"{file_name}".to_string(), &input_file_path.to_string()),
],
);
}
}