arturo@humming.UUCP (Arturo Perez) (01/24/86)
Does anyone know of programs to generate a subroutine cross-reference listing from either source code or object modules? Please reply directly to me. This is for a SysV and/or BSD UN*X machine. Thanx!
mo@wgivax.UUCP (01/25/86)
I have written two shell scripts which work with c source code.
The first merely uses sed to list the calls made in a .c file.
It should only be used with one file at a time, or embedded in
a loop which precedes it with the name of the file being listed.
Many improvements could be made to it, but here it is:
======================== list_calls ==================================
sed '
/\/\*.*\*\// s/\/\*.*\*\///g
/\/\*/,/\*\// d
/(/ !d
/(.*/ s/[a-zA-Z0-9_.]*[ ]*[(]/\
&\
/g
/[ ]/ s/[ ]//g
' $1 | sed '
/^if(/ d
/^for(/ d
/^while(/ d
/^switch(/ d
/^(/ d
/!(/ d
/(/ !d
/(/ s/(//g
/^$/ d
' | sort -u
======================================================================
the second formats the output of "cflow" (sys V) into two output files.
the file "whereis" lists each routine, the name of the source file it
is in, and the line it begins at. the file "call_tree" lists the calls
each routine makes in a hierarchically indented form. it does deal
with recursive routines.
========================= flowchart ==================================
cflow $* > /tmp/cflow.$$
fgrep : /tmp/cflow.$$ > /tmp/calls.$$
fgrep = /tmp/cflow.$$ | awk '{printf("%-10s = %-10s %-15s %5s\n",$1,$3,$4,$5)}' > whereis
tree /tmp/calls.$$ > call_tree
rm -f /tmp/cflow.$$ /tmp/calls.$$
========================= tree =======================================
#include <stdio.h>
FILE *file,*fopen();
main(argc,argv)
int argc;
char **argv;
{
if((file = fopen(argv[1],"r")) == NULL)
{
perror(argv[1]);
exit(-1);
}
trace("main",NULL);
}
static int buffer = 0;
static int first = 1;
trace(name,called_by)
char *name,*called_by;
{
int i,level;
char line[80],caller[40],callee[40];
char format[50];
long offset;
fseek(file,0,0);
while(fgets(line,80,file) != NULL)
{
offset = ftell(file);
sscanf(line,"%s : %s",caller,callee);
if(!strcmp(caller,name))
{
level = buffer;
if(first)
{
printf("main : %s\n",callee);
first = 0;
}
else
{
buffer += strlen(caller);
sprintf(format,"%%%ds : %%s\n",buffer);
printf(format," ",callee);
}
/* avoid recursive trap */
if(strcmp(callee,name) && strcmp(called_by,callee))
{
trace(callee,caller);
}
buffer = level;
fseek(file,offset,0);
}
}
}
============================================================================
Mike O'Shea decvax!mcnc!unccvax!wgivax!mo