Fortran Tools on the Spring 81 tape. ------------------------------------ The following is a short survey of programs on recent RSX SYMPOSIUM TAPES (mainly 1981 Spring), concentrating on those programs which may be of special use in debugging fortran software. In each case the programs have been made to run under my 11M+ system, all of the source code analysis programs were fed the same (arbitrary) fortran source program, while all of the binary debugging aids were tested only on trivial programs with integer, real and character types. The patches needed to any of the programs to make them useable have been appended to the notes on each of them. Remember that any copies of these found on symposium tapes will be unpatched. Richard James D Kirkman. ------------------------------------------------------------------------- [330,11] RESEQ - A program to resequence F4P programs. This program allows a choice of the justifictaion of the resulting statement numbers, and the choice of preserving the distinctions between several different blocks of statement numbers. As distributed there are no default extensions for files, lower case keywords are ignored, and floating overflows will occur when a constant (for example a floating point denotation ) contains more than 9 successive digits. Most of these problems are resolved in the attached correction file for the main module. RESEQ.FTN/-AU/-BF=RESEQ.FTN;-1 -30 C RJDK - 6 september 81 - Handle lower case i/p C fix bugs when reading text containing long constants -38 INTEGER UC -105,105 110 CALL SETEXT(FILEI(1,1)) CALL SETEXT(FILEO(1,1)) OPEN(UNIT=1,NAME=FILEI(1,1),TYPE='OLD',READONLY,SHARED) -138,138 IF(UC(IN(1)).NE.68)GO TO 200 -168,168 IF(UC(IN(NP)).NE.JIF(I))GO TO 260 -176,176 ICUR=UC(IN(I)) -201,201 IF(UC(IN(1)).NE.68)GO TO 310 -216,216 350 ICUR=UC(IN(NX)) -231,231 INI=UC(IN(J)) -249,249 400 ICUR=UC(IN(NX)) -261,261 ICUR=UC(IN(I)) -277,277 IF(UC(IN(NT)).NE.RR(J))GO TO 490 -283,283 ICUR=UC(IN(NT)) -299,299 IF(UC(IN(NT)).NE.ND(J))GO TO 510 -310,310 IF(UC(IN(NX)).EQ.69)GO TO 450 -317,317 ICUR=UC(IN(NX)) -337,337 ICUR=UC(IN(NT)) -370,370 650 ICUR=UC(IN(IS)) -384,384 IF((IN(IS)).NE.72)GO TO 650 -400,400 ICUR=UC(IN(NX)) -405,405 ICUR=UC(IN(IBEG)) -463 INTEGER UC -477,477 30 IF(UC(IN(1)).NE.68)GO TO 40 -503,510 INTEGER UC COMMON/RESBUF/IN(80) DATA JEND/69,78,68/ LAB=0 IF(UC(IN(1)).NE.67)GO TO 30 ITYPE=3 IBEG=1 DO 10 I=80,2,-1 ICUR=UC(IN(I)) -519,519 ICUR=UC(IN(I)) -524,524 50 ICUR=UC(IN(I)) -531,531 ICUR=UC(IN(I)) -545,545 IF(UC(IN(I)).NE.JEND(J))RETURN -561 INTEGER UC -569,569 10 ICUR=UC(IN(L)) -576,576 ICUR=UC(IN(K)) -581,582 ICUR=UC(IN(IE-1)) IF(UC(IN(IE)).NE.72.OR.ICUR.LT.48.OR.ICUR.GT.57)RETURN -588,590 IF(UC(IN(L)).NE.72)GO TO 10 L=L+N+1 IF(UC(IN(L)).GT.72)GO TO 20 -600,600 C ** RJDK** stop conversion errors when accidentally reading FP numbers to C simply skip them. C INTEGER NDIG !RJDK statement labels are 5 chars only -605,608 NDIG=0 !start with none DO 10 K=I,J ICUR=IN(K) IF(ICUR.LT.48.OR.ICUR.GT.57)GO TO 20 NDIG=NDIG+1 IF(NDIG.GT.5)GOTO 10 N=10*N+ICUR-48 10 CONTINUE -652 INTEGER UC -672,672 20 IF(UC(IN(NPT)).NE.IS(IPT))GO TO 40 -817 SUBROUTINE SETEXT(B) BYTE TEXT(40) BYTE B(40) J=0 DO 10 I=1,40 IF(B(I).EQ.0)GOTO 100 IF(B(I).EQ.';')J=I IF(B(I).EQ.'.')RETURN 10 CONTINUE RETURN 100 IF(J.EQ.0)GOTO 200 DO 110 K=J,I TEXT(K-J+1)=B(I) 110 CONTINUE B(J)='.' B(J+1)='F' B(J+2)='T' B(J+3)='N' DO 120 K=1,I-J+1 B(J+K+3)=TEXT(K) 120 CONTINUE RETURN 200 B(I)='.' B(I+1)='F' B(I+2)='T' B(I+3)='N' B(I+4)=0 RETURN END INTEGER FUNCTION UC(B) BYTE B UC=B IF(B.GT.96.AND.B.LE.122)UC=B-32 RETURN END / -------------------------------------------------------------- [373,12] XRF - A Fortran Cross-referencer. This program produces a cross reference listing of the uses of identifiers in a each module of a fortran program. The line numbers output correspond to those of an F4P listing. The cross reference generated is of references internal to a module, and not for the whole of the input file. As distributed the program copes correctly with lower case input, but has a bug in the treatment of ACCEPT and TYPE statements, causing syntax error messages to be output if the format used is "*" and no variables are used, e.g. TYPE*,'29-JUN-81 version' XREF.FTN/-BF/-AU=XREF.FTN;-1 -182,184 60 GOTO 90 !due to type*, number need not be present C NSYMTP=NXTSYM(BCHR) !GET FORMAT NUMBER C IF(NSYMTP.EQ.0) GOTO 96 !SHOULD HAVE FORMAT SPEC C GOTO 91 !ENTER FORMAT NUMBER---AND SCAN REST / --------------------------------------------------------------------- [360,213] UND - A program to detect undefined variables. Although billed as a program to detect undefined variables, this actually can only detect variables which are never assigned a value, and variables it is unable to determine the state of. Despite this restriction it looks likely to be very useful. The program reads an F4P listing file to determine the allocation of variables, and as distributed is intended for IAS using F4p v2.51. For RSX systems it is necessary to use SPAWN to call the F4P compiler, to produce a listing file for analysis, unless a listing file is explicitly provided by the user. The following patch will cause the program to translate its command line to upper case, use RSX SPAWN directives, accept lower case input (and not be woried by the fact that header and trailer lines of some versions of F4P differ in case and exact layout). UNDMN.FTN/-AU/-BF=UNDMN.FTN;-1 -40 C RJDK 5-SEP-81 VERSION FOR F4P ON 11M/11M+ SYSTEMS C C 1) USE SPAWN, NOT IAS SUBTASK C 2) USE LOGICAL FUNCTION STRCON(TEXTBF,'...') C INSTEAD OF ASSUMING EXACT FORMAT & CASES C TO CATER FOR HEADINGS SUCH AS C PDP-11 FORTRAN not just FORTRAN C and Total Space not just TOTAL SPACE C 3) CONVERT ALL INPUT INCLUDING COMMAND LINE TO UPPER CASE C C -46 INTEGER MCR(2),IDS,IESB(8),IEFN !RJDK LOGICAL STRCON -74,75 DATA CMD/ 'F4P ,X.T', 'MP/-SP/L' , 'I:2= ', 7*' '/ C DATA CMD/FOR ,X.TMP/-SP/LI:2= / DATA IEFN/16/,MCR/3RMCR,3R.../ -100 CALL UPPER(FNAME,35) -181,185 C CALL DECTDB(1) ! DECLARE TDB C CALL RUNTS(BUF,1,2,,'WAIT') ! SUBTASK FORTRAN COMPILER, C WAIT FOR ITS TERMINATION C CALL RDETS(ISTAT,1) ! FIND OUT EXIT STATUS C CALL RELTDB(1) ! RELEASE TDB C**RJDK** Modified for M/Mplus Spawn CALL SPAWN(MCR,,,IEFN,,IESB,,CMD,NTOTCH-1,,,IDS) IF (IDS.NE.1)STOP 'Spawn error' CALL WAITFR(IEFN) ISTAT=IESB(1) ! get status C** End of M/Mplus patch -228,233 CALL UPPER(LINE,132) NL=NL+1 CALL STRIP(LINE) IF (NL-2) 60,40,80 60 IF(.NOT.STRCON(LINE,FORT,7))GOTO 410 ! RJDK C DO 65 N=1,7 C IF (LINE(N+1).NE.FORT(N)) GO TO 410 C65 CONTINUE -271,274 CALL UPPER(LINE,132) CALL STRIP(LINE) IF(.NOT.STRCON(LINE,VARI,9))GOTO 110 C DO 120 N=1,9 C IF (LINE(N).NE.VARI(N)) GO TO 110 C120 CONTINUE -282 CALL UPPER(LINE,132) -293,295 C DO 131 I = 1,7 C IF (LINE(I+1) .NE. FORT(I)) GOTO 133 C 131 CONTINUE IF(.NOT.STRCON(LINE,FORT,7))GOTO 133 -308,310 134 IF(.NOT.STRCON(LINE,ARRY,6))GOTO 140 C DO 135 N=1,6 C IF (LINE(N).NE.ARRY(N)) GO TO 140 C135 CONTINUE -316,318 140 IF(.NOT.STRCON(LINE,LABL,6))GOTO 146 C DO 145 N=1,6 C IF (LINE(N).NE.LABL(N)) GO TO 146 C145 CONTINUE -325,327 C 146 DO 147 N = 1,9 C IF (LINE(N) .NE. FUNC(N)) GO TO 148 C 147 CONTINUE 146 IF(.NOT.STRCON(LINE,FUNC,9))GOTO 148 -337,339 C DO 149 N = 1,11 C IF (LINE(N) .NE. TOTL(N)) GOTO 130 C 149 CONTINUE IF(.NOT.STRCON(LINE,TOTL,11))GOTO 130 -506,509 CALL UPPER(LINE,132) CALL STRIP(LINE) C DO 405 N=1,7 C IF (LINE(N+1).NE.FORT(N)) GO TO 400 C405 CONTINUE IF(.NOT.STRCON(LINE,FORT,7))GOTO 400 -517 LOGICAL FUNCTION STRCON(LINE,TEXT,LEN) BYTE LINE(132),TEXT(LEN) DO 100 I=1,132 IF (LINE(I).EQ.0)GOTO 101 100 CONTINUE I=132 101 DO 102 J=1,I-LEN+1 DO 103 K=1,LEN IF(LINE(J+K-1).NE.TEXT(K))GOTO 104 103 CONTINUE STRCON=.TRUE. GOTO 200 104 CONTINUE 102 CONTINUE STRCON=.FALSE. 200 CONTINUE C TYPE300,STRCON,TEXT C TYPE301,(LINE(I),I=1,20) C300 FORMAT(' ',L2,40A1) C301 FORMAT(' ',20A1) RETURN END SUBROUTINE UPPER(BUF,L) BYTE BUF(L) DO 100 I=1,L IF(BUF(I).GT.96.AND.BUF(I).LE.122)BUF(I)=BUF(I)-32 100 CONTINUE RETURN END / ------------------------------------------------------------------ [302,304] INDEX - A fortran cross referencer. This is an all singing, all dancing cross reference processor. There is an assembly option for a subset to run under RT11. The program was the only one of those tested to accept lower case input, but even so needs corrections for cases where input does not immediately generate ouput. It also has to be corrected to allow the merging of cross references with compiler listing files containing TOTAL SPACE not in upper case only (eg F4Pv3). It can cater for FOR, F4P and F77 sources. It can produce call reference tables, tables of where common variables are used, as well as module by module cross references. Under RSX you are recommended to remove the EXTSCT line from the taskbuilder command file, and link to an FCSRES/FCSFSL if available. The program is in MACRO11, and is flat, using EXTK$ to extend its symbol tables. This program is highly recommended, as it gives considerably more functionality than XRF. OUTPUT.MAC/-AU/-BF=OUTPUT.MAC;-1 -17 ; RJDK - ATMOS - OXFORD 7-SEPT-81 ; ; Correct for F4P v3 which outputs Total Space not TOTAL SPACE ; -56,56 CMP LBUFF,#"TO ;Was it TOTAL SPACE allocated? BEQ 30$ ; - Yes F4Pv2.51 .ENABL LC CMP LBUFF,#"To ;Was it Total Space allocated .DSABL LC ;If not then not F4Pv3.0 / IOLINE.MAC/-AU/-BF=IOLINE.MAC;-1 -1 ; ; 7-Sept-81 RJDK - ATMOS , OXFORD. ; ; Correct bug where lower case was only converted to upper case if a ; listing file was being generated directly. ; -104,104 1$: MOV R0,-(SP) ; Save R0 MOV R1,-(SP) ; and R1 2$: MOVB (R0)+,R1 ; get the next character BEQ 3$ CMPB R1,#141 ;lower case BLO 2$ ; - no try next CMPB R1,#172 ;lower case? BHI 2$ ; - No get next SUB #40,R1 ;make it upper MOVB R1,-1(R0) ;and store back BR 2$ 3$: MOV (SP)+,R1 ;restore register MOV (SP)+,R0 ; RTS PC / -------------------------------------------------------------------- Fortran IV Plus debugging utilities ----------------------------------- [312,315] FPODT+PREPRC This is a fairly small and simple debugging tool for F4P programs. It is used by compiling the fortran program (modified by inserting a CALL FPODT statement at its head) with /TR:ALL, and then linking with the module FPODT.OBJ to produce TSK and MAP files. The pre- processor is run to read the MAP file and replace all references to $SEQC (the line number) by TRAP instructions. When the task is then run the routine FPODT sets up a TRAP SST trap and gains control at each point where $SEQC changes. The taskbuilder map is needed to reference variables other than those in psect $VARS (not commons or parameters) and there seems to be no way to access the values in the parameter list. Variables can be printed at any point in REAL, Decimal, Octal, Ascii and LOGICAL forms. To determine where the variable is, it is necessary to consult the taskbuilder map and the compiler listings. The actions available are setting breakpoints, stepping a number of lines of fortran, or until a breakpoint, and exiting. Known bugs/problems. Access to parameters of routines is not possible(?). Cannot use /MU task to gain code/preset write protection (the preprocessor cannot cope with that format task image). The preprocessor only accepts 6 character tasknames. Needs the program to be modified (CALL FPODT inserted). --------------------------------------------------------------------- [330,2] and [312,315] FDT + FDTSYM This debugging tool is rather closer to DDT than ODT. It uses a preprocessor reading compiler listing files (/LI:3) to determine the locations of variables and their types, and the taskbuilder map file to determine their actual locations. The preprocessor can then generate a binary file for the debugger and a listing of the addresses of all symbols. When the users program is linked with FDT/DA, FDT is entered and prompts for the name of this symbol table. It then allows the setting and clearing of breakpoints at linenumbers or statement labels in routines, and the examination of variables by name. Variables are always printed in their own types, except that integers may be printed in Octal and Decimal, and any variables may be printed in Ascii. I found a few minor bugs under RSX11M+, the most obvious things lacking are the ability to print the values of all known variables and the ability to step some number of instructions. However I recommend this to people working with F4P under RSX. FDT.MAC;2/-AU/-BF=FDT.MAC;-1 -51 ; RJDK 8-Sep-81 RSX11M+ always sets general register set 0 when ; entering a supervisor mode library. This causes the loss of all ; argument pointers if they were in set 1. ; How 11M behaves with register set 1 selected I dont know, but its ; safer to use set 0 on an 11M system. ; ; 9-Sep-81 ; Attach the terminal to allow typeahead, prevent character loss. ; Output on ;G command to put user back at start of line ; (Note future need for: S - Step n statements ; T - Print table of variables ; Catching task abnormal exits ; ) ; ; ; Stop using G15.7 for real and complex inputs since this makes ; 1E1 = 1.00000E-05 ; ; use G25.0 instead on input. ; ; reduce number of wasted lines by making EOL->CR only ; ; ; -67,67 RSX11M = 0 ;DEFINE RSX11M IF NOT IAS -133,133 .IIF NB , .BYTE 15 -341,346 ;3$: ; JMP RETRN. ;EXIT ON ASSIGN ERROR ; If the assign failed there is no TI:. Since we havent initialised ; the OTS we had better not use our current SAVPC. For the moment ; we will assume the world has fallen in and give up. HALT ;assume the world died 4$: MOV #OPQIO+Q.IOFN,R0 ;Get a QIO function code address MOV (R0),-(SP) ;save this for a bit MOV #IO.ATT,(R0) ;Do attach now DIR$ #OPQIO MOV (SP)+,(R0) ;restore function code OTSINI ;INITIALIZE FORTRAN OTS CALL FPSAVE ;SAVE FLOATING POINT REGS FOR FORTRAN TYPES BOL,<'FDT - ICR003/RKS - 12-NOV-80 RJDK 9-SEP-81'>,EOL -408 MOV #15,R0 ;Emit so users fortran i/o is ok CALL TYPE. ;output CALL FLUSH. ;from buffering -917 CMP #FORMR4,(SP) BNE 26$ ;convert to other Real i/p format MOV #FORMIR,(SP) 26$: -1126,1127 FORMIR: ;added format for input of reals and ;altered complex input format FORM 1,G,25,0 FORM ,FIN FORMIC: ;INPUT FORMAT FOR COMPLEX FORM 2,G,25,0 -1150,1150 TYPES BOL,'\\' ;TYPE ERROR -1683,1683 SAVR0: .WORD 0,0,0,0,0,0,0 ;REGISTER SAVE BUFFER .IF DF RSX11M .WORD 170000 ;Prev=Cur= User .IFF .WORD 174000 ;PREV=CUR=USER + REGSET1 .ENDC / ---------------------------------------------------------------- SPRING79 RSX TAPE [346,100]FODT - FORTRAN IV DEBUGGING TOOL. This is the predecessor of FPODT above. Because of the threaded code nature of the output of FOR it need not be specified as a debugging aid, just used as one of the input modules. This module replaces some of the normal fortran OTS routines, mainly those concerned with stepping to the next instruction and traceback handling. As such it requires no source or OBJ level changes, but may be difficult to link to a resident library. I have tested this with a fairly old FOR v2 compiler and its only problems are a tendency to exit on odd address or similar traps, if the addresses being examined are wrong. The main features offered are stepping a number of statements, up to 8 breakpoints, and variable examination. A compiler listing with storage offsets is necessary to determine the locations being examined. =========================================================================