[net.sources] f77 cross reference mapper

silvert@dalcs.UUCP (Bill Silvert) (07/03/85)

Here are the source code and manual entry for an f77 cross reference map program
modelled on the C xref program in Bourne's book (see manual entry for more
info).  It doesn't do everything I would like, and in particular it does not
recognize assignment statements.  I tried to put this feature in, but every
time I ran into new bugs -- if anyone can do it, please send me th patch.

The Makefile tells you all you need to know about installation.  The lex
parameters are adequate for my installation, and the lex part is extremely slow
-- takes over 20 min!

Any comments and enhancements greatly appreciated.
------------ cut here ---------
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	Makefile
#	fxref
#	fxref.1L
#	fxrefa.l
#	fxrefb.c
# This archive created: Tue Jul  2 08:26:09 1985
# By:	Bill Silvert (Marine Ecology Lab.)
export PATH; PATH=/bin:$PATH
if test -f 'Makefile'
then
	echo shar: over-writing existing file "'Makefile'"
fi
cat << \SHAR_EOF > 'Makefile'
# makefile for fxref, the f77 xref program from Bourne 8.2.2

BIN = /usr/new# where the executable shell is located
LIB = /usr/local/lib# where the executable binaries are located
CFLAGS = -O
# SHELL = $(BIN)/fxref
XREFA = $(LIB)/fxrefa
XREFB = $(LIB)/fxrefb
SCCSA = s.fxrefa.l
SCCSB = s.fxrefb.c

all:
	make fxrefa fxrefb
#	make $(XREFA) $(XREFB) # $(SHELL) 

# $(SHELL): fxref
#	binstall fxref

fxrefa: lex.yy.c
	cc -O -o fxrefa lex.yy.c -ll

fxrefb: fxrefb.c
	cc -O -o fxrefb fxrefb.c

lex.yy.c: fxrefa.l
	lex fxrefa.l > lex.rec || shout lex bombed

fxrefa.l: $(SCCSA)
	get $(SCCSA)

fxrefb.c: $(SCCSB)
	get $(SCCSB)

install:
	mv fxrefa $(XREFA)
	mv fxrefb $(XREFB)
clean:
	rm -f fxrefa.l fxrefb.c lex.yy.c *.o
SHAR_EOF
if test -f 'fxref'
then
	echo shar: over-writing existing file "'fxref'"
fi
cat << \SHAR_EOF > 'fxref'
#! /bin/sh
# f77 xref based on Bourne 8.2.2
LIB=/usr/local/lib
case $# in
0)	;;
*)	case $1 in
	-w*)	arg=$1 ; shift ;;
	-*)	echo "`basename $0: do not understand $1`" ; exit 1 ;;
	*)	arg= ;;
	esac
esac
$LIB/fxrefa $* | sort -ut: +0 -1 +1 -2 +2n -3 | $LIB/fxrefb $arg
SHAR_EOF
chmod +x 'fxref'
if test -f 'fxref.1L'
then
	echo shar: over-writing existing file "'fxref.1L'"
fi
cat << \SHAR_EOF > 'fxref.1L'
.TH FXREF 1L
.SH NAME
fxref \- cross reference for f77 programs
.SH SYNOPSIS
.B fxref
[ file ... ]
.SH DESCRIPTION
.I Fxref\^
reads the named 
.I files\^
or the standard input if no file is specified
and prints a cross reference consisting of lines
of the form
.nf

	identifier	file-name	line-numbers ...
.fi
.PP
Each line number may be followed by a symbol denoting the type of usage
on that line, e.g. COMMON declaration, DATA initialization, or
subroutine CALL.  These symbols are defined in a header to the output file.
.SH EXAMPLE
.IP
fxref program.f
.PP
will return a cross reference listing of all the identifiers
in the f77 program named "program.f".
.SH FILES
/usr/{new,local}/fxref,
/usr/local/lib/fxrefa,
/usr/local/lib/fxrefb
.SH BUGS
Fxref assumes that all executable code is capitalized, which conforms to the
ANSII standard but is not the practice among f77 programmers.
Fxref does not ignore blanks as f77 does: thus VAR ONE is the same variable
as VARONE in a Fortran program, but will be treated as two variables by fxref.
Symbols which identify the type of usage are not always reliable.
.PP
It would be nice if fxref recognized assignment statements, but so far it
does not.
.SH AUTHORS
Written by William Silvert, Marine Ecology Laboratory, Dartmouth, N. S.
Based on a C cross-reference program by Steve Bourne.
Consult Bourne's book, "The UNIX System", for program details.
SHAR_EOF
if test -f 'fxrefa.l'
then
	echo shar: over-writing existing file "'fxrefa.l'"
