mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
nl: increase line number over multiple files
This commit is contained in:
parent
351722ebac
commit
1107fadca9
2 changed files with 37 additions and 9 deletions
|
@ -55,6 +55,20 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Stats {
|
||||||
|
line_number: i64,
|
||||||
|
consecutive_empty_lines: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stats {
|
||||||
|
fn new(starting_line_number: i64) -> Self {
|
||||||
|
Self {
|
||||||
|
line_number: starting_line_number,
|
||||||
|
consecutive_empty_lines: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NumberingStyle stores which lines are to be numbered.
|
// NumberingStyle stores which lines are to be numbered.
|
||||||
// The possible options are:
|
// The possible options are:
|
||||||
// 1. Number all lines
|
// 1. Number all lines
|
||||||
|
@ -160,6 +174,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
None => vec!["-".to_owned()],
|
None => vec!["-".to_owned()],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut stats = Stats::new(settings.starting_line_number);
|
||||||
|
|
||||||
for file in &files {
|
for file in &files {
|
||||||
if file == "-" {
|
if file == "-" {
|
||||||
// If both file names and '-' are specified, we choose to treat first all
|
// If both file names and '-' are specified, we choose to treat first all
|
||||||
|
@ -170,12 +186,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let path = Path::new(file);
|
let path = Path::new(file);
|
||||||
let reader = File::open(path).map_err_context(|| file.to_string())?;
|
let reader = File::open(path).map_err_context(|| file.to_string())?;
|
||||||
let mut buffer = BufReader::new(reader);
|
let mut buffer = BufReader::new(reader);
|
||||||
nl(&mut buffer, &settings)?;
|
nl(&mut buffer, &mut stats, &settings)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if read_stdin {
|
if read_stdin {
|
||||||
let mut buffer = BufReader::new(stdin());
|
let mut buffer = BufReader::new(stdin());
|
||||||
nl(&mut buffer, &settings)?;
|
nl(&mut buffer, &mut stats, &settings)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -285,10 +301,9 @@ pub fn uu_app() -> Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
// nl implements the main functionality for an individual buffer.
|
// nl implements the main functionality for an individual buffer.
|
||||||
fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> UResult<()> {
|
fn nl<T: Read>(reader: &mut BufReader<T>, stats: &mut Stats, settings: &Settings) -> UResult<()> {
|
||||||
let mut current_numbering_style = &settings.body_numbering;
|
let mut current_numbering_style = &settings.body_numbering;
|
||||||
let mut line_no = settings.starting_line_number;
|
let mut consecutive_empty_lines = stats.consecutive_empty_lines;
|
||||||
let mut consecutive_empty_lines = 0;
|
|
||||||
|
|
||||||
for line in reader.lines() {
|
for line in reader.lines() {
|
||||||
let line = line.map_err_context(|| "could not read line".to_string())?;
|
let line = line.map_err_context(|| "could not read line".to_string())?;
|
||||||
|
@ -312,7 +327,7 @@ fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> UResult<()> {
|
||||||
if let Some(new_style) = new_numbering_style {
|
if let Some(new_style) = new_numbering_style {
|
||||||
current_numbering_style = new_style;
|
current_numbering_style = new_style;
|
||||||
if settings.renumber {
|
if settings.renumber {
|
||||||
line_no = settings.starting_line_number;
|
stats.line_number = settings.starting_line_number;
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
} else {
|
} else {
|
||||||
|
@ -336,13 +351,13 @@ fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> UResult<()> {
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
settings
|
settings
|
||||||
.number_format
|
.number_format
|
||||||
.format(line_no, settings.number_width),
|
.format(stats.line_number, settings.number_width),
|
||||||
settings.number_separator,
|
settings.number_separator,
|
||||||
line
|
line
|
||||||
);
|
);
|
||||||
// update line number for the potential next line
|
// update line number for the potential next line
|
||||||
match line_no.checked_add(settings.line_increment) {
|
match stats.line_number.checked_add(settings.line_increment) {
|
||||||
Some(new_line_no) => line_no = new_line_no,
|
Some(new_line_number) => stats.line_number = new_line_number,
|
||||||
None => return Err(USimpleError::new(1, "line number overflow")),
|
None => return Err(USimpleError::new(1, "line number overflow")),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -311,6 +311,19 @@ fn test_default_body_numbering() {
|
||||||
.stdout_is(" 1\ta\n \n 2\tb\n");
|
.stdout_is(" 1\ta\n \n 2\tb\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_default_body_numbering_multiple_files() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
|
||||||
|
at.write("a.txt", "a");
|
||||||
|
at.write("b.txt", "b");
|
||||||
|
at.write("c.txt", "c");
|
||||||
|
|
||||||
|
ucmd.args(&["a.txt", "b.txt", "c.txt"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(" 1\ta\n 2\tb\n 3\tc\n");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_body_numbering_all_lines_without_delimiter() {
|
fn test_body_numbering_all_lines_without_delimiter() {
|
||||||
for arg in ["-ba", "--body-numbering=a"] {
|
for arg in ["-ba", "--body-numbering=a"] {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue