mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #5091 from cakebaker/nl_fix_output_of_line_numbers
nl: fix calculation of line number lengths
This commit is contained in:
commit
e15e03a2bf
2 changed files with 54 additions and 17 deletions
|
@ -263,13 +263,8 @@ pub fn uu_app() -> Command {
|
||||||
fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> UResult<()> {
|
fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> UResult<()> {
|
||||||
let regexp: regex::Regex = regex::Regex::new(r".?").unwrap();
|
let regexp: regex::Regex = regex::Regex::new(r".?").unwrap();
|
||||||
let mut line_no = settings.starting_line_number;
|
let mut line_no = settings.starting_line_number;
|
||||||
// The current line number's width as a string. Using to_string is inefficient
|
let mut line_no_width = line_no.len();
|
||||||
// but since we only do it once, it should not hurt.
|
|
||||||
let mut line_no_width = line_no.to_string().len();
|
|
||||||
let line_no_width_initial = line_no_width;
|
let line_no_width_initial = line_no_width;
|
||||||
// Stores the smallest integer with one more digit than line_no, so that
|
|
||||||
// when line_no >= line_no_threshold, we need to use one more digit.
|
|
||||||
let mut line_no_threshold = 10i64.pow(line_no_width as u32);
|
|
||||||
let mut empty_line_count: u64 = 0;
|
let mut empty_line_count: u64 = 0;
|
||||||
let fill_char = match settings.number_format {
|
let fill_char = match settings.number_format {
|
||||||
NumberFormat::RightZero => '0',
|
NumberFormat::RightZero => '0',
|
||||||
|
@ -331,7 +326,6 @@ fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> UResult<()> {
|
||||||
if settings.renumber {
|
if settings.renumber {
|
||||||
line_no = settings.starting_line_number;
|
line_no = settings.starting_line_number;
|
||||||
line_no_width = line_no_width_initial;
|
line_no_width = line_no_width_initial;
|
||||||
line_no_threshold = 10i64.pow(line_no_width as u32);
|
|
||||||
}
|
}
|
||||||
&settings.header_numbering
|
&settings.header_numbering
|
||||||
}
|
}
|
||||||
|
@ -400,11 +394,7 @@ fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> UResult<()> {
|
||||||
// Now update the variables for the (potential) next
|
// Now update the variables for the (potential) next
|
||||||
// line.
|
// line.
|
||||||
line_no += settings.line_increment;
|
line_no += settings.line_increment;
|
||||||
while line_no >= line_no_threshold {
|
line_no_width = line_no.len();
|
||||||
// The line number just got longer.
|
|
||||||
line_no_threshold *= 10;
|
|
||||||
line_no_width += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -424,3 +414,39 @@ fn pass_none(_: &str, _: ®ex::Regex) -> bool {
|
||||||
fn pass_all(_: &str, _: ®ex::Regex) -> bool {
|
fn pass_all(_: &str, _: ®ex::Regex) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait Length {
|
||||||
|
fn len(&self) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Length for i64 {
|
||||||
|
// Returns the length in `char`s.
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
if *self == 0 {
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
let sign_len = if *self < 0 { 1 } else { 0 };
|
||||||
|
(0..).take_while(|i| 10i64.pow(*i) <= self.abs()).count() + sign_len
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_len() {
|
||||||
|
assert_eq!((-1).len(), 2);
|
||||||
|
assert_eq!((-10).len(), 3);
|
||||||
|
assert_eq!((-100).len(), 4);
|
||||||
|
assert_eq!((-1000).len(), 5);
|
||||||
|
|
||||||
|
assert_eq!(0.len(), 1);
|
||||||
|
|
||||||
|
assert_eq!(1.len(), 1);
|
||||||
|
assert_eq!(10.len(), 2);
|
||||||
|
assert_eq!(100.len(), 3);
|
||||||
|
assert_eq!(1000.len(), 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -213,14 +213,25 @@ fn test_line_increment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_negative_line_increment() {
|
fn test_line_increment_from_negative_starting_line() {
|
||||||
// TODO make this test work with -10
|
for arg in ["-i10", "--line-increment=10"] {
|
||||||
for arg in ["-i-1", "--line-increment=-1"] {
|
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.arg(arg)
|
.arg(arg)
|
||||||
.pipe_in("a\nb")
|
.arg("-v-19")
|
||||||
|
.pipe_in("a\nb\nc")
|
||||||
.succeeds()
|
.succeeds()
|
||||||
.stdout_is(" 1\ta\n 0\tb\n");
|
.stdout_is(" -19\ta\n -9\tb\n 1\tc\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_negative_line_increment() {
|
||||||
|
for arg in ["-i-10", "--line-increment=-10"] {
|
||||||
|
new_ucmd!()
|
||||||
|
.arg(arg)
|
||||||
|
.pipe_in("a\nb\nc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(" 1\ta\n -9\tb\n -19\tc\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue