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