Listing 7.
A SWIG-enabled top emulator
Scott Bolte
SWIG
The Perl Journal, Winter 1997
  A SWIG-enabled top emulator

#!/usr/bin/perl -w



use strict;

use Top;        # treated like any other module



sub memfix ($) {

        my $label = shift;

        if ($label =~ m/(\d+)K/ && $1 > 8192) {

                        my $M = int($1 / 1024);

                        $label =~ s#$1K#${M}M#;

        }

        return $label;

}



sub names ($) {

        my $ref   = shift;

        my @names = ();

        for(my $i = 0; $val ne "NULL"; $i++) {

                        my $val = Top::ptrvalue($ref, $i);

                        push(@names, $val);

        }

        return(@names);

}



my $clear = 'clear';

# contains the OS specific field names

my($statics) = new statics();

# contains the raw system information

my($si)      = new system_info();

# used to store process information

my($ps)      = new process_select(); 

$ps->{idle}       =  1;

$ps->{"system"} =  0;

$ps->{uid}         = -1;



# Extract field names from their respective null-terminated lists.

Top::machine_init($statics);

my(@procstates) = names($statics->{procstate_names});

my(@cpustates)  = names($statics->{cpustate_names});

my(@memory)     = names($statics->{memory_names});



# We'll emulate top's basic display sixty times.

Top::get_system_info($si);

for (1 .. 60) {

        sleep(1);



        # Get the info and clear the screen

        Top::get_system_info($si);

        my $handle = Top::get_process_info($si, $ps);

        print $clear;



        # "load averages:  0.02,  0.05,  0.01  20:43:09"

        print("load averages");

        for my $i (0 .. 2) {

            my $value =Top::ptrvalue($si->{load_avg},$i);

                printf("%s %5.2f", $i == 0 ? ":" : ",", $value);

        }

        printf("\t\t\t\t      %2d:%02d:%02d\n", 

                              reverse((localtime())[0..2]));



        # "34 processes: 1 running, 32 sleeping, 1 stopped"

        printf("%d processes: ", $si->{p_total});

        for my $i (0 .. $#procstates) {

           my $value = Top::ptrvalue($si->{procstates},$i);

            next        unless $value;

            printf("%d%s", $value, $procstates[$i]);

        }

        print("\n");



        # "CPU states:  2.3% user,  0.0% nice,  1.5% system,  

        # 0.0% interrupt, 96.2% idle"

        my $sum = 0;

        for my $i (0 .. $#cpustates) {  

                    $sum += Top::ptrvalue($si->{cpustates}, $i) }

        $sum /= 100.0;

        for my $i (0 .. $#cpustates) {

            my $percent = Top::ptrvalue($si->{cpustates},$i)/$sum;

               my $value  = $percent == 100.0   ? "100" : 

                                         sprintf("%4.1f", $percent);  

               printf("%s %4s%% %s", $i == 0 ? "CPU states:" : ",", 

                      $value, $cpustates[$i]);

        }

        print("\n");



        # "Mem: 25M Active, 3752K Inact, 14M Wired, 8M Cache, 

                #  7323K Buf, 8M Free"

        print("Mem: ");

        for my $i (0 .. $#memory) {

                        my $value = Top::ptrvalue($si->{memory},$i);

                        next    if $value == 0;

                        print(memfix("$value$memory[$i]"));

        }

        print("\n");



        # "29938 root   28   0  1204K  1648K RUN   

        #  0:00 20.31%  0.99% perl"

        print("\n");

        print(Top::full_format_header("USERNAME"), "\n");

        for my $p (1 .. $si->{p_total}) {

            print(Top::full_format_next_process($handle), "\n");

        }

}