MORSE Coding Conventions

Last Updated: 27JUL05


CODING

FORTRAN Standard
As far as possible the code has been written in `standard' FORTRAN-77. However, a couple of commonly-implemented non-standard extensions have also been used for convenience:
COMMON Blocks
All COMMON data blocks (i.e., data which is passed between subroutines via a COMMON block rather than via the argument list) are kept as `include files' (ie *.inc). This avoids problems where the COMMON block declaration in one subroutine may be inconsistent with the same block declaration in another.
BLOCK DATA
The standard way of initialising data held in COMMON blocks is using the BLOCK DATA statement. However, this is not used in MORSE due to the additional complexity required in the compile statement. Instead, all data held in COMMON blocks is written explicitly during run time.
Array Dimensions
Most of the array sizes are held as PARAMETER statements in the file rfmsiz.inc. MORSE should always check array dimensions before arrays are written so that array bound errors should not occur. Instead, the program will stop with a fatal error message indicating the subroutine where the problem occurred and the array dimension which needs to be increased.
DATA Statements
Where possible and necessary, subroutine variables are initialised using DATA statements (and also SAVEd in subroutines called more than once). In many cases, this isn't actually necessary since the code itself should ensure that the initial value that is accessed is always defined, however DATA statements are used anyway (often with an illegal `dummy' value such as -1) to avoid nagging messages from the compiler or code-checking programs.
SAVE Statements
SAVE statements are used sparingly to avoid unnecessary computational overheads. Obviously these are only used in subroutines which are called more than once, and usually only applied to specific variables (usually those which are also initialised in DATA statements).
Continuation
In standard FORTRAN 77 almost any character can be used in `column 6' of a record to indicate a continuation. However, in MORSE, only the & character is used since it is distinct from character which might appear as part of a legitimate statement.
EXTERNAL
All functions and subroutines called within a module are declared using an EXTERNAL statement. Mostly this just serves to make the dependencies clear but also prevents intrinsic functions being used which accidentally have the same name as a MORSE subroutine/function.

Module Names

Subroutine Modules
Most subroutine modules have 6-letter names (plus the .for extension). These are often of structure abcxyz.for where abc are the last 3 letters of the name of the parent module (or mse in the cases of subroutines called directly from the program module) and xyz relates to the operation being performed in the subroutine.
For example, drvxsc.for is the module which reads the *XSC section of the driver table, which is called from msedrv.for and calls subroutines xscchk.for and xscfil.for (as well as a couple of general purpose modules nxtfld.for which reads the next field from the driver table section and rfmlog.for, which writes messages to morse.log).
Include Files
Include files are of three types:
Common Variables
These have names like abccom.inc where ABCCOM is the name of the FORTRAN COMMON BLOCK, and within the COMMON BLOCK are a series of variables with names terminating in ...ABC. Where these variables are 1-dimensional arrays, they will usually have a declared array dimension MAXABC (stored as a PARAMETER in rfmsiz.inc) and a COMMON VARIABLE NABC, indicating the number of array elements which are actually used.
Note that BLOCK DATA statements are not used in MORSE, ie all elements of COMMON BLOCKS are filled during run time.
Global Constants
Names sometimes ending in ...con.inc but with some notable exceptions such as rfmsiz.inc (containing most of the array dimensions of common variables, MAX...) and mselun.inc containin the list of Logical Unit Numbers used by MORSE.
Large Data Statements
Names sometimes ending in ...dat.inc, but also h2ockd.inc and h2omtc.inc containing large tabulated datasets such as molecular continuum and line-mixing data. These are usually only required in single modules but make the subroutine code unwieldy if directly included within the subroutine itself.

I/O Operations

Terminal Input/Output
Printing to the terminal uses a WRITE statement with * as the unit number, giving the default output LUN (usually 6).
WRITE ( *, '(A)' ) 'Typical output statement'
MORSE does not READ from the terminal, so the default input lun (usually 5) is not used.
Logical Unit Numbers
MORSE LUNs are contained in file mselun.inc.
Apart from avoiding the default terminal input (5) and output (6) luns, most of these are arbitrary. The only exception is LUNFRE which is used as the base value for assigning LUNs to files which are opened and remain open while MORSE is run. Therefore this should be at least 1 higher than any other assigned LUN value.
LUNTMP is recommended for files which are opened, read/written, and immediately closed.
I/O Errors
On most (but not all) MORSE FORTRAN I/O statements (OPEN, CLOSE, READ, WRITE, REWIND, BACKSPACE) there is a test on the IOSTAT value returned.
If IOSTAT is non-zero MORSE usually interprets this as a fatal error, in which case the program terminates with a MORSE-generated error message indicating the subroutine where the error occurred and the IOSTAT value (this is preferable to just letting the program crash with an I/O error message but no clue where in the code it occurred).
Unfortunately, these IOSTAT values are compiler-dependent so it is not possible to uniquely identify each IOSTAT value with a particular error.
An exception is the end-of-file error, indicated by IOSTAT=-1 on all compilers. However, in cases where this is expected (eg reading the contents of a file or record until the end is detected) the END=nnn switch is used in the FORTRAN READ statement to control the next action.

  • Back to MORSE Index