negative limit counts from last line
authorMischa POSLAWSKY <perl@shiar.org>
Sat, 27 Mar 2021 22:57:35 +0000 (23:57 +0100)
committerMischa POSLAWSKY <perl@shiar.org>
Mon, 31 Oct 2022 22:42:56 +0000 (23:42 +0100)
barcat
t/t1504-bottom_limit_-L-3.out [moved from t/t1504-bottom_limit_-L-3_#TODO.out with 100% similarity]

diff --git a/barcat b/barcat
index 82f0fffd51870985cf19a30503e9e4dcb24535f6..5d0f85c287b571a726a6426ae027406b3b8cb0ef 100755 (executable)
--- a/barcat
+++ b/barcat
@@ -39,8 +39,9 @@ GetOptions(\%opt,
        'limit|L:s' => sub {
                my ($optname, $optval) = @_;
                $optval ||= 0;
        'limit|L:s' => sub {
                my ($optname, $optval) = @_;
                $optval ||= 0;
+               $optval =~ /\A-[0-9]+\z/ and $optval .= '-';  # tail shorthand
                ($opt{hidemin}, $opt{hidemax}) =
                ($opt{hidemin}, $opt{hidemax}) =
-               $optval =~ m/\A (?: ([0-9]+)? - )? ([0-9]+)? \z/ or die(
+               $optval =~ m/\A (?: (-? [0-9]+)? - )? ([0-9]+)? \z/ or die(
                        "Value \"$optval\" invalid for option limit",
                        " (range expected)\n"
                );
                        "Value \"$optval\" invalid for option limit",
                        " (range expected)\n"
                );
@@ -205,7 +206,9 @@ sub color {
 
 sub show_lines {
 
 
 sub show_lines {
 
-state $nr = $opt{hidemin};
+state $nr =
+       $opt{hidemin} < 0 ? @lines + $opt{hidemin} + 1 :
+       $opt{hidemin};
 @lines or return;
 @lines > $nr or return;
 
 @lines or return;
 @lines > $nr or return;
 
@@ -316,9 +319,12 @@ say $opt{palette} ? color(0) : '' if $opt{spark};
 
 sub show_stat {
        if ($opt{hidemin} or $opt{hidemax}) {
 
 sub show_stat {
        if ($opt{hidemin} or $opt{hidemax}) {
-               printf '%.8g of ', $opt{'sum-format'}->(sum(grep { length }
-                       @values[$opt{hidemin} .. ($opt{hidemax} || @lines) - 1]
-               ) // 0);
+               my $linemin = $opt{hidemin};
+               $linemin += @lines if $linemin < 0;
+               my $linemax = ($opt{hidemax} || @lines) - 1;
+               printf '%.8g of ', $opt{'sum-format'}->(
+                       sum(grep {length} @values[$linemin .. $linemax]) // 0
+               );
        }
        if (@order) {
                my $total = sum @order;
        }
        if (@order) {
                my $total = sum @order;
@@ -422,9 +428,13 @@ unless C<--length=0>.
 Prepend a dash (i.e. make negative) to enforce padding
 regardless of encountered contents.
 
 Prepend a dash (i.e. make negative) to enforce padding
 regardless of encountered contents.
 
-=item -L, --limit[=(<count> | <start>-[<end>])]
+=item -L, --limit[=(<count> | -<last> | <start>-[<end>])]
 
 Stop output after a number of lines.
 
 Stop output after a number of lines.
+A single value indicates the last line number (like C<head>),
+or first line counting from the bottom if negative (like C<tail>).
+A specific range can be given by two values.
+
 All input is still counted and analyzed for statistics,
 but disregarded for padding and bar size.
 
 All input is still counted and analyzed for statistics,
 but disregarded for padding and bar size.