
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		<FF>PDP-11 FORTRAN not just <FF>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 <CR> 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	<EOL>,	.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 <CR> 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.

=========================================================================
