#!/usr/bin/perl
# DUMP - bytes and chars for my own version of od
# SSF 041506 initial work
# SSF 092306 suppress ctrl characters in text, final 00
# SSF 052407 take STDIN if file is -
# SSF 052607 use -u to get rid of weirdness with embedded wide chars
####################################################################
use strict;
use bytes;
use Encode;
use Getopt::Std;
my (%opts,$file,$cols,$rows);
eval "use Term::Size 'chars'"; # if available
($cols,$rows)=chars() unless $@;
getopts('dhosuw:x',\%opts);
map { $file+=$opts{$_} } qw/d o x/; # prevent specifying exclusive fl
+ags
if (!@ARGV or $opts{h} or $file>1) {
print "Mutually exclusive flags: -d, -o, -x\n" if $file>1;
print "Usage: dump [-w chars] [-dhox] file|glob...\n",
" Dump bytes and chars for file(s), or STDIN if - given
+ as file\n",
"-d Display decimal instead of hex\n",
"-h This help display\n",
"-o Display octal instead of hex\n",
"-u Tolerate wide characters (UTF8, Unicode)\n",
"-s Suppress header text\n",
"-x Display hex (default)\n";
exit 1;
}
$opts{w}||=$cols;
$cols=$opts{w}||80;
my $ofmt='%06X '; # offset format
my $fmt='%02X '; # byte format
my $spc=' '; # space (file ends before block boundary)
my $n=3; # chars to show one byte
my $div=8; # divider every n bytes
if ($opts{o}) {
$ofmt='%06o ';
$fmt='%03o ';
$spc=' ';
$n=4;
}
elsif ($opts{d}) {
$ofmt='%6d ';
$fmt='%3d ';
$spc=' ';
$n=4;
$div=10;
}
my $cpr; # number of chars per row - formulas are offset+di
+viders+bytes+chars
if ($opts{d}) { # decimal display
if ($cols>=8+4+$n*30+30) {
$cpr=30;
}
elsif ($cols>=8+2+$n*20+20) {
$cpr=20;
}
else { # 8+0+$n*10+10
$cpr=10;
}
} else { # hex or octal display
if ($cols>=8+6+$n*32+32) {
$cpr=32;
}
elsif ($cols>=8+4+$n*24+24) {
$cpr=24;
}
elsif ($cols>=8+2+$n*16+16) {
$cpr=16;
}
else { # 8+0+$n*8+8
$cpr=8;
}
}
my $blk=$cpr*32; # block size
my ($i,$j,$c,$buf,@row); my $offset=0;
my @files;
for $file (@ARGV) {
if ($file=~/[?*\[\]]/) {
push @files,glob $file;
} else {
push @files,$file;
}
}
for $file (@files) {
printf "File %s:\n",($file eq '-' ? 'STDIN' : $file) unless $opts{s
+};
open(FILE,$file) || die "$file: $!";
while ($c=sysread(FILE,$buf,$blk)) {
$buf=Encode::encode('ascii',$buf) if $opts{u};
for ($i=0; $i<$c; $i+=$cpr) {
printf $ofmt,$offset+$i;
@row=0;
for ($j=0; $j<$cpr; $j++) {
print '| ' if ($j and !($j%$div));
if ($i+$j>=length($buf)) {
print $spc;
} else {
$row[$j]=ord(substr($buf,$i+$j,1));
printf $fmt,$row[$j];
}
}
for ($j=0; $j<$cpr; $j++) {
if ($i+$j>=length($buf)) {
print ' ';
} else {
if ($row[$j]<32 || $row[$j]>126) {
print '.';
} else {
print chr($row[$j]);
}
}
}
print "\n";
}
$offset+=$blk;
}
close FILE;
}
exit;
|