mirror of
https://github.com/uutils/coreutils
synced 2024-12-25 04:23:16 +00:00
pr: reformat with rustfmt
pr: refactor batching of pages in pr
This commit is contained in:
parent
40e7f3d900
commit
aefc2eb540
1 changed files with 106 additions and 162 deletions
268
src/pr/pr.rs
268
src/pr/pr.rs
|
@ -20,6 +20,7 @@ use chrono::offset::Local;
|
||||||
use chrono::DateTime;
|
use chrono::DateTime;
|
||||||
use getopts::{HasArg, Occur};
|
use getopts::{HasArg, Occur};
|
||||||
use getopts::{Matches, Options};
|
use getopts::{Matches, Options};
|
||||||
|
use itertools::structs::Batching;
|
||||||
use itertools::structs::KMergeBy;
|
use itertools::structs::KMergeBy;
|
||||||
use itertools::{GroupBy, Itertools};
|
use itertools::{GroupBy, Itertools};
|
||||||
use quick_error::ResultExt;
|
use quick_error::ResultExt;
|
||||||
|
@ -350,9 +351,9 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
"separate columns by STRING,
|
"separate columns by STRING,
|
||||||
without -S: Default separator <TAB> with -J and <space>
|
without -S: Default separator <TAB> with -J and <space>
|
||||||
otherwise (same as -S\" \"), no effect on column options",
|
otherwise (same as -S\" \"), no effect on column options",
|
||||||
"string",
|
"string",
|
||||||
HasArg::Yes,
|
HasArg::Yes,
|
||||||
Occur::Optional,
|
Occur::Optional,
|
||||||
);
|
);
|
||||||
|
|
||||||
opts.opt(
|
opts.opt(
|
||||||
|
@ -672,10 +673,10 @@ fn build_options(
|
||||||
x[0].to_string()
|
x[0].to_string()
|
||||||
})
|
})
|
||||||
.map(invalid_pages_map)
|
.map(invalid_pages_map)
|
||||||
{
|
{
|
||||||
Some(res) => res?,
|
Some(res) => res?,
|
||||||
_ => start_page_in_plus_option,
|
_ => start_page_in_plus_option,
|
||||||
};
|
};
|
||||||
|
|
||||||
let end_page: Option<usize> = match matches
|
let end_page: Option<usize> = match matches
|
||||||
.opt_str(PAGE_RANGE_OPTION)
|
.opt_str(PAGE_RANGE_OPTION)
|
||||||
|
@ -685,10 +686,10 @@ fn build_options(
|
||||||
x[1].to_string()
|
x[1].to_string()
|
||||||
})
|
})
|
||||||
.map(invalid_pages_map)
|
.map(invalid_pages_map)
|
||||||
{
|
{
|
||||||
Some(res) => Some(res?),
|
Some(res) => Some(res?),
|
||||||
_ => end_page_in_plus_option,
|
_ => end_page_in_plus_option,
|
||||||
};
|
};
|
||||||
|
|
||||||
if end_page.is_some() && start_page > end_page.unwrap() {
|
if end_page.is_some() && start_page > end_page.unwrap() {
|
||||||
return Err(PrError::EncounteredErrors(format!(
|
return Err(PrError::EncounteredErrors(format!(
|
||||||
|
@ -723,12 +724,11 @@ fn build_options(
|
||||||
|
|
||||||
let across_mode: bool = matches.opt_present(ACROSS_OPTION);
|
let across_mode: bool = matches.opt_present(ACROSS_OPTION);
|
||||||
|
|
||||||
let column_separator: String = match matches.opt_str(COLUMN_STRING_SEPARATOR_OPTION)
|
let column_separator: String = match matches.opt_str(COLUMN_STRING_SEPARATOR_OPTION) {
|
||||||
{
|
Some(x) => Some(x),
|
||||||
Some(x) => Some(x),
|
None => matches.opt_str(COLUMN_CHAR_SEPARATOR_OPTION),
|
||||||
None => matches.opt_str(COLUMN_CHAR_SEPARATOR_OPTION),
|
}
|
||||||
}
|
.unwrap_or(DEFAULT_COLUMN_SEPARATOR.to_string());
|
||||||
.unwrap_or(DEFAULT_COLUMN_SEPARATOR.to_string());
|
|
||||||
|
|
||||||
let default_column_width = if matches.opt_present(COLUMN_WIDTH_OPTION)
|
let default_column_width = if matches.opt_present(COLUMN_WIDTH_OPTION)
|
||||||
&& matches.opt_present(COLUMN_CHAR_SEPARATOR_OPTION)
|
&& matches.opt_present(COLUMN_CHAR_SEPARATOR_OPTION)
|
||||||
|
@ -832,128 +832,102 @@ fn open(path: &str) -> Result<Box<Read>, PrError> {
|
||||||
.unwrap_or(Err(PrError::NotExists(path.to_string())))
|
.unwrap_or(Err(PrError::NotExists(path.to_string())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pr(path: &String, options: &OutputOptions) -> Result<i32, PrError> {
|
fn split_lines_if_form_feed(file_content: Result<String, IOError>) -> Vec<FileLine> {
|
||||||
let start_page: &usize = &options.start_page;
|
file_content
|
||||||
let start_line_number: usize = get_start_line_number(options);
|
.map(|content| {
|
||||||
let last_page: Option<&usize> = options.end_page.as_ref();
|
let mut lines: Vec<FileLine> = Vec::new();
|
||||||
let lines_needed_per_page: usize = lines_to_read_for_page(options);
|
let mut f_occurred: usize = 0;
|
||||||
let is_form_feed_used = options.form_feed_used;
|
let mut chunk: Vec<u8> = Vec::new();
|
||||||
let lines: Map<Map<Enumerate<FlatMap<Map<Lines<BufReader<Box<Read>>>, _>, _, _>>, _>, _> =
|
for byte in content.as_bytes() {
|
||||||
BufReader::with_capacity(READ_BUFFER_SIZE, open(path)?)
|
if byte == &FF {
|
||||||
.lines()
|
f_occurred += 1;
|
||||||
.map(|file_content: Result<String, IOError>| {
|
} else {
|
||||||
file_content
|
if f_occurred != 0 {
|
||||||
.map(|content| {
|
|
||||||
let mut lines: Vec<FileLine> = Vec::new();
|
|
||||||
let mut f_occurred: usize = 0;
|
|
||||||
let mut chunk: Vec<u8> = Vec::new();
|
|
||||||
for byte in content.as_bytes() {
|
|
||||||
if byte == &FF {
|
|
||||||
f_occurred += 1;
|
|
||||||
} else {
|
|
||||||
if f_occurred != 0 {
|
|
||||||
// First time byte occurred in the scan
|
|
||||||
lines.push(FileLine {
|
|
||||||
line_content: Ok(String::from_utf8(chunk.clone()).unwrap()),
|
|
||||||
form_feeds_after: f_occurred,
|
|
||||||
..FileLine::default()
|
|
||||||
});
|
|
||||||
chunk.clear();
|
|
||||||
}
|
|
||||||
chunk.push(*byte);
|
|
||||||
f_occurred = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// First time byte occurred in the scan
|
// First time byte occurred in the scan
|
||||||
lines.push(FileLine {
|
lines.push(FileLine {
|
||||||
line_content: Ok(String::from_utf8(chunk.clone()).unwrap()),
|
line_content: Ok(String::from_utf8(chunk.clone()).unwrap()),
|
||||||
form_feeds_after: f_occurred,
|
form_feeds_after: f_occurred,
|
||||||
..FileLine::default()
|
..FileLine::default()
|
||||||
});
|
});
|
||||||
|
chunk.clear();
|
||||||
|
}
|
||||||
|
chunk.push(*byte);
|
||||||
|
f_occurred = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lines
|
lines.push(FileLine {
|
||||||
})
|
line_content: Ok(String::from_utf8(chunk.clone()).unwrap()),
|
||||||
.unwrap_or_else(|e| {
|
form_feeds_after: f_occurred,
|
||||||
vec![FileLine {
|
..FileLine::default()
|
||||||
line_content: Err(e),
|
});
|
||||||
..FileLine::default()
|
|
||||||
}]
|
lines
|
||||||
})
|
})
|
||||||
})
|
.unwrap_or_else(|e| {
|
||||||
.flat_map(|i| i)
|
vec![FileLine {
|
||||||
.enumerate()
|
line_content: Err(e),
|
||||||
.map(|i: (usize, FileLine)| FileLine {
|
..FileLine::default()
|
||||||
line_number: i.0,
|
}]
|
||||||
..i.1
|
})
|
||||||
})
|
}
|
||||||
.map(|file_line: FileLine| FileLine {
|
|
||||||
line_number: file_line.line_number + start_line_number,
|
fn pr(path: &String, options: &OutputOptions) -> Result<i32, PrError> {
|
||||||
..file_line
|
let start_page: &usize = &options.start_page;
|
||||||
}); // get display line number with line content
|
let start_line_number: usize = get_start_line_number(options);
|
||||||
|
let last_page: Option<&usize> = options.end_page.as_ref();
|
||||||
|
let lines_needed_per_page: usize = lines_to_read_for_page(options);
|
||||||
|
let pages: Batching<
|
||||||
|
Map<Map<Enumerate<FlatMap<Map<Lines<BufReader<Box<Read>>>, _>, _, _>>, _>, _>,
|
||||||
|
_,
|
||||||
|
> = BufReader::with_capacity(READ_BUFFER_SIZE, open(path)?)
|
||||||
|
.lines()
|
||||||
|
.map(split_lines_if_form_feed)
|
||||||
|
.flat_map(|i: Vec<FileLine>| 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
|
||||||
|
.batching(|it| {
|
||||||
|
let mut first_page: Vec<FileLine> = Vec::new();
|
||||||
|
let mut page_with_lines: Vec<Vec<FileLine>> = Vec::new();
|
||||||
|
for line in it {
|
||||||
|
let form_feeds_after = line.form_feeds_after;
|
||||||
|
first_page.push(line);
|
||||||
|
|
||||||
|
if form_feeds_after > 1 {
|
||||||
|
// insert empty pages
|
||||||
|
page_with_lines.push(first_page);
|
||||||
|
for _i in 1..form_feeds_after {
|
||||||
|
page_with_lines.push(vec![]);
|
||||||
|
}
|
||||||
|
return Some(page_with_lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
if first_page.len() == lines_needed_per_page || form_feeds_after == 1 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if first_page.len() == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
page_with_lines.push(first_page);
|
||||||
|
return Some(page_with_lines);
|
||||||
|
});
|
||||||
|
|
||||||
let mut page_number = 1;
|
let mut page_number = 1;
|
||||||
let mut page_lines: Vec<FileLine> = Vec::new();
|
for page_set in pages {
|
||||||
let mut feed_line_present = false;
|
for page in page_set {
|
||||||
for file_line in lines {
|
print_page(&page, options, &page_number, &start_page, &last_page)?;
|
||||||
if file_line.line_content.is_err() {
|
page_number += 1;
|
||||||
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 || form_feeds_after > 0 {
|
|
||||||
if form_feeds_after > 1 {
|
|
||||||
print_page(
|
|
||||||
&page_lines,
|
|
||||||
options,
|
|
||||||
&page_number,
|
|
||||||
&start_page,
|
|
||||||
&last_page,
|
|
||||||
feed_line_present,
|
|
||||||
)?;
|
|
||||||
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,
|
|
||||||
&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 page_lines.len() != 0 {
|
|
||||||
print_page(
|
|
||||||
&page_lines,
|
|
||||||
options,
|
|
||||||
&page_number,
|
|
||||||
&start_page,
|
|
||||||
&last_page,
|
|
||||||
feed_line_present,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,14 +1008,7 @@ 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(
|
print_page(&lines, options, &page_counter, &start_page, &last_page)?;
|
||||||
&lines,
|
|
||||||
options,
|
|
||||||
&page_counter,
|
|
||||||
&start_page,
|
|
||||||
&last_page,
|
|
||||||
false,
|
|
||||||
)?;
|
|
||||||
lines = Vec::new();
|
lines = Vec::new();
|
||||||
}
|
}
|
||||||
lines.push(file_line);
|
lines.push(file_line);
|
||||||
|
@ -1050,14 +1017,7 @@ 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(
|
print_page(&lines, options, &page_counter, &start_page, &last_page)?;
|
||||||
&lines,
|
|
||||||
options,
|
|
||||||
&page_counter,
|
|
||||||
&start_page,
|
|
||||||
&last_page,
|
|
||||||
false,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
@ -1124,7 +1084,6 @@ fn print_page(
|
||||||
page: &usize,
|
page: &usize,
|
||||||
start_page: &usize,
|
start_page: &usize,
|
||||||
last_page: &Option<&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 {
|
if (last_page.is_some() && page > last_page.unwrap()) || page < start_page {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
|
@ -1141,7 +1100,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();
|
||||||
|
@ -1159,7 +1118,6 @@ 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 {
|
||||||
|
@ -1189,20 +1147,6 @@ fn write_columns(
|
||||||
.unwrap_or(&blank_line),
|
.unwrap_or(&blank_line),
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO simplify
|
|
||||||
let col_width: Option<usize> = options
|
|
||||||
.column_mode_options
|
|
||||||
.as_ref()
|
|
||||||
.map(|i| Some(i.width))
|
|
||||||
.unwrap_or(
|
|
||||||
options
|
|
||||||
.merge_files_print
|
|
||||||
.map(|_k| Some(DEFAULT_COLUMN_WIDTH))
|
|
||||||
.unwrap_or(None),
|
|
||||||
);
|
|
||||||
|
|
||||||
let page_width: Option<usize> = options.page_width;
|
|
||||||
|
|
||||||
let line_width: Option<usize> = if options.join_lines {
|
let line_width: Option<usize> = if options.join_lines {
|
||||||
None
|
None
|
||||||
} else if columns > 1 {
|
} else if columns > 1 {
|
||||||
|
@ -1238,7 +1182,7 @@ fn write_columns(
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
|
let feed_line_present = options.form_feed_used;
|
||||||
let spaces = " ".repeat(*offset_spaces);
|
let spaces = " ".repeat(*offset_spaces);
|
||||||
let mut not_found_break = false;
|
let mut not_found_break = false;
|
||||||
for fetch_index in fetch_indexes {
|
for fetch_index in fetch_indexes {
|
||||||
|
|
Loading…
Reference in a new issue