fi
cat << \SHAR_EOF > 'fxrefa.l'
/* xref.a -- f77 cross reference mapper -- from Bourne's C xref, p. 204 */
%k 400
%a 6000
%o 6000
%n 1000
%e 2500
%p 8000
%{
static char SCCSID[] = "@(#)fxrefa.l	Ver. 2.1, 85/06/28 09:37:30";
char *filename="-";
char flag;

main(argc,argv)
	int argc;
	char *argv[];
{
	register int rc=0;
	flag = ' ';
	if(argc <= 1) {
		yylex();
	}
	else {
		while(argc > 1) {
			if(freopen(argv[1],"r",stdin)==NULL) {
				fprintf(stderr,"%s: %s: cannot open\n",
						argv[0],argv[1]);
				rc++;
			}
			else {
				filename=argv[1];
				yylineno=1;
				yylex();
			}
			argc--;
			argv++;
		}
	}
	return(rc);
}
%}
%%
AIMAG\ *"("	;
AINT\ *"("	;
CABS\ *"("	;
CCOS\ *"("	;
CEXP\ *"("	;
CLOG\ *"("	;
CMPLX\ *"("	;
CONJG\ *"("	;
CSIN\ *"("	;
CSQRT\ *"("	;
DABS\ *"("	;
DATAN\ *"("	;
DATAN2\ *"("	;
DBLE\ *"("	;
DCOS\ *"("	;
DEXP\ *"("	;
DLOG\ *"("	;
DLOG10\ *"("	;
DMAX1\ *"("	;
DMIN1\ *"("	;
DMOD\ *"("	;
DSIGN\ *"("	;
DSIN\ *"("	;
DSQRT\ *"("	;
IABS\ *"("	;
IDIM\ *"("	;
IDINT\ *"("	;
ALOG\ *"("	;
ALOG10\ *"("	;
AMAX0\ *"("	;
AMAX1\ *"("	;
AMIN0\ *"("	;
AMIN1\ *"("	;
AMOD\ *"("	;
COMPLEX	flag = 'C';
DOUBLE\ *PRECISION	flag = '#';
IMPLICIT	;
ISIGN\ *"("	;
MAX0\ *"("	;
MAX1\ *"("	;
MIN0\ *"("	;
MIN1\ *"("	;
^[C*].*\n	; /* skip comments */
"\'"	{
	while(yyinput() != '\''); /* skip quoted material */
	}
^"     "[^ ]	flag='&' ; /* continuation line */
ABS\ *"("	;
".AND."	;
ATAN\ *"("	;
ATAN2\ *"("	;
BACKSPACE	;
BLOCK\ *DATA	flag = 'h';
CALL	flag = '@';
CHARACTER	flag = '$';
CLOSE\ *"("	;
COMMON	flag = 'c';
CONTINUE	;
COS\ *"("	;
ACOS\ *"("	;
DATA	flag = 'i';
DIMENSION	flag = 'd';
DO\ /.*	;
ELSE\ *IF[ \t]*"("	flag = '?';
ELSE	;
END\ *FILE	;
END\ *IF	;
END	;
ENTRY	flag = 'h';
".EQ."	;
EQUIVALENCE\ *"("	flag =  '~';
EXP\ *"("	;
EXTERNAL	flag =  'x';
".FALSE."	;
FILE	;
FLOAT\ *"("	;
FORMAT\ *"("	;
FUNCTION	flag =  'h';
".GE."	;
GO\ *TO	;
".GT."	;
IF\ *"("	flag = '?';
IFIX\ *"("	;
INDEX\ *"("	;
INT\ *"("	;
INTEGER	flag =  '%';
INTERNAL	flag =  'p';
".LE."	;
".LGE."	;
".LGT."	;
".LLE."	;
".LLT."	;
LOG\ *"("	;
LOG10\ *"("	;
LOGICAL	flag = 'L';
".LT."	;
MAX\ *"("	;
MIN\ *"("	;
MOD\ *"("	;
".NE."	;
".NOT."	;
".OR."	;
OPEN\ *"("	flag = 'o';
PARAMETER\ *"("	flag =  'p';
PRINT	flag = '>';
PROGRAM	flag = 'h';
READ	flag = '<';
REAL	flag =  '!';
RECL	;
RETURN	;
REWIND\ *"("	;
SAVE	;
SIGN\ *"("	;
SIN\ *"("	;
SQRT\ *"("	;
STOP	;
SUBROUTINE	flag =  'h';
TANH\ *"("	;
THEN	;
TO	;
".TRUE."	;
WRITE\ *"("	flag = '>';
[0-9.]*[ED][-+0-9]*	;
[A-Z][A-Z0-9]* {
	printf("%s\t%s\t%03d%c\n", yytext, filename, yylineno, flag);
	}
