Coding Standards help reduce sources of common bugs, causes of inscrutable software, differences in coding style, ... In other words, they facilitate maintenance, and improve code portability and readability. And at the end, they improve science productivity.
"Mostly, a program is communication from one programmer to another (forget about the machine), where the "other" programmer is likely to be myself next week, and using the clearest coding style is usually the best. D. Hendrickson, on comp.lang.fortran
For TM5 a couple of rules are mandatory: internal documentation and line length. Others are recommendations. Feel free to add your own suggestions (so we can discuss it). Three broad categories are considered here: style, language, and design. Have a look at some of TM5 most recent modules to see how these standards are applied.
These rules force you to clean up your code. You should describe module/procedure/function, and their variables. It also brings a consistent look-and-feel across the code, which increases readability. We recommend using ProTex keywords to introduce these mandatory comments in your code. You should at least include:
- a header : module and public procedures (subroutine or function) must have a header summary.
- variables information : module public entities, and procedure dummy variable must be documented.
We do not recommend including history. This is better retrieved through the version control software (subversion).
This concerns names, indentation, usage of spaces, case, ... We have not agree on any conventions, but have these suggestions:
- a maximum length of line is 79 (a la PEP 8, a recommended coding style for Python code). For readability, it may be wise to go for longer lines when needed, but please, no more 855 characters long line (YES! there was one such line in TM5). Actually we require that all new lines of code are no longer than 132 characters, which is the standard and which is enforced by some compilers.
- Naming conventions: none yet, but good practice includes meaningful variable, module and routine names. See the TM5 dictionary for more about naming in TM5.
F90 language constructs
These rules seem to be tacitly followed, and are viewed as good practice.
- use FORTRAN 95 standard
- banned use of obsolete features (despite the backward compatibility).
Code design and control
These rules are particularly helpful for new developments.
Add these lines at the top of your module:
#define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
Add a return code to your subroutines:
integer, intent(out) :: status
and define the rname parameter for each subroutine:
character(len=*), parameter :: rname = 'routine_name'
Then, if your code catches an error, it must return a status with a value different from 0. After a call to that subroutine, you can catch any error and return to the caller with either one of these lines:
action is typically
status=1 for a typical error.
Specific treatment for MDF routines (the user interface to data files) are used, see io_save.F90 for example.
For for logs and print statements, just use the General Object (GO) suite of tools.
use GO, only :: gol, goPr, goErr, goBug ... write(gol,*) 'something to write' call goPr
If you call
goBug instead of
[BUG] is prepended to the output.
You can find more details about formatting the logs in Output options.
Put them in the
- New projects
- They should be below the TM5/proj/ dir. In the following tree, alanis, budget, c13, and chem/base are different projects. See Creating a new project for more details on creating your own.
TM5 |-- base | |-- branches | |-- release | `-- trunk |-- proj | |-- alanis | |-- budget | |-- c13 | |-- chem/base | | |-- branches | | |-- release | | `-- trunk
- Existing projects
- A project has typically a trunk and a branches sub-directories. Before inclusion in the trunk, major modifications to the project should be carried on a copy of the trunk into a branch under the branches directory. See Creating a new branch for more details on creating your own branch.