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");

    	}

}