Skip to content

Commit

Permalink
Merge pull request #203 from mknos/od-limit
Browse files Browse the repository at this point in the history
od: add -N option: limit input bytes
  • Loading branch information
briandfoy authored Jul 15, 2023
2 parents 7f186d9 + 8628924 commit 3ace270
Showing 1 changed file with 76 additions and 27 deletions.
103 changes: 76 additions & 27 deletions bin/od
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@ License: perl


use strict;
use Getopt::Std;
use vars qw/ $opt_A $opt_b $opt_c $opt_d $opt_f $opt_i $opt_j $opt_l $opt_o
$opt_v $opt_x /;

my ($offset1, $radix, $data, @arr, $len, $fh);
use File::Basename qw(basename);
use Getopt::Std qw(getopts);

use constant EX_SUCCESS => 0;
use constant EX_FAILURE => 1;
use constant LINESZ => 16;

use vars qw/ $opt_A $opt_b $opt_c $opt_d $opt_f $opt_i $opt_j $opt_l $opt_N
$opt_o $opt_v $opt_x /;

my ($offset1, $radix, $data, @arr, $len, $fh, $lim);
my ($lastline, $upformat, $pffmt, $strfmt, $ml);

my %charescs = (
Expand Down Expand Up @@ -58,25 +65,55 @@ my %charescs = (
$offset1 = 0;
$lastline = '';

getopts('A:bcdfij:lovx') or help();
my $Program = basename($0);

getopts('A:bcdfij:lN:ovx') or help();
defined $opt_A ? ($radix = $opt_A) : ($radix = 'o');
defined $opt_j && ($offset1 = $opt_j);
if (defined $opt_j) {
if ($opt_j =~ m/\D/) {
warn "$Program: bad argument to -j: '$opt_j'\n";
exit EX_FAILURE;
}
$offset1 = $opt_j;
}
if (defined $opt_N) {
if ($opt_N =~ m/\D/) {
warn "$Program: bad argument to -N: '$opt_N'\n";
exit EX_FAILURE;
}
$lim = $opt_N;
}

if (defined $ARGV[0] && $ARGV[0] ne '-') {
open($fh, '<', $ARGV[0]) or die "$0: $ARGV[0]: $!\n";
unless (open $fh, '<', $ARGV[0]) {
warn "$Program: cannot open '$ARGV[0]': $!\n";
exit EX_FAILURE;
}
}
else {
$fh = *STDIN;
}

binmode $fh;
if ($offset1 && !seek($fh, $offset1, 0)) {
if ($offset1) {
foreach (1 .. $offset1) {
$len = read $fh, $data, 1;
die "$0: read error: $!\n" if $!;
if ($len == 0) {
warn "$Program: cannot skip past end of input\n";
exit EX_FAILURE;
}
unless (defined $len) {
warn "$Program: read error: $!\n";
exit EX_FAILURE;
}
undef $data;
}
}
if (defined($lim) && $lim == 0) {
printf("%.8$radix\n", $offset1);
close $fh;
exit EX_SUCCESS;
}

$opt_o = 1 if ! ($opt_b || $opt_c || $opt_d || $opt_f || $opt_i ||
$opt_l || $opt_o || $opt_x);
Expand Down Expand Up @@ -110,27 +147,39 @@ else {
help();
}

while ($len = read($fh, $data, 16)) {
$ml = ''; # multi-line indention

if ( &diffdata || $opt_v) {
printf("%.8$radix ", $offset1);
&$fmt;
printf("%s$strfmt\n", $ml, @arr);
$ml = ' ' x 9;
}
else {
print "*\n";
my $buf;
my $nread = 0;
while ($len = read($fh, $buf, 1)) {
$data .= $buf;
$nread++;

my $is_limit = defined($lim) && $nread == $lim;
if (length($data) == LINESZ || $is_limit || eof($fh)) {
$ml = ''; # multi-line indention
if (&diffdata || $opt_v) {
printf("%.8$radix ", $offset1);
&$fmt;
printf("%s$strfmt\n", $ml, @arr);
$ml = ' ' x 9;
}
else {
print "*\n";
}
$lastline = $data . '|';
undef $data;
}

$offset1 += $len;
$lastline = $data . '|';
$offset1++;
last if $is_limit;
}
unless (defined $len) {
warn "$Program: read error: $!\n";
exit EX_FAILURE;
}
die "$0: read error: $!\n" if $!;

printf("%.8$radix\n", $offset1);
close $fh;
exit 0;
exit EX_SUCCESS;

sub octal1 {
$upformat = 'C*'; # for -b
Expand Down Expand Up @@ -217,8 +266,8 @@ sub diffdata {
}

sub help {
print "usage: od [-bcdfiloxv] [-A radix] filename\n";
exit 1;
print "usage: od [-bcdfiloxv] [-A radix] [-j skip_bytes] [-N limit_bytes] filename\n";
exit EX_FAILURE;
}
__END__
Expand All @@ -228,7 +277,7 @@ od - dump files in octal and other formats
=head1 SYNOPSIS
B<od.pl> [ I<-abcdfiloxv> ] [I<-j skip_n_bytes>] [ I<-A radix> ] F<filename>
B<od> [ I<-abcdfiloxv> ] [I<-j skip_n_bytes>] [I<-N read_n_bytes>] [ I<-A radix> ] F<filename>
=head1 DESCRIPTION
Expand Down

0 comments on commit 3ace270

Please sign in to comment.