Special considerations ====================== The example presented so far was a simple one that required no manual intervention to complete the processing chain. Unfortunately there are examples within the NEMO source tree that fail at the first hurdle by not producing a valid submod.list file. There are several reasons why this can occur and in each case a quick hand edit is usually sufficient to resolve the issue. In no particular order of priority, the issues that can occur are listed here. The reason why they occur and the simplest fix to each is provided in the subsequent sections: * Multiple CONTAINS statements and duplicate declarations * No MODULE statement * INTERFACE statements occurring before the CONTAINS statement * Apparently empty modules Multiple CONTAINS statements ---------------------------- This one occurs because of modules that still contain preprocessor keys which can remove large blocks of code. Often in these circumstances alternative, 'dummy' routines are provided to satisfy the linker. Unfortunately this means two CONTAINS statements and duplicate SUBROUTINE declarations. Take this example (albeit a rather obsolete one) from the `SBC` directory:: sbcice_cice.F90 MODULE sbcice_cice CONTAINS INTEGER FUNCTION sbc_ice_cice_alloc SUBROUTINE sbc_ice_cice SUBROUTINE cice_sbc_init SUBROUTINE cice_sbc_in SUBROUTINE cice_sbc_out SUBROUTINE cice_sbc_hadgam SUBROUTINE cice_sbc_final SUBROUTINE cice_sbc_force SUBROUTINE nemo2cice SUBROUTINE cice2nemo CONTAINS SUBROUTINE sbc_ice_cice ! Dummy routine SUBROUTINE cice_sbc_init ! Dummy routine SUBROUTINE cice_sbc_final ! Dummy routine The `submod.sh` script handles this situation by ignoring the second CONTAINS and any lines between this statement and the next blank (i.e. whitespace only) line. Users may prefer a more explicit solution which, in this example, is obviously just to delete the second CONTAINS statement and duplicate subroutine names. Of course this snippet is taken from a lengthy `newsubmod.list` file so spotting this issue isn't necessarily straight-forward. To assist, there is an additional script: `sanity_submod.sh` that does its best to discover issues and pinpoint line numbers. More on that later though after all the potential issues have been discussed. No MODULE statement ------------------- This one occurs primarily in `.h90` files that aren't whole files. Here is one example from the `SBC` directory:: sbcwave.F90 MODULE sbcwave CONTAINS SUBROUTINE sbc_stokes SUBROUTINE sbc_wstress SUBROUTINE sbc_wave SUBROUTINE sbc_wave_init tide.h90 tideini.F90 MODULE tideini CONTAINS SUBROUTINE tide_init (note `tide.h90` hidden in the middle there). There are also a few examples in the `NST` directory of non-modular programs with subroutines but no modules. E.g.:: agrif2model.F90 SUBROUTINE Agrif2Model SUBROUTINE Agrif_Set_numberofcells SUBROUTINE Agrif_Get_numberofcells SUBROUTINE Agrif_Allocationcalls SUBROUTINE Agrif_probdim_modtype_def SUBROUTINE Agrif_clustering_def SUBROUTINE Agrif2Model the best solution here is to insert a `MODULE none` statement followed by a CONTAINS statement before the first SUBROUTINE statement. INTERFACE statements occurring before the CONTAINS statement ------------------------------------------------------------ This one doesn't indicate any non-conformity to the coding convention but is rather an indication that generic subroutines are present and human interaction is required to decide how the module contents are to be presented. Take this example from the `OCE` main directory:: lib_fortran.F90 MODULE lib_fortran INTERFACE glob_sum INTERFACE glob_sum_full INTERFACE local_sum INTERFACE sum3x3 INTERFACE glob_min INTERFACE glob_max INTERFACE SIGN CONTAINS FUNCTION local_sum_2d FUNCTION local_sum_3d SUBROUTINE sum3x3_2d SUBROUTINE sum3x3_3d SUBROUTINE DDPDD SUBROUTINE glob_sum_1d SUBROUTINE glob_sum_2d SUBROUTINE glob_sum_full_2d SUBROUTINE glob_sum_3d SUBROUTINE glob_sum_full_3d FUNCTION SIGN_SCALAR FUNCTION SIGN_ARRAY_1D FUNCTION SIGN_ARRAY_2D FUNCTION SIGN_ARRAY_3D FUNCTION SIGN_ARRAY_1D_A FUNCTION SIGN_ARRAY_2D_A FUNCTION SIGN_ARRAY_3D_A FUNCTION SIGN_ARRAY_1D_B FUNCTION SIGN_ARRAY_2D_B FUNCTION SIGN_ARRAY_3D_B showing all the component variations that make up the generic routines and functions is probably not required. If it is then just delete the INTERFACE statements, but a better solution is probably to delete the internal variants and just present the generic names. This is achieved by moving the INTERFACE statements below the CONTAINS statements and deleting any surplus. I.e.:: lib_fortran.F90 MODULE lib_fortran CONTAINS INTERFACE glob_sum INTERFACE glob_sum_full INTERFACE local_sum INTERFACE sum3x3 INTERFACE glob_min INTERFACE glob_max INTERFACE SIGN SUBROUTINE DDPDD Apparently empty modules ------------------------ Some modules are intentionally empty of any contained routines. For example:: par_kind.F90 MODULE par_kind these cases are not errors and are handled correctly. Some others are apparently empty because they rely on the preprocessor to include content from h90 files. These are primarily in the OBS directory and can be fixed by suitably combining the list entries for the relevant .F90 and .h90 files. The sanity_submod.sh script --------------------------- As mentioned earlier some of these issues can be difficult to spot in lengthy submod list files. To assist, the sanity_submod.sh script can be run immediately after generating the newsubmod.list file. It should catch most issues and pinpoint the first occurrence in the file. A null return indicates no errors were detected. Here are some examples of its output whilst iteratively fixing issues in `OCE`:: mksubmodlist sanity_submod.sh =================================== | Errors detected | =================================== # files = 12 # modules = 10 # contains = 7 # interfaces = 7 =================================== Some files do not contain a MODULE statement. First suspect occurs near line: 28 See full list of line numbers for filename(+1) and MODULE statements below: files : 2 28 38 48 53 56 59 65 68 73 89 97 Modules: 2 38 48 53 56 59 65 68 73 89 =================================== vi newsubmod.list #remove files without MODULES sanity_submod.sh Error detected: misplaced INTERFACE statement at line: 3 vi newsubmod.list # Sort out misplaced interface statements sanity_submod.sh # No return. Job done mv newsubmod.list OCE_submod.list Just one caution here though because this file contained 10 `MODULE` statements but only 7 `CONTAINS` statements. This is not necessarily an error but worth checking just in case. `sanity_submod.sh` has a warning mode that can be useful to narrow the search:: ./sanity_submod.sh -w OCE_submod.list =================================== | File stats | =================================== # files = 10 # modules = 10 # contains = 7 # interfaces = 7 =================================== =================================== | Warnings | =================================== Some files do not contain a CONTAINS statements. First suspect occurs near line: 35 See full list of line numbers for MODULE and CONTAINS(-1) statements below: Modules : 2 14 24 29 32 35 41 44 49 65 Contains: 2 14 24 35 44 49 65 =================================== (note `sanity_submod.sh` will also accept an alternative input filename). An investigation is unneccessary in this case since the three modules without a CONTAINS statement are genuine examples (`par_kind`, `par_oce` and `step_oce`).