Fortran Analysis & Refactoring with plusFORT
plusFORT, from Polyhedron Solutions, is a multi-purpose suite of tools for analyzing and improving Fortran programs. It combines restructuring and reformatting with global static analysis, dynamic analysis and many other features in a single powerful package. plusFORT is a one-stop solution for programmers, project managers, and quality assurance engineers working with Fortran source code.
- SPAG – Re-engineering Fortran source code
- Quality Assurance using plusFORT
- GXCHK – Global Static Analysis
- Dynamic Analysis
- Coverage Analysis
- AUTOMAKE – automated make for Fortran and C
- QMERGE – Version Selection
- HyperKWIC – Hyperlinked KeyWord In Context
SPAG, the plusFORT restructuring tool, can unscramble spaghetti Fortran 66 or Fortran 77 code, and convert it to modern structured Fortran 95. It also converts back and forth between standard Fortran 77, and code with Fortran 95 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.
Re-Structuring and Re-formatting
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 F95 source forms. But SPAG goes much further:
- SPAG identifies, and optionally removes dead code (statements which could never be executed) and clutter (variables or PARAMETERs which are declared but never used).
- SPAG can rewrite your declarations from scratch using either Fortran 77 or Fortran 95 notation.
- SPAG provides a simple and safe method for systematically changing the names of symbols within a program.
- SPAG allows you to specify how upper and lower case should be used to distinguish different types of symbol. For example, local variables may be lower case, PARAMETERs upper case, dummy arguments capitalised etc. (e.g. local , PARAM , Dummyarg, COMmonvar).
- SPAG generates symbol table files which are used by GXCHK, and may be used by user-written applications. For example it would be a simple matter to write a program to check conformance to local variable naming conventions. A detailed description of the symbol table format is supplied.
There are over 100 configuration options which allow you to customise SPAG output to local conventions and requirements.
Switch to Explicit Typing
SPAG allows you to switch programs to explicit typing by adding declarations for implicitly defined variables. Explicit typing, which in Fortran is normally enforced using IMPLICIT NONE, allows your compiler to detect errors which might otherwise remain undetected for years.
Switch to Fortran 95 and later
SPAG allows you to migrate your code to current Fortran standards. It can convert source form, control constructs, declaration style, relational operators, and can convert COMMON blocks to MODULEs. SPAG can detect the appropriate and insert the INTENT value for dummy arguments. In conjunction with GXCHK, the plusFORT static analysis tool, it can help you to migrate your legacy Fortran 66 or 77 code to modern modular code, which could have been written today.
- Example 1 – Before
- Example 1 – After
- Example 2 – Fortran 66
- Example 2 – Fortran 77
- Example 2 – Fortran 95
Example 1 – Original Spaghetti Code
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
Example 1 – After Processing by SPAG
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
Example 2 – Original Fortran 66.
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
Example 2 – Fortran 77 Version.
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
Example 2 – Fortran 95.
SPAG has used DO WHILE, SELECT CASE, EXIT and CYCLE.
No GOTOs or labels remain.
The COMMON block has been replaced by a MODULE, and all declarations rewritten using Fortran 95 syntax.
SUBROUTINE OBACT(Todo) USE C_EG1 IMPLICIT NONE ! !*** Start of declarations rewritten by SPAG ! ! PARAMETER definitions ! INTEGER , PARAMETER :: BASE = 10 ! ! Dummy arguments ! INTEGER,INTENT(INOUT) :: Todo ! ! Local variables ! INTEGER :: act ! !*** End of declarations rewritten by SPAG ! DO WHILE ( Todo/=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 END SUBROUTINE OBACT
plusFORT Quality Assurance
Many people know plusFORT mainly for SPAG, the restructuring tool which unscrambles spaghetti code. However, the plusFORT quality assurance facilities are arguably of even greater importance to most users.
plusFORT Version 7 is unique among QA tools in offering three distinct and complementary approaches to the problem of software quality assurance. Working together these three approaches have far more impact than any one could by itself.
QA Method 1- Global Static Analysis
GXCHK is the plusFORT global static analysis tool. GXCHK views data usage from a global perspective, and detects errors and anomalies that compilers and other tools miss. Examples are:
- Subprogram argument mismatch or misuse (e.g. constant actual argument is illegally modified by subprogram).
- COMMON and/or MODULE variables assigned a value but never used, or used but never assigned a value.
- Globally unused COMMON or MODULE variables, COMMON blocks, PARAMETERs, & INCLUDE files.
- Inconsistent COMMON block definitions.
- COMMON or MODULE variable name appears in other contexts (e.g. as a local variable, or in a different COMMON).
Version 7 of plusFORT introduces greatly improved HTML static analysis reports, with comprehensive cross- reference links. These reports are designed to act as a constant companion to coders, providing instant answers to questions like “where is this variable set” and “where is this routine called from”. A new “modularization report” shows how a traditional Fortran 77 program can be reorganised using modules and/or internal subprograms to take full advantage of the modular programming features of Fortran 95 and Fortran 2003.
An unusual feature of GXCHK is its ability to analyse local and global data together. For example, if a local variable in subprogram A has the same name as a COMMON variable in subprogram B, it could be that the programmer has omitted the relevant COMMON statement from subprogram A. GXCHK, unlike other static analysers spots this problem. GXCHK also produces a call tree, and concise but comprehensive charts showing where and how each symbol is used. Handy aggregated reports are produced for COMMON blocks and INCLUDE files.
Interface specifications for every subprogram, showing calls in and out, dummy arguments, PARAMETERs, COMMON and MODULE variables usage etc., can also be produced, and, optionally, embedded as comments back into the original source code.
GXCHK operates in a “compile & link” style which allows reports to be updated with minimal source code analysis. AUTOMAKE can be used to automate the process.
A big advantage of static analysis is that it can check all your code without regard to whether or not it is actually executed in a particular run. On the other hand, static analysis cannot take account of subtleties in program control flow, or the varying nature on input data. Neither can it cannot monitor the status of individual array elements. Arrays are treated as amorphous blobs of data.
QA Method 2 – Dynamic Analysis
If a bug is defined as “an incorrect value in a storage location” then there is a large subset (perhaps 30%) which can be defined as “an undefined value in a storage location”, and many of the remainder may cause that condition as a knock-on effect.
The Dynamic Analysis option of plusFORT is a tool for diagnosing these errors at run-time. A test version of your program is created, which detects any use of an undefined variable or array element, and logs it to a file. In other respects, the test program behaves exactly like the original. This is done by inserting calls to probe routines in the source code before any operation which depends on the value of a data item. The program is compiled and linked in the normal way, and the executable code appears to the user to operate in exactly the same way as the original. However, if a probe detects an undefined data item, it writes details to a log-file for later analysis. Source code for the probe routines is supplied.
|Feature||Static Analysis||Dynamic Analysis|
|Checks code whether or not it executes||Yes||No|
|Checks for unsafe/questionable source code||Yes||No|
|Identifies used before set error||Sometimes||Yes|
|Checks status of individual array elements||No||Yes|
|Handles dependence on external data||No||Yes|
|Effective with dummy args, EQUIVALENCE||Poor||Yes|
Dynamic analysis excels at detecting bugs which depend on external data, or on the use of arrays. These characteristics defeat conventional analysers.
QA Method 3 – Test Coverage and Hot-Spot Analysis.
A reasonable goal for a software test suite is to ensure that every line of source code is executed at least once. The plusFORT coverage analysis facility allows users to monitor progress against this goal, as well as identifying “hot-spots” – the sections of code which are executed most frequently, and which have most effect on program execution time.
The plusFORT coverage analysis facility places probes into Fortran source code which allow users to monitor the effectiveness of testing. At the end of each run, the probes update the coverage statistics for each source file. This data may be analysed at any time using the CVRANAL tool. CVRANAL identifies untested code blocks, and execution hot-spots.
In addition, CVRANAL can annotate your source code as shown below. The annotations are comments and do not affect the validity of the source code.
Software Documentation using HyperKWIC
HyperKWIC generates software documentation that combines the instant connectivity of hypertext with the analytical strengths of KeyWord In Context. It produces HTML documents that provide a fully interactive alternative to traditional documentation.
HyperKWIC is a part of the plusFORT toolkit.
- Meet requirements for accurate and complete software documentation with the aid of HyperKWIC reports which are generated automatically and quickly.
- Update as often as required, and publish to your team and to other stakeholders. HyperKWIC reports may be stored locally or published on an internal or external website.
- Impact Analysis: Even small changes to an established code base can have consequences that propagate through the entire program. With HyperKWIC you can quickly assess possible changes and produce a plan to minimize coding effort.
- Keep HyperKWIC software documentation open in your web browser for an instant answer to those constant questions:-
- where is that defined?
- which routine set that value?
- what else uses that?
- is that redundant?
- HyperKWIC is aware of programming language syntax, including comments and reserved words. Syntax rules for several common languages are defined in an external file, which may be customized as required.
- R-click to open a separate tab for reports you will need again later.