GXCHK takes the symbol tables written by SPAG and combines them to form a global view of data usage within a program. The output takes the form of an HTML document (see Figure 1) with hyperlinks providing access both to global reports, and detailed summaries for individual symbols. The report is designed to assist in quality assurance, but is also a valuable in coding and debugging: for example it allows programmers to determine with a single click where particular variables are used and/or set.
You can familarize yourself with the interface by playing with with a fully functional sample report online here.
The first two GXCHK Reports identify errors and other possibly anomalous conditions. Many of these are not clear errors in that they do not necessarily violate the Fortran standard. However, they may indicate a cause for concern. If, after inspection, they appear benign, the messages can be selectively suppressed by settings in the configuration file. The conditions reported include:
Subsequent reports contain documentation of the program, including charts showing where and how each symbol is used. For example, these charts could be used to identify which subprograms modify a particular COMMON variable, and which use it without changing it. A separate report is produced for each type of symbol (subprograms, INCLUDE files, COMMON blocks, COMMON variables, MODULEs, MODULE variables and PARAMETERs). Also included is a CALL tree (see Figure 2), and a Modularization Report, which shows how a legacy Fortran 77 style program with COMMON blocks and a large number separately compiled subprograms, could be organized into a smaller number of modules reflecting the underlying structure (see Section 3.7) .
Wherever a symbol name is shown in one of the GXCHK HTML reports, a link to a summary report for the individual symbol is available. The summary report shows everything that GXCHK knows about the symbol, including any errors relating to it. By default the report appears in the right hand pane, but many browsers allow you to route the report to a different tab or window. Often, this is done by right-clicking on the link, and selecting the destination from a menu. This can be very useful to keep commonly used "per symbol" or other reports easily accessible.
An example "Per Symbol" Report is show below:
In addition to the interactive reference mode described above, GXCHK may also embed a block of comments containing a summary of the interface of each subprogram into the restructured code produced by SPAG. This summary includes lists of calls from and to this subprogram, COMMON and MODULE variables used and/or modified, dummy arguments, local variables and PARAMETERs.
For example, for the case shown in Figure 3, GXCHK may be instructed to insert the block of comments following "IMPLICIT NONE" below into the source code
SUBROUTINE WAKE_TURB(Kstinp,Lrurl,Xinp,L,Rinp,Tiz,Tiy) USE MAIN1 IMPLICIT NONE !*--******************************************************************** !A UNUSED - KSTINP !A UNUSED - LRURL !A INPUT - XINP !A INPUT - L !A INPUT - RINP !A OUTPUT - TIZ !A OUTPUT - TIY ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! calls ** NOTHING ** ! called by WAKE_DFSN WAKE_DFSN2 ! modifies ** NOTHING ** ! uses value /DFSN/ DUA_UA SVEFF SWEFF UEFF WFY ! WFZ WIY0 WIZ0 XDECAY ! local vars AMBIY AMBIZ FARIY FARIZ ONE XFAC ! XFRAC XML ZERO ! uses PARAMs *** NONE **** !*++********************************************************************
GXCHK is also used to make final adjustments to the source code of the main program prior to a dynamic analysis run. See Section 2.8 for a discussion of dynamic analysis.
To start a run, simply type gxchk followed by the name of the symbol table file(s) you wish to process. You can use wild-cards to specify more than one file. For example:
gxchk a*.smb b*.smb
processes the contents of all files in the current directory which fit either wildcard.
Under Windows, .smb is assumed if no extension is specified (b* is treated as b*.smb). The default file name is *.smb. Thus, if you just type gxchk, all .smb files in the current directory are processed.
On Linux and Mac, the extension must be specified, and there is no default file name.
The operation of GXCHK may be modified by command line switches. Currently the following switches are available:
FIG= |
specifies the configuration file name (see section 3.3). If you don't specify a file name in this way, GXCHK assumes that the configuration file is in a file called gxchk.fig. In either case, the search rules defined in section 1.4 are followed. If no configuration file can be found, GXCHK uses internal defaults for all configuration items. If a '?' is appended (e.g. FIG=GXCHK.FIG? or FIG=?), GXCHK lists the contents of the active configuration file to the screen, with a pause after each screen full. |
nnn= |
specifies the value of item nnn in the GXCHK configuration file (see section 3.4). Items specified in this way over-ride those read from the configuration file. This is particularly useful for switching individual errors on and off. |
HTML= |
specifies the name of the file to which the main GXCHK HTML reports are sent. The default file name is gxchk.htm. |
TITLE= |
specifies a title to be used if possible to identify the browser tab containing the report. The default is "GXCHK Analysis" |
TO= |
specifies the name of a text file to which a version of the GXCHK output reports are sent. The default file name is gxchk.out. The text version does not contain all of the reports available in HTML. |
For example
gxchk a*.smb html=gxmary.html fig=gxmary.fig 311=1 321=1
This command causes GXCHK to analyze all files in the current directory whose name fits the template a*.smb. Configuration options are read from gxmary.fig, but the controls on records 311 and 321 are both set to 1. The HTML report is sent to gxmary.html.
The GXCHK configuration file has the same general format as the SPAG configuration file (see Section 2.5). The item numbers for GXCHK are in the range 300-450, and all items are integers. There is no overlap between GXCHK and SPAG item numbers.
An example configuration file is shown below. The meaning of each data item is explained in detail in the next section. The values shown in this example are, in fact, the defaults which are used by GXCHK if no configuration file is found.
============================ GXCHK controls ================================== 302=2 0 - unicode text reports 1 - ASCII text reports 2 - unicode text and HTML reports 3 - ASCII text and HTML reports 304=78 target width of output reports (some records excced target) 305=0 used to economise on storage/time in GXCHK 0=keep everything 1=keep all except local variables 2=keep sub-programs & COMMON blocks 3=keep sub-programs only 306=0 0=batch operation 1=interactive operation 308=0 0=no subroutine interface summaries 1=embed summaries in SPAGged code 309=0 0=no preparation for dynamic analysis 1=prompt to modify main program 2=modify main program - no prompt ====================== Controls on Error Reporting =========================== (see also 401-450) 311=2 0=no errors relating to sub-programs 1=one line message 2=verbose 312=2 0=no errors relating to COMMON blocks 1=one line message 2=verbose 313=2 0=no errors relating to INCLUDE files 1=one line message 2=verbose 314=2 0=no errors relating to COMMON variables 1=one line message 2=verbose 315=2 0=no errors relating to PARAMETERs 1=one line message 2=verbose 316=1 0=no type check of subprogram arguments 1=argument type checking 317=2 0=no errors relating to MODULE variables 1=one line message 2=verbose 318=0 0=assume default type lengths throughout 1=only for dummy args =================== Controls on Cross Reference Reports ====================== 320=1 0=no sub-program index 1=index of sub-program source code 321=1 0=no sub-program reports 1=where called 322=3 0=no COMMON block reports 1=where modified 3=where referenced 323=3 0=no INCLUDE file reports 1=where modified 3=where referenced 324=3 0=no COMMON variable reports 1=where modified 3=where referenced 325=1 0=no PARAMETER reports 1=where used 326=3 0=no MODULE reports 1=where modified 3=where referenced 327=3 0=no MODULE variable reports 1=where modified 3=where referenced 329=1 0=no Modularization report 1=Modularization report 330=1 0=no CALL tree 1=minimal CALL tree 2=show unresolved references 3=expand every occurrence of every reference 331=0 0=full X-ref charts 1=suppress 'var not used' in X-ref charts 332=0 0=keep all branches 1=suppress 'orphan' branches in CALL tree 350=1 0=no per symbol reports 1=per symbol HTML reports ================== Controls on Individual Error Messages ===================== 0 to suppress >0 specifies severity 401=1 Subprogram used but not defined 402=4 Subprogram defined more than once 403=2 Subprogram defined but not used 404=4 Subprogram used in conflicting ways 405=4 Subprogram has varying argument counts 406=4 Subprogram has varying result types 407=2 Subprogram name is used in other contexts 408=2 Subprogram is called recursively (if 330>0) 409=8 410=8 411=3 COMMON block has varying component counts 412=2 COMMON is defined in and out of INCLUDE file 413=2 COMMON is defined in different INCLUDE files 414=2 nothing in COMMON block is ever referenced 415=2 COMMON block name is used in other contexts 416=3 COMMON block defined with varying sizes 417=1 COMMON not in MAIN (for dynamic analysis) 418=8 419=8 420=8 421=2 PARAMETER defined in and out of INCLUDE file 422=2 PARAMETER defined in different INCLUDE files 423=1 PARAMETER is never used 424=2 PARAMETER name is used in other contexts 425=2 PARAMETER defined with different values 426=8 427=8 428=8 429=8 430=2 nothing in INCLUDE file is ever referenced 431=3 COMMON variable is not consistently named 432=3 COMMON array dimensioned in different ways 433=3 COMMON variable is not consistently typed 434=3 COMMON var has varying position in COMMON 435=3 COMMON var name appears in different COMMONs 436=2 COMMON variable is never referenced 437=4 COMMON var is used, but never given a value 438=2 COMMON var is given a value, but never used 439=2 COMMON variable name used in other contexts 440=8 441=4 Argument mismatch - Alternate Rtn expected 442=4 Argument mismatch - Variable expected 443=4 Argument mismatch - Subprogram name expected 444=4 Argument mismatch - Array expected 445=4 Argument mismatch - Scalar expected 446=4 Subprogram may modify non-variable argument 447=4 Argument mismatch - incorrect data type 448=4 Argument mismatch - incorrect type-length 449=8 450=8 451=2 MODULE used but not defined 452=3 MODULE defined more than once 453=2 MODULE defined but not used 454=3 MODULE name used in other contexts 455=2 MODULE var name appears in different MODULEs 456=2 MODULE variable is never referenced 457=4 MODULE var is used, but never given a value 458=2 MODULE var is given a value, but never used 459=2 MODULE variable name used in other contexts
Item 302 |
Character Output FormatSpecifies whether ASCII or Unicode characters should be used, and whether an HTML report is to be generated in addition to the basic text report. Possible values are:
|
||||||||||||||||||||||
Item 304 |
Page Width in CharactersSpecifies the target width (in characters) of the GXCHK output file. Must be between 65 and 160. Certain single line messages may exceed the specified width. |
||||||||||||||||||||||
Item 305 |
Filter Input DataMay be used to filter out some symbol table entries. This may be done to allow GXCHK to process larger programs than would otherwise be possible, to make GXCHK run more quickly, or to reduce the amount of output. Possible values are:
The size of the symbol tables produced by SPAG may often be reduced by setting item 2 of the SPAG configuration data to 2 or less (see the description of that item for a discussion). This is usually a better approach to capacity problems than filtering the GXCHK input data. |
||||||||||||||||||||||
Item 308 |
Interface Summary OutputSpecifies whether GXCHK should embed interface summary reports into the restructured source code. The summary replaces a special marker inserted in the restructured code by SPAG if item 8 of the SPAG configuration data is set greater than 0. Possible values are:
Interface summary reports are discussed in detail in Section 3.6. |
||||||||||||||||||||||
Item 309 |
Preparation for Dynamic AnalysisSpecifies whether GXCHK is to prepare the main program for a dynamic analysis run. Possible values are:
If this option is set, GXCHK adjusts the main program to ensure that COMMON variables initialized in a BLOCKDATA (or in any other subprogram) are not overwritten by the dynamic analysis code. Calls to dynamic analysis routines are commented out as necessary by inserting the characters CINIT- or !INIT- in columns 1-6. The Fortran 95 compliant form (!INIT-) is used if the item is set to a negative value (-1 or -2 instead of 1 or 2). GXCHK also reports conditions which may weaken or invalidate the dynamic analysis, including unresolved references and COMMON blocks not defined in the main program. GXCHK will modify the main program only if the input symbol tables were produced by SPAG while preparing the source code for dynamic analysis (item 1 of the SPAG configuration data was set to 4). |
||||||||||||||||||||||
Item 311 |
Subprogram Error ReportingControls reporting of errors and other conditions relating to subprograms. These are
Possible values are:
Recursive subprogram calls are detected only if item 330 is set greater than 0. See items 401-450 for controls on individual messages. |
||||||||||||||||||||||
Item 312 |
COMMON Block Error ReportingControls reporting of errors and other conditions relating to COMMON blocks. These are:
Possible values are as for item 311. See items 401-450 for controls on individual messages. |
||||||||||||||||||||||
Item 313 |
INCLUDE file Error ReportingControls reporting of errors and other conditions relating to INCLUDE files. The only one is:
Possible values are as for item 311. See items 401-450 for controls on individual messages. |
||||||||||||||||||||||
Item 314 |
COMMON Variable Error ReportingControls reporting of errors and other conditions relating to COMMON variables. These are:
Possible values are as for item 311. See items 401-450 for controls on individual messages. |
||||||||||||||||||||||
Item 315 |
PARAMETER Error ReportingControls reporting of errors and other conditions relating to PARAMETERs. These are:
Possible values are as for item 311. See items 401-450 for controls on individual messages. |
||||||||||||||||||||||
Item 316 |
Argument Type CheckingIf item 316 is set greater than zero, GXCHK produces a report showing any inconsistencies between the actual arguments of CALLs and function references, and the dummy arguments in the subroutine or function definitions. For example, if an actual argument is an integer variable, but the subprogram expects a real variable, GXCHK will report an error. Similarly, if the actual argument is a variable, and the dummy argument an array, a different error is reported. The full set of argument mismatch messages is shown below:
The error messages also detail the types of the actual and dummy arguments using three character abbreviations of the form R8E, I4L etc. For alternate returns, the abbreviation is ALT; otherwise the three characters are interpreted as described below. The first character indicates the data type (I for INTEGER, R for REAL, L for LOGICAL, C for CHARACTER, D for DOUBLE PRECISION, X for COMPLEX, Y for DOUBLE COMPLEX or B for BYTE). The second character indicates the element size (e.g. 8 for REAL*8 or DOUBLE PRECISION items). Letters are used for element sizes between 10 and 35. + indicates an element size greater than 35, and * that the size is variable. The third character specifies what sort of entity the argument is (V for variable, E for constant, expression or DO variable, L for an array element, A for an array name or, F for a subprogram name. If a dummy argument is specified as E, this indicates that the subprogram does not change the value of the dummy argument, and that the actual argument may be an expression, constant or DO variable. |
||||||||||||||||||||||
Item 317 |
MODULEs and MODULE variablesControls reporting of errors and other conditions relating to MODULEs and MODULE variables. These are:
|
||||||||||||||||||||||
Item 318 |
Use of default TypesBy default, GXCHK assumes that single precision REAL and INTEGER variables comprise 4 bytes, and that non-standard usages such as REAL*4 and REAL*8 are equivalent to REAL and DOUBLE PRECISION respectively. The Fortran standard does not require this, but it applies to most current hardware, including all of those supported by plusFORT. If item 318 is set greater than 0, the assumption is not made, and in many instances GXCHK reports errors, for example when a REAL*4 variable is used in a context where REAL is expected. Currently, GXCHK is not able to enforce this strict type checking for dummy arguments. |
||||||||||||||||||||||
Item 320 |
Subprogram Location ReportIf item 320 is set greater than 0, GXCHK produces a report showing the subprograms that have been analyzed, the number of executable statements in each one, and the name of the file containing the source code (together with the start and finish line numbers). A summary at the end of the report shows the total number of subprograms, the total number of lines of code, and the total number of executable statements. |
||||||||||||||||||||||
Item 321 |
Subprogram DocumentationControls the generation of reports showing calls in and out of each subprogram (SUBROUTINE or FUNCTIONs). Possible values are:
|
||||||||||||||||||||||
Item 322 |
COMMON block DocumentationControls the generation of reports showing where COMMON blocks are referenced or modified. Possible values are:
|
||||||||||||||||||||||
Item 323 |
INCLUDE file DocumentationControls the generation of reports showing where INCLUDE files are referenced or modified. Possible values are:
|
||||||||||||||||||||||
Item 324 |
COMMON Variable DocumentationControls the generation of reports showing where COMMON variables are referenced or modified. Possible values are:
|
||||||||||||||||||||||
Item 325 |
PARAMETER DocumentationControls the generation of reports showing where PARAMETERs (particularly those defined in INCLUDE files) are used. Possible values are:
|
||||||||||||||||||||||
Item 326 |
MODULE DocumentationControls the generation of reports showing where MODULEs are referenced or modified. Possible values are:
|
||||||||||||||||||||||
Item 327 |
MODULE Variable DocumentationControls the generation of reports showing where MODULE variables are referenced or modified. Possible values are:
|
||||||||||||||||||||||
Item 329 |
Modularization ReportIf item 329 is set greater than 0, GXCHK generates a Modularization report; this shows how subprograms and COMMON data may be combined into MODULEs and/or subprograms with internal procedures. For example, if subprogram A calls subprogram B and uses COMMON block C, and if B and C are not used anywhere else, then B could be converted to an internal subprogram and the variables in C could be local to A. In this case A, B and C may be regarded as a single entity - a subtree. The Modularization report shows the subtrees that exist in the program being analysed, and can be used as a guide to help simplify program structure, by combining subprograms and COMMON blocks into a smaller number of MODULEs and subprograms with internal subroutines. |
||||||||||||||||||||||
Item 330 |
Call TreeControls the generation of a call tree; the call tree shows the calling structure of a program in a graphical format. Possible values are:
If a call tree is generated, GXCHK also detects and reports recursive subroutine calls. |
||||||||||||||||||||||
Item 331 |
'Used by Nothing' ReportsIf item 331 is set greater than 0, lines of the form VARNAME used by ** NOTHING ** are suppressed in the INCLUDE file, COMMON block, COMMON variable and PARAMETER cross reference charts. |
||||||||||||||||||||||
Item 332 |
Orphan BranchesIf item 332 is set greater than 0, 'orphan branches' are suppressed in the call tree. An orphan branch is one which stems from a subroutine or function which is defined but not used. |
||||||||||||||||||||||
Item 350 |
Per Symbol ReportsIf item 350 is set greater than 0, GXCHK produces a individual HTML reports for each symbol. These reports enhance the usefullness of the HTML report by allowing the user to navigate through a program by simply clicking on symbol names to find what is known about it. For example, clicking on a subprogram name calls up a report showing where it is called from, where it calls to, the identity of COMMON and MODULE variables it uses and/or modifes, dummy argument usage, PARAMETER usage, and local variables. In addition any errors in the argument lists of calla to the subroutine are summarised. . |
||||||||||||||||||||||
Items 401-460 |
Error Severity CodesItems 401 to 460 specify the severity code for the corresponding error numbers (GXCHK errors have numbers between 401 and 460). If the severity code is set to 0, the error is suppressed. Error numbers may be found by reference to the documentation of items 311 to 316 above, or from the error summary report produced at the end of a GXCHK run. For example, at the end of a GXCHK run, you may see a summary of the form: 738 sub-programs 86314 lines of source code (excluding INCLUDE files) 38947 executable statements 598 diagnostics reported 5 occurrences of message 401 Subprogram used but not defined 25 occurrences of message 402 Subprogram defined more than once 5 occurrences of message 403 Subprogram defined but not used 9 occurrences of message 405 Subprogram has varying argument counts 1 occurrences of message 406 Subprogram has varying result types 20 occurrences of message 407 Subprogram name is used in other contexts 3 occurrences of message 408 Subprogram is called recursively 5 occurrences of message 421 PARAMETER defined in and out of INCLUDE file 20 occurrences of message 423 PARAMETER is never used 50 occurrences of message 424 PARAMETER name is used in other contexts 4 occurrences of message 425 PARAMETER defined with different values 61 occurrences of message 432 COMMON array dimensioned in different ways 12 occurrences of message 435 COMMON var name appears in different COMMONs 38 occurrences of message 438 COMMON var is given a value, but never used 114 occurrences of message 439 COMMON variable name used in other contexts 8 occurrences of message 441 Possible Argument mismatch - Optional/AltRtn 1 occurrences of message 444 Argument mismatch - Array expected 2 occurrences of message 452 MODULE defined more than once 2 occurrences of message 453 MODULE is defined but not USEd 1 occurrences of message 454 MODULE name is used in other contexts 20 occurrences of message 455 MODULE variable name appears in >1 MODULE 114 occurrences of message 456 MODULE variable is never referenced 9 occurrences of message 457 MODULE var is used, but never given a value 32 occurrences of message 458 MODULE var is given a value, but never used 37 occurrences of message 459 MODULE variable name used in other contexts You can then repeat the run, suppressing all occurrences of errors 401 and 407 (assuming those messages are considered benign) by typing gxchk *.smb 401=0 407=0 Most versions of GXCHK return the highest severity code encountered as an exit code (see Section 1.6), which can be examined by the operating system procedure which runs GXCHK. |
GXCHK is able to examine the usage of COMMON variables in a program wide context. For example if a COMMON variable is used somewhere in the program, but is nowhere assigned a value, GXCHK reports an error. For the purposes of these checks, GXCHK assumes that a given COMMON block should appear the same wherever it occurs. This is good practice, but goes beyond the requirements of standard Fortran. For example the ISO standard permits COMMON variable names to be different in different subprograms. If you find yourself plagued with messages reporting such differences, and it is not practical to remove their cause, you may prefer to switch off COMMON variable checks (item 314 of the configuration file).
Where appropriate, similar checks are applied to MODULE variables. For example, GXCHK reports if it finds that a MODULE variable is never used, or is used but never set, or set but never used.
In order to be sure that GXCHK catches all cases of globally unreferenced COMMON variables, you should ensure that:
either |
Symbol tables are created with item 2 of the SPAG configuration file set to 3. This can result in much larger symbol tables than otherwise. |
or |
Every INCLUDEd file appears in a PROGRAM or BLOCKDATA segment. |
Name clashes are not always errors, but they may deserve attention. For example a 'COMMON variable name is used in other contexts' message may indicate that a COMMON variable is being used, but the COMMON block definition has been omitted. Even if there is no error, there may be cause for action. For example, if a COMMON block is inserted in a subprogram, then there will be a problem if an existing local variable has the same name as one of the COMMON variables. Even with explicit typing, the compiler has no way of knowing that anything is wrong, except, perhaps, that the variable appears in two type declaration statements.
If name clashes are eliminated, that sort of problem cannot occur. One effective technique is to use a naming convention to distinguish symbols of different types. SPAG has a variable renaming facility which can be used to convert existing programs to use a naming convention.
The 'error' conditions reported by GXCHK range from clear errors (e.g. Subprogram defined more than once) through clutter checks (e.g. COMMON variable is given a value but never used), to indications of possible future problems (e.g. COMMON variable name used in other contexts). It may be that not all messages require corrective action, though all should be evaluated.
If you use SPAG to insert declarations in INCLUDE files, turn symbol table output off, or delete the symbol tables before running GXCHK.
If item 8 of the SPAG configuration data and item 308 of the GXCHK configuration data is set to 1, GXCHK embeds a brief summary of the external interface of each subprogram into the restructured output produced by SPAG. A sample interface summary is shown below:
**--*************************************************************** *A INPUT - FIRST - dummy arguments *A INPUT - LAST - space for user descriptions here *A OUTPUT - CNTL * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * calls FRLIST FRWHER FRWNAM FRWTOP OPUT OTRIM * called by PRDIAL PRY2K * modifies /PROGA3/ IWORK1 * uses value /PROGA2/ /PROGA3/ /PROGA4/ /PRCHZ2/ FATHER FUNREC * IORDER LONG_NCHTZM NMTZMB NUMDIM OWNERZ * TZUSES ZBUTTN ZMODIF ZSCOPE ZTBAGE ZTBEDZ * local vars DAD DEF1 DEFS I IL IOS * J JJ K L MXWID NLIST * uses PARAMs MAXFRQ MAXUUB **++***************************************************************
The summary takes the form of a series of Fortran comments. It contains sections describing dummy arguments, external subprograms, MODULE and COMMON variables, local variables and PARAMETERs. These are described below.
Each dummy argument is listed on a line beginning with the two characters '*A' (or '!A' if Fortran 95 free form source is used). Columns 4 to 9 specify the way the argument is used. Possible values are:
INPUT |
The argument is used within the subprogram, but not changed. |
OUTPUT |
The value of the argument is modified within the subprogram. |
PASSED |
The argument is not used within the subprogram, but is passed as an argument to other routines. |
UNUSED |
The argument is not used within the subprogram |
The name of the argument is inserted at column 13. The remainder of the line is intended to contain an explanation, written by the user, of the purpose of the variable.
The second section contains lists of subprograms called or referenced by this subprogram, and of other subprograms which call or reference this one.
The next section shows every MODULE ot COMMON variable that is used by the subprogram. There may be up to three sub-sections, for different types of use:
modifies |
is followed by a list of MODULE or COMMON variables whose value is changed within this subprogram. |
passes arg |
is followed by a list of MODULE or COMMON variables which are not accessed directly within this subprogram, but which are passed as actual arguments to other subprograms. |
uses value |
is followed by a list of MODULE or COMMON variables whose value is used, but not changed within this subprogram. |
The last two sections show the local variables and PARAMETERs used by the subprogram.
Since Fortran 90, two forms of modularization have been available in Fortran:
In general, the former, where feasible, is usually preferable, because it is conceptually simple, and more effective at hiding code and data that does not need to be public.
Legacy Fortran typically comprises a large number of separate subprograms and global data stored in many named COMMON blocks. GXCHK produces two reports designed to assist users in converting such code to a more modern style with modules and contained subprograms.
Figure 4 shows a typical internalization report for a small molecular dynamics program (2000 lines, 28 subprograms, 25 COMMON blocks). The yellow box at top left represents the main program, and the nested structure within it represents a sort of call tree with increasingly narrow scope. Routines and COMMON blocks within a green "CONTAINS" box could logically be contained within the subprogram named immediately to its left. COMMON block names are displayed in red with surrounding "/"s.
The subprograms and COMMON blocks named in boxes to the right of "CALLs" are referenced exclusively from within lowest level containing structure. Thus DENFUN is called only from DENSIT, whereas SYMM may be called from anywhere within the hierarchy below MASTER. Some of these CALLed subprograms themselves have subsidiary lists of CONTAINed and CALLed subprograms.
If internal subprograms could be nested at will, all of the "CALLs" could be replaced by "CONTAINS" and the structure could be implemented precisely as shown in the chart. However nested internal subprograms are not allowed in Fortran, and a decision must be made as to which subprogram will be exposed containers, and which will be hidden.
This can be done simply by choosing which subprogram will not be exposed and merging them with the containing routine. At the extreme, MDBNCH could simply contain all of the subprograms and COMMON blocks it uses, so that the program becomes a single compilation unit. However that's impractical for larger programs, and not ideal from an information hiding perspective. To illustrate a less extreme course, we can see in Figure 4, that the DENSIT and DENFUN subprograms could be combined. so that DENSIT contains DENFUN and /DENDAT/.
This merging of modules could be done manually, but GXCHK includes a facility which allows the user to experiment with different ideas until a suitable simplification of the original structure is found. Before creating the internalization report, GXCHK looks for a plain text file called GXCHK_NOT_SUBTREES.txt in the current directory. If the file is found, it is assumed to contain a list of subprograms, separated by spaces or line breaks, which are to be made internal to the next higher level subprogram. For example, if the file contains:
denfun glufun potfun minit mlist ranpos
then GXCHK produces a simpler structure, as shown in Figure 5
GXCHK analyses the calling structure and COMMON data access patterns of your program, with a view to splitting subprograms and COMMON blocks into groups. For example, if there is a set of five routines that access the same COMMON blocks, and are all called from the same higher level routines, or each other, then they will be judged to be good candidates to be combined in a single module. The resulting analysis is displayed in the form of a "Cluster Analysis" matrix, an example of which is shown in Figure 6.
The matrix comprises a matrix with coloured cells, one for every pair of subprograms or COMMON blocks. The cell is white if there are no interactions (e.g. calls from one to another) and increasing dark green for stronger and stronger interactions. The dashed black boxes along the diagonal group together subprograms or COMMON blocks which could be placed together in a module. In a perfect world all coloured squares would be inside the dashed black boxes. In practice, it's best to regard this division into modules as a starting point to be refined with human intervention.
Although the GXCHK modularization report provides a good overview of the modularization process, the implementation remains non-trivial, and it is advisable to prepare the ground carefully. In particular the following should be considered:
COMMON blocks should be standardized, and ideally inserted in a file which is INCLUDEd in the source where required. If local variables are EQUIVALENCEd to COMMON variables, the local variable declaration declaration and EQUIVALENCE statement should also be in the INCLUDEd file. Note that the Fotran standard does not permit local variables to be EQUIVALENCEd to variables in a USEd module.
It is recommended that SPAG be used to convert the program to use explicit typing (see Section 2.7)
BLOCK DATA subprograms can inhibit modularization, especially if they contain unrelated COMMON blocks. Consider moving initializations into non BLOCK DATA subprograms.
When inserting USE statements for global data from a "CONTAINS" list, consider using ONLY clauses to minimize pollution of the namespace, and reduce the scope for name clashes. This is especially important if implicit typing is used. Use GXHK's HTML reports to find what variables and routines need to be in the ONLY clause.
Remember that it is not necessary to deal with the entirety of a large program as a single unit. If the broad subdivisions are known, it can make good sense to deal with each as a separate project.