#!/bin/sh # # $Header: /cel/swd/usr/iag/cxref/RCS/tree.pl,v 1.2 2000/01/06 14:14:47 iag Exp $ # # Converts the cxref.function output file into a format that can display # a simple tree structure # # Warning: This is my first perl program. It can probably be improved on ! # # This file Copyright 2000 Ian A. Gilmour. # (ian@igilmour.freeserve.co.uk / ian.gilmour.ffei.co.uk) # # It may be distributed under the GNU Public License, version 2, or # any higher version. See section COPYING of the GNU Public license # for conditions under which this file may be redistributed. # exec perl -w -x $0 $* #!perl $level = 0; $func = "main"; $max_level = 3; $found = 0; # generates the tree going down # i.e. displays which functions are called by the given function # sub find_func { my $func_reqd = $_[0]; if ($level > $max_level) { return; } else { $level++; } for ($z=0; $z < ($level-1)*3; $z++) { print " "; } print "+- "; if (defined ($functions{$func_reqd})) { print "$func_reqd() \t[$file{$func_reqd}]"; if($scope{$func_reqd}==2) { print " \t(static)"; } if ($fshown{$func_reqd}) { print " \t...referenced above\n"; } else { print "\n"; $fshown{$func_reqd} = 1; for (my $y=0; $y <= $fcount{$func_reqd}; $y++) { find_func ($fcalls{$func_reqd}[$y]); } } } else { if (!defined ($fundefshown{$func_reqd})) { print "$func_reqd() \t[undefined]\n"; $fundefshown{$func_reqd} = 1; } else { print "$func_reqd() \t[undefined] \t...referenced above\n"; } } $level--; } # generates the tree going up # i.e finds which functions call the specified function # sub find_called_func { my $func_reqd = $_[0]; if ($level <= $max_level) { return; } else { $level--; } foreach my $func (keys %functions) { if (defined ($fcount{$func})) { for (my $y=0; $y <= $fcount{$func}; $y++) { if ($func_reqd eq $fcalls{$func}[$y]) { if (!$found) { $found = 1; print "+- $func_reqd()\n"; } for (my $z=0; $z > (($level)*3); $z--) { print " "; } print "+- "; print "$functions{$func} \t[$file{$func}]"; if($scope{$func}==1) { print " \t(static)"; } if ($fshown{$func}) { print " \t...referenced above\n"; } else { print "\n"; $fshown{$func} = 1; find_called_func ($functions{$func}); } } } } } $level++; if (!$found) { print "$func_reqd() not referenced.\n"; }; return; } die "Usage: $0 cxref_function_file root_function max_level\n". "max_level +ve for functions called by specified function\n". "max_level -ve for functions that call specified function\n" if($#ARGV==-1); if (defined ($ARGV[2])) { $max_level = $ARGV[2]; }; if (defined ($ARGV[1])) { $func = $ARGV[1]; }; open(FUNCTION,"<$ARGV[0]") || die "Cannot open $ARGV[0]\n"; # read all function names in once to set up database # while() { s/\%//g; s/\&//g; chop; ($file,$function,$scope,@calls)=split(/ /); if((defined ($scope)) && (($scope==2) || ($scope==1))) { $scope{$function}="$scope"; $functions{$function}="$function"; $file{$function}="$file"; if (defined (@calls)) { $fcalls{$function} = [@calls]; $fcount{$function} = $#calls; $fshown{$function} = 0; } else { $fcount{$function} = -1; } } } close(FUNCTION); # now display reqd info.... # if ($max_level >= 0) { print "Looking for functions that $func() calls...\n"; find_func ($func); } else { print "Looking for functions that call $func()...\n"; find_called_func ($func); }