Fax: +44(0)1865 300 232
SPAG, the plusFORT restructuring tool, can unscramble spaghetti Fortran 66 code, and convert it to structured Fortran 77. It also converts back and forth between standard Fortran 77, and code with VAX and Fortran 90 extensions such as DO WHILE, ENDDO, CYCLE, EXIT and SELECT CASE.
SPAG does not change the meaning of a program, or even the order in which statements are executed; it does change the way the program logic is written down, making it much easier to understand and maintain. Blocks of code are reordered so that logically related sections are physically close, and jumps in control flow are minimised. SPAG may also replicate small code fragments where this improves the re-structured code. SPAG computes complexity metrics before and after restructuring.
*** NEW *** SPAG is now available to use on-line. Click here for further details
SPAG contains a powerful code beautifier, with dozens of options controlling spacing, case, labels, indentation, use of CONTINUE etc. You can use SPAG to switch back and forth between the F77 and F90 source forms. But SPAG goes much further:
There are over 100 configuration options which allow you to customise SPAG output to local conventions and requirements.
Example 1 - Before
Example 1 - After
Example 2 - Fortran 66
Example 2 - Fortran 77
Example 2 - Fortran 90
IBON=0
IF(KON)35,19,35
19 IF(NSQ-56)24,22,24
22 IF(LSQ-46)5,28,5
24 IF(NSQ-55)29,27,29
27 IF(LSQ-45)5,28,5
28 IBON=2
GO TO 5
29 IF(LSQ-32)30,31,30
30 IF(LSQ-39)39,31,39
31 IBON=-5
GO TO 5
39 IF(LSQ-35)52,51,52
52 IF(LSQ-36)5,51,5
51 IBON=10
GO TO 5
35 IF(MARK(NMOVE))36,37,37
36 IBON=-5
GO TO 5
37 IBON=5
5 end
ibon = 0
IF ( kon.NE.0 ) THEN
IF ( mark(nmove).LT.0 ) THEN
ibon = -5
ELSE
ibon = 5
ENDIF
ELSEIF ( nsq.NE.56 ) THEN
IF ( nsq.NE.55 ) THEN
IF ( lsq.EQ.32 ) THEN
ibon = -5
ELSEIF ( lsq.EQ.39 ) THEN
ibon = -5
ELSEIF ( lsq.EQ.35 ) THEN
ibon = 10
ELSEIF ( lsq.EQ.36 ) THEN
ibon = 10
ENDIF
ELSEIF ( lsq.EQ.45 ) THEN
ibon = 2
ENDIF
ELSEIF ( lsq.EQ.46 ) THEN
ibon = 2
ENDIF
END
This subroutine picks off digits from an integer and branches depending on their value.
SUBROUTINE OBACT(TODO)
INTEGER TODO,DONE,IP,BASE
COMMON /EG1/N,L,DONE
PARAMETER (BASE=10)
13 IF(TODO.EQ.0) GO TO 12
I=MOD(TODO,BASE)
TODO=TODO/BASE
GO TO(62,42,43,62,404,45,62,62,62),I
GO TO 13
42 CALL COPY
GO TO 127
43 CALL MOVE
GO TO 144
404 N=-N
44 CALL DELETE
GO TO 127
45 CALL PRINT
GO TO 144
62 CALL BADACT(I)
GO TO 12
127 L=L+N
144 DONE=DONE+1
CALL RESYNC
GO TO 13
12 RETURN
END
In addition to restructuring, SPAG has renamed some variables, removed the unused variable IP, inserted declarations, and used upper and lower case to destinguish different types of variable.
SUBROUTINE OBACT(Todo)
IMPLICIT NONE
C*** Start of declarations inserted by SPAG
INTEGER act , LENgth , NCHar
C*** End of declarations inserted by SPAG
INTEGER Todo , DONe , BASE
COMMON /EG1 / NCHar , LENgth , DONe
PARAMETER (BASE=10)
100 IF ( Todo.NE.0 ) THEN
act = MOD(Todo,BASE)
Todo = Todo/BASE
IF ( act.EQ.1 .OR. act.EQ.4 .OR.
& act.EQ.7 .OR. act.EQ.8 .OR.
& act.EQ.9 ) THEN
CALL BADACT(act)
GOTO 200
ELSEIF ( act.EQ.2 ) THEN
CALL COPY
LENgth = LENgth + NCHar
ELSEIF ( act.EQ.3 ) THEN
CALL MOVE
ELSEIF ( act.EQ.5 ) THEN
NCHar = -NCHar
CALL DELETE
LENgth = LENgth + NCHar
ELSEIF ( act.EQ.6 ) THEN
CALL PRINT
ELSE
GOTO 100
ENDIF
DONe = DONe + 1
CALL RESYNC
GOTO 100
ENDIF
200 RETURN
END
SPAG has used DO WHILE, SELECT CASE, EXIT and CYCLE. No GOTOs or labels remain.
SUBROUTINE OBACT(Todo)
IMPLICIT NONE
C*** Start of declarations inserted by SPAG
INTEGER act , LENgth , NCHar
C*** End of declarations inserted by SPAG
INTEGER Todo , DONe , BASE
COMMON /EG1 / NCHar , LENgth , DONe
PARAMETER (BASE=10)
DO WHILE ( Todo.NE.0 )
act = MOD(Todo,BASE)
Todo = Todo/BASE
SELECT CASE (act)
CASE (1,4,7,8,9)
CALL BADACT(act)
EXIT
CASE (2)
CALL COPY
LENgth = LENgth + NCHar
CASE (3)
CALL MOVE
CASE (5)
NCHar = -NCHar
CALL DELETE
LENgth = LENgth + NCHar
CASE (6)
CALL PRINT
CASE DEFAULT
CYCLE
END SELECT
DONe = DONe + 1
CALL RESYNC
ENDDO
RETURN
END