[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 960627: Fortran-90 module for netCDF API



Robert,

> >Thanks, I'll try to include this with the next update.
> 
> >I tried defining interface blocks for all the subroutines (see the appended
> >draft interface block), but discovered this wasn't really possible with the
> >kind of type-punning we do in the current Fortran interface.
> 
> Geez, do I feel silly. Your interface block (even for the functions alone,
> as I had sent them to you) is far more complete and well documented than
> the module I hastily pulled together. Distribute your version, and chuck
> mine away!

Not so fast; I liked your formatting and decided we didn't need yet another
set of comments documenting what each parameter was for if good names were
used in the interface blocks, so I merged the two.  I've appended the
result.  I haven't tried compiling with it because I don't have easy access
to a Fortran-90 compiler right now.

> I didn't think very hard about how to treat either the type-punning of the
> variable rank of data passed to routines like NCVPT, but it seems like
> there might be some serious headaches, although the additional checking
> allowed by F90 might also allow compilation-time trapping of some class of
> errors. Best of luck! Count me in as an avid consumer.

Yes, I have the feeling that there is no way around the type-punning
problem, so it might be better to just comment out all the interfaces for
the get/put subroutines that use it, but I wish I knew if there were some
way to get the compiler to use the interface blocks to just check the other
parameters and ignore the ones that type-punning is used for.  That would
probably be useful.  Something like a "don't-care" type declaration for
what in the C interface are the "void*" parameters.

Anyway, thanks for your contribution and any light you may be able to shed
on the above.

--Russ


! Encapsulation of netCDF API parameters and interface blocks. 
! Derived from "netcdf.inc" in the netCDF 2.4/HDF 4.0.1  distribution.

module netcdf
! Netcdf data types
  integer, parameter :: NCBYTE = 1, NCCHAR = 2, NCSHORT = 3, &
                        NCLONG = 4, NCFLOAT = 5, NCDOUBLE = 6
      
!     masks for the struct NC flag field; passed in as 'mode' arg to
!     nccreate and ncopen.
     
  integer, parameter :: & 
    NCRDWR   = 1,   & ! read/write, 0 => readonly 
    NCCREAT  = 2,   & ! in create phase, cleared by ncendef 
    NCEXCL   = 4,   & ! on create destroy existing file 
    NCINDEF  = 8,   & ! in define mode, cleared by ncendef 
    NCNSYNC  = 16,  & ! synchronise whole header on change (X'20')
    NCHSYNC  = 32,  & ! synchronise numrecs on change (X'10')
    NCNDIRTY = 64,  & ! numrecs has changed (X'40')
    NCHDIRTY = 128, & ! header info has changed (X'80')
    NCFILL   = 0,   & ! prefill vars on endef and increase of record (default)
    NCNOFILL = 256, & ! don't fill vars on endef and increase of record (X'100')
    NCLINK   = 32768  ! isa link (X'8000')
      
! 'mode' arguments for nccreate and ncopen
     
  integer, parameter ::  &
    NCNOWRIT = 0, NCWRITE = NCRDWR, &
    NCCLOB = 11, NCNOCLOB = 15
     
  integer, parameter :: &
    NCUNLIM  = 0 ! 'size' argument to ncdimdef for an unlimited dimension
      
  integer, parameter :: &
    NCGLOBAL = 0 ! attribute id to put/get a global attribute
     
! Advisory Maximums
     
  integer, parameter :: &
    MAXNCOP = 32, MAXNCDIM = 32, MAXNCATT = 512, MAXNCVAR = 512, &
    MAXNCNAM = 128, MAXVDIMS = MAXNCDIM ! Not enforced 
      
     
!     Global netcdf error status variable
!     Initialized in error.c
      
  integer, parameter :: &
    NCNOERR  = 0, &  ! No Error 
    NCEBADID = 1, &  ! Too many netcdfs open 
    NCENFILE = 2, &  ! Not a netcdf id 
    NCEEXIST = 3, &  ! netcdf file exists && NCNOCLOB
    NCEINVAL = 4, &  ! Invalid Argument 
    NCEPERM  = 5, &  ! Write to read only 
    NCENOTIN = 6, &  ! Operation not allowed in data mode 
    NCEINDEF = 7, &  ! Operation not allowed in define mode 
    NCECOORD = 8, &  ! Coordinates out of Domain 
    NCEMAXDS = 9, &  ! String match to name in use 
    NCENAME  = 10, & ! MAXNCDIMS exceeded 
    NCENOATT = 11, & ! Attribute not found 
    NCEMAXAT = 12, & ! MAXNCATTRS exceeded 
    NCEBADTY = 13, & ! Not a netcdf data type 
    NCEBADD  = 14, & ! Invalid dimension id 
    NCEUNLIM = 15, & ! NCUNLIMITED in the wrong index 
    NCEMAXVS = 16, & ! MAXNCVARS exceeded 
    NCENOTVR = 17, & ! Variable not found 
    NCEGLOB  = 18, & ! Action prohibited on NCGLOBAL varid 
    NCENOTNC = 19, & ! Not a netcdf file 
    NCESTS   = 20, &
    NCENTOOL = 21, &    
    NCFOOBAR = 32, &
    NCSYSERR = -1
      
!     Global options variable. Used to determine behavior of error handler.
!     Initialized in lerror.c
     
 integer, parameter :: NCFATAL = 1, NCVERBOS = 2

! Functions in the FORTRAN interface
! NB: Interface blocks for some or all of these would sure be nice ... RP

  interface
    integer function nccre(filename, cmode, rcode)
      character (len = *), intent ( in) :: filename
      integer            , intent ( in) :: cmode
      integer            , intent (out) :: rcode
    end function nccre

    integer function ncopn(filename, rwmode, rcode)
      character (len = *), intent ( in) :: filename
      integer            , intent ( in) :: rwmode
      integer            , intent (out) :: rcode
    end function ncopn

    subroutine ncredf (ncid, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent (out) :: rcode
    end subroutine ncredf

    subroutine ncendf (ncid, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent (out) :: rcode
    end subroutine ncendf

    subroutine ncclos (ncid, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent (out) :: rcode
    end subroutine ncclos

    subroutine ncinq (ncid, ndims, nvars, natts, recdim, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent (out) :: ndims
      integer            , intent (out) :: nvars
      integer            , intent (out) :: natts
      integer            , intent (out) :: recdim
      integer            , intent (out) :: rcode
    end subroutine ncinq

    subroutine ncsnc (ncid, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent (out) :: rcode
    end subroutine ncsnc

    subroutine ncabor (ncid, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent (out) :: rcode
    end subroutine ncabor

    integer function ncddef(ncid, dimname, dimsize, rcode)
      integer            , intent ( in) :: ncid, dimsize
      character (len = *), intent ( in) :: dimname
      integer            , intent (out) :: rcode
    end function ncddef

    integer function ncdid(ncid, dimname, rcode)
      integer            , intent ( in) :: ncid
      character (len = *), intent ( in) :: dimname
      integer            , intent (out) :: rcode
    end function ncdid

    subroutine ncdinq (ncid,dimid, dimname,size,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: dimid
      character (len = *), intent (out) :: dimname
      integer            , intent (out) :: size
      integer            , intent (out) :: rcode
    end subroutine ncdinq

    subroutine ncdren (ncid,dimid,dimname, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: dimid
      character (len = *), intent ( in) :: dimname
      integer            , intent (out) :: rcode
    end subroutine ncdren

    integer function ncvdef(ncid, varname, vartype, nvdims, vdims, rcode)
      integer              , intent ( in) :: ncid, vartype, nvdims
      character (len = *)  , intent ( in) :: varname
      integer, dimension(:), intent ( in) :: vdims
      integer              , intent (out) :: rcode
    end function ncvdef
      
    integer function ncvid(ncid, varname, rcode)
      integer            , intent ( in) :: ncid
      character (len = *), intent ( in) :: varname
      integer            , intent (out) :: rcode
    end function ncvid

    subroutine ncvinq (ncid,varid, varname,datatype,nvdims,vdims,nvatts,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      character (len = *), intent (out) :: varname
      integer            , intent (out) :: datatype
      integer            , intent (out) :: nvdims
      integer            , intent (out) :: vdims(nvdims)
      integer            , intent (out) :: nvatts
      integer            , intent (out) :: rcode
    end subroutine ncvinq

    subroutine ncvpt1 (ncid,varid,indices,value, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: indices(*)
      real               , intent ( in) :: value
      integer            , intent (out) :: rcode
    end subroutine ncvpt1

    subroutine ncvp1c (ncid,varid,indices, chval, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: indices(*)
      character          , intent ( in) :: chval
      integer            , intent (out) :: rcode
    end subroutine ncvp1c

    subroutine ncvgt1 (ncid,varid,indices, value, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: indices(*)
      real               , intent (out) :: value
      integer            , intent (out) :: rcode
    end subroutine ncvgt1

    subroutine ncvg1c (ncid,varid,indices, chval, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: indices(*)
      character          , intent (out) :: chval
      integer            , intent (out) :: rcode
    end subroutine ncvg1c

    subroutine ncvpt (ncid,varid,start,counts,values, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: start(*)
      integer            , intent ( in) :: counts(*)
      real               , intent ( in) :: values(*)
      integer            , intent (out) :: rcode
    end subroutine ncvpt

    subroutine ncvptc (ncid,varid,start,counts,string,lenstr, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: start(*)
      integer            , intent ( in) :: counts(*)
      character (len = *), intent ( in) :: string
      integer            , intent ( in) :: lenstr
      integer            , intent (out) :: rcode
    end subroutine ncvptc

    subroutine ncvptg (ncid,varid,start,counts,strides,imap,values, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: start(*)
      integer            , intent ( in) :: counts(*)
      integer            , intent ( in) :: strides(*)
      integer            , intent ( in) :: imap(*)
      real               , intent ( in) :: values(*)
      integer            , intent (out) :: rcode
    end subroutine ncvptg

    subroutine ncvpgc (ncid,varid,start,counts,strides,imap,string,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: start(*)
      integer            , intent ( in) :: counts(*)
      integer            , intent ( in) :: strides(*)
      integer            , intent ( in) :: imap(*)
      character (len = *), intent ( in) :: string
      integer            , intent (out) :: rcode
    end subroutine ncvpgc

    subroutine ncvgt (ncid,varid,start,counts, values,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: start(*)
      integer            , intent ( in) :: counts(*)
      real               , intent (out) :: values
      integer            , intent (out) :: rcode
    end subroutine ncvgt

    subroutine ncvgtc (ncid,varid,start,counts, string,lenstr,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: start(*)
      integer            , intent ( in) :: counts(*)
      character (len = *), intent (out) :: string
      integer            , intent ( in) :: lenstr
      integer            , intent (out) :: rcode
    end subroutine ncvgtc

    subroutine ncvgtg (ncid,varid,start,counts,strides,imap,values,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: start(*)
      integer            , intent ( in) :: counts(*)
      integer            , intent ( in) :: strides(*)
      integer            , intent ( in) :: imap(*)
      real               , intent (out) :: values
      integer            , intent (out) :: rcode
    end subroutine ncvgtg

    subroutine ncvggc (ncid,varid,start,counts,strides,imap,string,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: start(*)
      integer            , intent ( in) :: counts(*)
      integer            , intent ( in) :: strides(*)
      integer            , intent ( in) :: imap(*)
      character (len = *), intent (out) :: string
      integer            , intent (out) :: rcode
    end subroutine ncvggc

    subroutine ncvren (ncid,varid,varname, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      character (len = *), intent ( in) :: varname
      integer            , intent (out) :: rcode
    end subroutine ncvren

    subroutine ncapt (ncid,varid,attname,datatype,attlen,values, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      character (len = *), intent ( in) :: attname
      integer            , intent ( in) :: datatype
      integer            , intent ( in) :: attlen
      real               , intent ( in) :: values(*)
      integer            , intent (out) :: rcode
    end subroutine ncapt

    subroutine ncaptc (ncid,varid,attname,datatype,lenstr,string, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      character (len = *), intent ( in) :: attname
      integer            , intent ( in) :: datatype
      integer            , intent ( in) :: lenstr
      character (len = *), intent ( in) :: string
      integer            , intent (out) :: rcode
    end subroutine ncaptc

    subroutine ncainq (ncid,varid,attname, datatype,attlen,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      character (len = *), intent ( in) :: attname
      integer            , intent (out) :: datatype
      integer            , intent (out) :: attlen
      integer            , intent (out) :: rcode
    end subroutine ncainq

    subroutine ncagt (ncid,varid,attname, values,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      character (len = *), intent ( in) :: attname
      real               , intent (out) :: values
      integer            , intent (out) :: rcode
    end subroutine ncagt

    subroutine ncagtc (ncid,varid,attname, string,lenstr,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      character (len = *), intent ( in) :: attname
      character (len = *), intent (out) :: string
      integer            , intent ( in) :: lenstr
      integer            , intent (out) :: rcode
    end subroutine ncagtc

    subroutine ncacpy (inncid,invarid,attname,outncid,outvarid, rcode)
      integer            , intent ( in) :: inncid
      integer            , intent ( in) :: invarid
      character (len = *), intent ( in) :: attname
      integer            , intent ( in) :: outncid
      integer            , intent ( in) :: outvarid
      integer            , intent (out) :: rcode
    end subroutine ncacpy

    subroutine ncanam (ncid,varid,attnum, attname,rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      integer            , intent ( in) :: attnum
      character (len = *), intent (out) :: attname
      integer            , intent (out) :: rcode
    end subroutine ncanam

    subroutine ncaren (ncid,varid,attname,newname, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      character (len = *), intent ( in) :: attname
      character (len = *), intent ( in) :: newname
      integer            , intent (out) :: rcode
    end subroutine ncaren

    subroutine ncadel (ncid,varid,attname, rcode)
      integer            , intent ( in) :: ncid
      integer            , intent ( in) :: varid
      character (len = *), intent ( in) :: attname
      integer            , intent (out) :: rcode
    end subroutine ncadel
    
    integer function nctlen(type, rcode)
      integer            , intent ( in) :: type
      integer            , intent (out) :: rcode
    end function nctlen

    subroutine ncpopt (ncopts)
      integer            , intent ( in) :: ncopts
    end subroutine ncpopt

    subroutine ncgopt (ncopts)
      integer            , intent (out) :: ncopts
    end subroutine ncgopt

    integer function ncsfil(ncid, fillmode, rcode)
      integer            , intent ( in) :: ncid, fillmode
      integer            , intent (out) :: rcode
    end function ncsfil

  end interface
end module netcdf