#!/usr/bin/perl 

# jkob 13/04/2007  14/12/2011  30/11/201 


sub usage {

    print <<EOF;

NAZWA
   $name -- układ pamięci dla danego procesu

SKŁADNIA
   $name [-u k|K|m|M|g|G|t|T|p|P] [-x] <command name>
   
OPIS PROGRAMU 
    Program wywołuje pmap dla PID odpowiadającego podanej komendzie i wypisuje adresy w
    systemie dziesiętnym zamiast szestnastkowym. Adresy mogą być wypisywane w KB, MB, GB,
    itd. (dokładniej KiB, MiB, ...).


OPCJE PROGRAMU
   -u k|K adresy w KiB (adres/2^10)
  
   -u m|M adresy w MiB (adres/2^20)

   -u g|G adresy w GiB (adres/2^30)

   -u t|T adresy w TiB (adres/2^40)

   -u p|P adresy w PiB (adres/2^50)

   -u e|E adresy w EiB (adres/2^60)

   -u z|Z adresy w ZiB (adres/2^70)

AUTOR 
   Jacek Kobus (jkob\@fizyka.umk.pl)
  
EOF
}

$name=`basename $0`;
chop($name);

use Getopt::Std;
getopts('hu:x');

if ($opt_h) {
    usage();
}

if (! defined $ARGV[0]) {
    usage();
    exit;
} 

$command=shift;
$pid=`pgrep $command | head -1`;

sub prtf {

    my $num=shift;
    my $unit=shift;
    my $format="%16.4f";

    if ( $unit =~ /[kK]/ ) {
	$usymb="K";
	$factor=2**10;
    }

    if ( $unit =~ /[mM]/ ) {
	$usymb="M";
	$factor=2**20;
    }

    if ( $unit =~ /[gG]/ ) {
	$usymb="G";
	$factor=2**30;
    }

    if ( $unit =~ /[tT]/ ) {
	$usymb="T";
	$factor=2**40;
    }

    if ( $unit =~ /[pP]/ ) {
	$usymb="P";
	$factor=2**50;
    }

    if ( $unit =~ /[eE]/ ) {
	$usymb="P";
	$factor=2**60;
    }

    if ( $unit =~ /[zZ]/ ) {
	$usymb="Z";
	$factor=2**70;
    }

    printf "$format $usymb",$num/$factor;
}

sub hex2dec {

    my $hex=shift;
    my @hextab=split('',$hex);
    my $dec=0;
    my $power=1;
    for (my $i=$#hextab; $i>=0; $i--) {
#	print $i,": ",$hextab[$i],"\n";
	$hextab[$i] =~ s/a/10/i;
	$hextab[$i] =~ s/b/11/i;
	$hextab[$i] =~ s/c/12/i;
	$hextab[$i] =~ s/d/13/i;
	$hextab[$i] =~ s/e/14/i;
	$hextab[$i] =~ s/f/15/i;
	$dec=$dec+$hextab[$i]*$power;
	$power=$power*16;
    }

    my $format="%20.0f";
    if (defined($opt_u)) {
	prtf ($dec,$opt_u);
    } else {
	printf "$format ",$dec;
    }
}

#`pmap $pid`;

if (defined($opt_x)) {
    open (PMAP,"pmap -x $pid|") or die $!,"\n";
} else {
    open (PMAP,"pmap  $pid|") or die $!,"\n";
}

my @pmap=<PMAP>;

for (my $line=1; $line<=$#pmap; $line++) {
#    print $pmap[$line];
    if ( $pmap[$line] =~ /total/ ) {
	print $pmap[$line];
	next;
    }

    if ( $pmap[$line] =~ /Address/ ) {
	print "    ",$pmap[$line];
	next;
    }

    if ( $pmap[$line] =~ /$pid:/ ) {
	print $pmap[$line];
	next;
    }

    $pmap[$line] =~ /([01-9abcdef]+)\s(.*)/i;
    $address=$1;
    $therest=$2;
    hex2dec($address);print "  ",$therest,"\n";
}

close(PMAP);