.	;
\n	flag =  ' ';
SHAR_EOF
if test -f 'fxrefb.c'
then
	echo shar: over-writing existing file "'fxrefb.c'"
fi
cat << \SHAR_EOF > 'fxrefb.c'
/* second part of f77 xref program.  Developed from Bourne p. 207 */
#include <stdio.h>
static char SCCSID[] = "@(#)fxrefb.c	Ver. 2.1, 85/06/28 09:37:55";
#define MAXW 256
char	lastw[MAXW]; /* last word read */
char	lastc;

main(argc,argv)
	int argc;
	char *argv[];
{
	char f1[MAXW], f2[MAXW];
	char first=0;
	int width, col=0;

	switch(argc) {
	case 1:
		width=80; /* default */
		break;
	case 2:
		if(sscanf(argv[1], "-w%d", &width) == 1) {
			width = 5 * (width / 5);
			break;
		}
	default:
		printf("%s: illegal argument\n", argv[0]);
		exit(1);
	}
	f1[0]=0;
	f2[0]=0;

	printf("\t\t\tFlags mean:\n");
	printf("h\tprogram unit header\t");
	printf("p\tPARAMETER definition\n");
	printf("L\tLOGICAL declaration\t");
	printf("$\tCHARACTER declaration\n");
	printf("%%\tINTEGER declaration\t");
	printf("#\tDOUBLE PRECISION declaration\n");
	printf("C\tCOMPLEX declaration\t");
	printf("!\tREAL declaration  \n");
	printf("d\tDIMENSION statement\t");
	printf("c\tCOMMON statement   \n");
	printf("~\tEQUIVALENCE        \t");
	printf("i\tDATA initialization\n");
	printf("x\tEXTERNAL           \t");
	printf("?\tIF line\n");
	printf("@\tCALL               \t");
	printf("&\tcontinuation line\n");
	printf("<\tinput              \t");
	printf(">\toutput\n");
	printf("o\tOPEN statement     \n");

	while(word() != EOF) {
		if(lastw[0] != first) {
			first = lastw[0];
			printf("\n");
			col=0;
		}
		if(col >= width) {
			printf("\n                    ");
			col=20;
		}
		if(strcmp(lastw, f1) == 0) {
			word();
			if( ! strcmp(lastw, f2) == 0) {
				printf("\n          %-10s", lastw);
				col=20;
				strcpy(f2, lastw);
			}
		}
		else {
			strcpy(f1, lastw);
			printf("\n%-10s", f1);
			col=10;
			word();
			strcpy(f2, lastw);
			printf("%-10s", f2);
			col += 10;
		}
		if(lastc != '\n') {
			word();
			printf("%5s", lastw);
			col += 5;
		}
		lastc = 0;
	}
	printf("\n");
	exit(0);
}

int word()
{
	register char *p=lastw;
	register int c;

	if(lastc != '\n') {
		while((c = getchar()) != '\t' && c != '\n' && c != EOF) {
			if(p < &lastw[MAXW])
				*p++ = c;
		}
		lastc=c;
	}
	*p++ = 0;
	return(lastc);
}
SHAR_EOF
#	End of shell archive
exit 0
-- 
Bill Silvert
Marine Ecology Lab.
Dartmouth, NS
dalcs!silvert
dalcs!biomel!bill