Fortran-90 MODULE M3UTILIO

Summary

Fortran-90 style MODULE M3UTILIO does the "proper F90 way" of encapsulating the Models-3 I/O API parameter, data structure, and function-declarations, in a way that nested Fortran USE <module> constructs do not interact with older Fortran INCLUDE statements to generate multiple-declaration errors at compile time.

The issue is that when one has two or more Fortran-90 MODULEs, say MODULE A that USEs MODULE B, where both of these need access to facilities provded by the standard I/O API INCLUDE files PARMS3.EXT, FDESC3.EXT, and/or IODECL3.EXT, there is a problem: if MODULE B INCLUDEs these, it introduces an artificial dependency of MODULE A upon MODULE B: where should the INCLUDE statements be placed (if they appear in both MODULEs, the compiler will complain that variables and functions have repeated declarations, which is illegal. The problem is even worse if MODULE A USEs a third MODULE C, independent of B, that also needs I/O API INCLUDE files: one can't necessarily make C USE B, or vice versa.

However, the Fortran-90 USE construct does not have this problem: MODULEs A, B, and C can all have statements USE M3UTILIO without causing multiple-declaration problems: the recognition that these statements provide one common set of declarations is now built into the Fortran-90 (and later) language, in a way not possible at all for Fortran-77 (and that must be managed manually by the programmer with #ifdefs for the corresponding C #include construct).

Note that in retro-fitting MODULE M3UTILIO into existing codes, one must not only remove all of the INCLUDE statements associated with the standard I/O API PARMS3.EXT, FDESC3.EXT, and/or IODECL3.EXT, one must also remove any (now extra, duplicate) declarations of the functions with explicit INTERFACEs from the list given above.


Contents of MODULE M3UTILIO

MODULE M3UTILIO itself includes, and therefore USE M3UTILIO replaces the INCLUDE statements for the following Models-3 I/O API INCLUDE files:
PARMS3.EXT
FDESC3.EXT
IODECL3.EXT
It further provides Fortran-90 style INTERFACE blocks for the following list of routines (basically, all of the public routines in the I/O API whose usage does not require "void pointer" arguments -- note that the BUFFER argument for WRITE3() does not have a single specified type; it may be INTEGER, REAL, or DOUBLE PRECISION, and may have an arbitrary number of dimensions, instead of being restricted (as an INTERFACE would require) to one single possibility like a 3-D REAL BUFFER(:,:,:), or requiring over three thousand lines of "wrapper" code to support the implied polymorphism. (IODECL3.EXT is invoked from this MODULE to provide the EXTERNAL declarations for these polymorphic routines, but not full interface blocks.)
BILIN
BMATVEC
CHKBUF3
CRLF
CURREC
CURSTEP
DAYMON
DMATVEC
DSCGRID and DSCOORD
DT2STR
ENVDBLE
ENVINT
Generic ENVLIST (as of March, 2014)
generalizing INTLIST, REALIST, STRLIST
ENVREAL
ENVSTR
ENVYN
Generic FINDKEY (as of March, 2014)
generalizing FINDC, FIND1, FIND2, FIND3, FIND4, FINDL1, FINDL2, FINDL3, FINDL4, FINDR1, FINDR2, FINDR3, FINDR4
FINDC
FIND1
FIND2
FIND3
FIND4
FINDL1
FINDL2
FINDL3
FINDL4
FINDR1
FINDR2
FINDR3
FINDR4
GCD
GETDATE
GETDBLE
GETDFILE
GETEFILE
GETFFILE
GETMENU
GETNUM
GETREAL
GETSTR
GETYN
GRDCHK3
GTP0
HHMMSS
INDEX1
INDEXINT1
INTLIST
ISDST
JSTEP3
JULIAN
JUNIT
LAMBERT
and related routines POLSTE, EQMERC, TRMERC, ALBERS, SETLAM, SETPOL, SETEQM, SETTRM, SETALB, LAM2LL, LL2LAM, LAM2UTM, UTM2LAM, LAM2POL, POL2LAM, POL2LL, LL2POL, POL2UTM, UTM2POL, TRM2LL, LL2TRM, LAM2TRM, TRM2LAM, TRM2UTM, UTM2TRM, TRM2POL, POl2TRM, EQM2LL, LL2EQM, LAM2EQM, EQM2LAM, EQM2UTM, UTM2EQM, EQM2POL, POL2EQM, EQM2TRM, TRM2EQM, ALB2LL, LL2ALB
LASTTIME (as of Jan. 2013)
LBLANK
Generic LOCATE (as of March, 2014)
generalizing LOCATC, LOCAT1, LOCAT2, LOCAT3, LOCAT4, LOCATL1, LOCATL2, LOCATL3, LOCATL4, LOCATR1, LOCATR2, LOCATR3, LOCATR4
LOCAT1
LOCAT2
LOCAT3
LOCAT4
LOCATC
LOCATL1
LOCATL2
LOCATL3
LOCATL4
LOCATR1
LOCATR2
LOCATR3
LOCATR4
LUSTR
M3EXIT
M3FLUSH
M3MESG
M3MSG2
M3PARAG
M3PROMPT
M3WARN
MMDDYY
NEXTIME
PCOEF
PMATVEC
POLY
PROMPTDFILE
PROMPTFFILE
PROMPTMFILE
PROMPTGRID()
REALIST
SCANINT()
SEC2TIME
SECSDIFF
SETENVVAR
SETSPHERE and INITSPHERES
Generic SORTI (as of March, 2014)
generalizing SORTIC, SORTIC4, SORTIC8, SORTI1, SORTI2, SORTI3, SORTI4, SORTL1, SORTL2, SORTL3, SORTL4, SORTR1, SORTR2, SORTR3, SORTR4
SORTIC
SORTI1
SORTI2
SORTI3
SORTI4
SORTL1
SORTL2
SORTL3
SORTL4
SORTR1
SORTR2
SORTR3
SORTR4
STR2DBLE
STR2INT
STR2REAL
STRLIST
TIME2SEC
UNGRIDB
UNGRIDI
UPCASE()
WKDAY
YEAR4
YR2DAY
It also provides four cleanly-coded public parsing-utility routines that replace various less-well-conceived SMOKE 1.x library-routines,and new utility routines for grid-description checking and for integer unsorted-table lookup:
SUBROUTINE SPLITLINE( LINE, NMAX, N, FIELD, EFLAG )
CHARACTER(LEN=*), INTENT( IN ):: LINE
INTEGER, INTENT( IN ):: NMAX
INTEGER, INTENT( OUT ):: N
CHARACTER(LEN=*), INTENT( OUT ):: FIELD( NMAX )
LOGICAL, INTENT( OUT ):: EFLAG
split a line into fields, ignoring comments

SUBROUTINE FIXFIELD( FIELD )
CHARACTER(LEN=*), INTENT( INOUT ):: FIELD
fixup, replacing blanks and "missing"s in character-string fields by zeros

REAL FUNCTION KEYVAL( KEY )
CHARACTER(LEN=*), INTENT( IN ) :: KEY
search for REAL key-value in I/O API file descriptive header FDESC3D array.

KEYSTR
CHARACTER(LEN=*), INTENT( IN ) :: KEY CHARACTER(LEN=*), INTENT( OUT ) :: VAL
search for character-string key-value in I/O API file descriptive header FDESC3D array.


To: Models-3/EDSS I/O API: The Help Pages

Send comments to

Carlie J. Coats, Jr.
cjcoats@email.unc.edu