30.8 Standards (Rules) for Writing CONGEN Code
The following set of rules is designed to help keep CONGEN
readable and modifiable.
- All routines should have similar organization.
Each Fortran subroutine should have the following
C A comment which describes the purpose of this subroutine.
C This comment is essential because it provides the only
C documentation for nearly all subroutines in CONGEN. The
C program, AUTODOC, can be used to get this comment from all
The separation of the code from the declarations by a
blank comment aids in reading the code. It becomes obvious
where executed code begins.
Each C procedure should be written like this:
dothis(type par1, type par2,...)
* A comment which describes the purpose of the routine. This
* comment must come here so that automatic documentation can
* be implemented (a program similar to AUTODOC is planned.)
- Prototypes for all the C functions should be provided through the use of
mkproto, see Mkproto. See the
makefile for CONGEN
for details of the mechanism. Note that not all files can be processed
correctly, such as functions which are declared with structures or
types that are machine dependent. All such functions should be
placed in the file, noproto.c.
- All source files must have a copyright notice at the top. See any source file
for the appropriate text.
- All C source files must include config.h and wrappers_c.h
in that order. It is a good idea to use an existing source file
to provide the copyright and includes to get started.
- All FLECS source files must include config.h and wrappers_f.h.
- All code should be written clearly. Since the code must
be largely self-documenting, clarity should not be sacrificed
for insignificant gains in efficiency. The use of C and the FLECS
preprocessor is encouraged as it graphically illustrates the
flow of control and allows for internal procedure calls.
Variable names should be chosen with care so as to illustrate
their purpose. Avoid using one or two letter variable names
in any COMMON blocks. Comments should be used where the
function of code is not obvious.
- All usages of integers, floats, doubles in C code must use the
defined in config.h. Boolean variables should use the
BOOLEAN macro, and Fortran logical variables defined in Fortran
should use the
F77_LOGICAL macro. The
should declare to a
long int. If not, you must review calls to
printf functions to ensure correct
- Be careful to distinguish between Fortran 77 logical variables and
C integers being used to hold Boolean variables. The testing conditions
are machine dependent. Use the macros provided in macros.h
for Fortran logicals.
- Be careful that the type of any numeric constant match correctly with
its usage across the various platforms that CONGEN is implemented on.
For example, there may be problems with using a real constant in an
intrinsic function call with multiple variables in Fortran,
SIGN(1.0,P). If P is
DOUBLE_DECL, you will have
a problem because
DOUBLE_DECL can map to either
DOUBLE PRECISION depending on the machine. In such cases, it is
better to use a variable or parameter to store the constant.
- All usages of
DOUBLE PRECISION variables in Fortran must be declared
DOUBLE_DECL macro. This allows CONGEN to switch double precision
variables to single precision on 64-bit computers.
- Any variable in Fortran code that holds a pointer to be used by the C
code must be declared using the
POINTER_DECL macro. On 64 bit architectures,
this macro will expand to 64 bit integers. The equivalent type in C is
given by the
- Any subroutine defined in C which can be called from FLECS code
must have its prototype entered into the source file wrap_cdef.proto.
Likewise, any subroutine defined in FLECS which can be called from
C must have its prototype entered into the source file wrap_fdef.proto.
- Whenever Fortran common blocks are accessed within C, you must use the
predefined macro for the common block name. The macro is the upper case
name for the common block. Header files (suffix .h) are defined for
all common blocks used in C code. For example, if you want to refer to the
X coordinate array in C, use
- There are number of rules associated with input and output:
- All input commands should be free field. The
command processor should check that the entire
command is consumed.
- Short outputs, messages, warnings, and error should
be sent to unit 6 for output.
- All inputs should be echoed to unit 6. All values
read by the command should also be output to unit 6.
- All warning and fatal messages should state what subroutine
generated it, so that one find the location in the source code
where the problem arose.
- All data structures output with unformatted I/O statements
must have a
TITLE in the first two
records. See any existing binary output subroutines
for the exact format.
- Unformatted I/O file formats should remain upward
compatible. Use an
ICNTRL array element to indicate
which version of CONGEN wrote the file. Such upward
compatibility must be maintained only across
production versions of CONGEN. In other words, a file
format for the developmental version may be freely
changed until a new version is generated, at which
point all future versions must be able to read it.
- All I/O must be done through Fortran I/O. C I/O is
not to be used. See the procedures in the source
code file, CUTIL.C, for useful analogs of C
I/O functions to make this rule easy to follow.
- All error conditions must terminate with a
CALL DIE. The
DIE, provides a traceback or core dump so the program
statements causing the error can be seen.
- Large or variable storage requirements for Fortran code
must be met on the stack or heap. In C,
cgfree should be
used for all variable storage needs.
- Array overflows must always be checked for when arrays are being
written. This is especially important when the array being
constructed might be dynamically allocated. Error checking
in general should be as complete as feasible.
- The code should use a minimum of non-standard Fortran or C
features. All non-standard features must be conditionally compiled
so that any CONGEN programmer is informed that the code is special.
- In order to make subroutines callable from different
contexts, parameter passing should be done through the
subroutine call rather than through COMMON blocks.
- All common blocks which are shared between multiple subprograms
are to be placed in files and
the program. The common blocks should have comments
describing each variable in the common block so that new
users will know what's there. No directory should be specified for
#include'd files, so that the -I option to the C preprocessor
can be used to select the directory at will. If a common block is to be shared
between C and Fortran code, use the existing code in the *.h files
to implement the needed name equivalence.
- Avoid the use of static memory for initialization purposes. As more
sections of CONGEN are implemented on parallel computers, making the
subroutines reentrant is essential. Also, avoid the use of
DATA statements in Fortran, since all storage referenced by these
statements is allocated statically on the Iris.
- When using
scanf functions in C, use only long int's or doubles
for your I/O, and then convert to your type. This avoids the need
to control for machine dependent variations in data lengths.