[net.unix] cross reference generator

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