This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
>To: address@hidden, >To: address@hidden >cc: address@hidden >From: Robert Pincus <address@hidden> >Subject: Fortran-90 module for netCDF API >Organization: Climate and Radiation Branch, NASA Goddard Space Flight Center >Keywords: 199606271905.AA04392 Hi Robert, > I am a regular user of the netCDF API to the HDF libraries. I'm also a > regular user of Fortran-90. To make my life easier, I've encapsulated the > information found in the "netcdf.inc" file (parameters for the > Fortran interface) in a Fortran-90 module. This includes the parameter > definitions as well as interface blocks for the Fortran-callable > functions (though not the subroutines). I have attached the code to this > email message. You are welcome to add it to the netCDF and/or HDF > distributions if you wish. 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. For version 3 of netCDF, we have defined a draft of a new type-safe interface for which this should no longer be a problem (but the old interface will still be supported for backwards compatibility). --Russ ______________________________________________________________________________ Russ Rew UCAR Unidata Program address@hidden http://www.unidata.ucar.edu ! Draft Fortran-90 interface block for the netCDF Fortran interface. ! ! Currently, this just uses type REAL for generic numeric values. This ! could be fixed to define a different interface name for each numeric ! type, with a generic interface that has the conventional name, but ! then we would have to define extra program units for INTEGER, REAL, ! and DOUBLE PRECISION types, something like: ! ! INTERFACE NCVPT ! SUBROUTINE NCVPT_INT (NCID,VARID,START,COUNTS,VALUES, rcode) ! INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN ! INTEGER, INTENT(IN) :: VARID ! variable ID ! INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be written ! INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be written ! INTEGER, INTENT(IN) :: VALUES(*) ! real values to be written ! INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors ! END SUBROUTINE NCVPT ! SUBROUTINE NCVPT_REAL (NCID,VARID,START,COUNTS,VALUES, rcode) ! INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN ! INTEGER, INTENT(IN) :: VARID ! variable ID ! INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be written ! INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be written ! REAL, INTENT(IN) :: VALUES(*) ! real values to be written ! INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors ! END SUBROUTINE NCVPT ! SUBROUTINE NCVPT_DOUBLE (NCID,VARID,START,COUNTS,VALUES, rcode) ! INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN ! INTEGER, INTENT(IN) :: VARID ! variable ID ! INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be written ! INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be written ! DOUBLE, INTENT(IN) :: VALUES(*) ! real values to be written ! INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors ! END SUBROUTINE NCVPT ! END INTERFACE INTERFACE ! Uses type REAL for generic numeric values FUNCTION NCCRE (FILENAME, CLOBMODE, rcode) INTEGER NCCRE CHARACTER (*), INTENT(IN) :: FILENAME ! name of netCDF file INTEGER, INTENT(IN) :: CLOBMODE ! either NCCLOB or NCNOCLOB INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END FUNCTION NCCRE FUNCTION NCOPN (FILENAME, RWMODE, rcode) INTEGER NCOPN CHARACTER(*), INTENT(IN) :: FILENAME INTEGER, INTENT(IN) :: RWMODE ! either NCWRITE or NCNOWRIT INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END FUNCTION NCOPN SUBROUTINE NCREDF (NCID, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCREDF SUBROUTINE NCENDF (NCID, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCENDF SUBROUTINE NCCLOS (NCID, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCCLOS SUBROUTINE NCINQ (NCID, ndims,nvars,natts,recdim,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(OUT) :: ndims ! number of dimensions in netCDF INTEGER, INTENT(OUT) :: nvars ! number of variables in netCDF INTEGER, INTENT(OUT) :: natts ! number of global attributes in netCDF INTEGER, INTENT(OUT) :: recdim ! dimension ID of unlimited dimension INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCINQ SUBROUTINE NCSNC (NCID, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCSNC SUBROUTINE NCABOR (NCID, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCABOR FUNCTION NCDDEF (NCID,DIMNAME,SIZE, rcode) INTEGER NCDDEF INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN CHARACTER (*), INTENT(IN) :: DIMNAME ! name for dimension INTEGER, INTENT(IN) :: SIZE ! size of dimension INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END FUNCTION NCDDEF FUNCTION NCDID (NCID,DIMNAME, rcode) INTEGER NCDID INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN CHARACTER (*), INTENT(IN) :: DIMNAME ! name for dimension INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END FUNCTION NCDID SUBROUTINE NCDINQ (NCID,DIMID, dimname,size,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: DIMID ! dimension ID from NCDDEF or NCDID CHARACTER (*), INTENT(OUT) :: dimname ! name for dimension INTEGER, INTENT(OUT) :: size ! size of dimension INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCDINQ SUBROUTINE NCDREN (NCID,DIMID,DIMNAME, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: DIMID ! dimension ID from NCDDEF or NCDID CHARACTER (*), INTENT(IN) :: DIMNAME ! new name for dimension INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCDREN FUNCTION NCVDEF (NCID,VARNAME,DATATYPE,NVDIMS,VDIMS, rcode) INTEGER NCVDEF INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN CHARACTER (*), INTENT(IN) :: VARNAME ! name for variable INTEGER, INTENT(IN) :: DATATYPE ! type, one of NCBYTE, ..., NCDOUBLE INTEGER, INTENT(IN) :: NVDIMS ! number of dimensions in shape INTEGER, INTENT(IN) :: VDIMS(NVDIMS) ! dimension IDs for shape INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END FUNCTION NCVDEF FUNCTION NCVID (NCID,VARNAME, rcode) INTEGER NCVID INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN CHARACTER (*), INTENT(IN) :: VARNAME ! name for variable INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END FUNCTION NCVID SUBROUTINE NCVINQ (NCID,VARID, varname,datatype,nvdims,vdims,nvatts,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID CHARACTER (*), INTENT(OUT) :: varname ! name for variable INTEGER, INTENT(OUT) :: datatype ! type, one of NCBYTE, ..., NCDOUBLE INTEGER, INTENT(OUT) :: nvdims ! number of dimensions in shape INTEGER, INTENT(OUT) :: vdims(nvdims) ! dimension IDs for shape INTEGER, INTENT(OUT) :: nvatts ! number of attributes INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVINQ SUBROUTINE NCVPT1 (NCID,VARID,INDICES,VALUE, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: INDICES(*) ! coordinates of element REAL, INTENT(IN) :: VALUE ! real value to be written INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVPT1 SUBROUTINE NCVP1C (NCID,VARID,INDICES, CHVAL, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: INDICES(*) ! coordinates of element CHARACTER, INTENT(IN) :: CHVAL ! character value to be written INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVP1C SUBROUTINE NCVGT1 (NCID,VARID,INDICES, value, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: INDICES(*) ! coordinates of element REAL, INTENT(OUT) :: value ! real value to be read INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVGT1 SUBROUTINE NCVG1C (NCID,VARID,INDICES, chval, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: INDICES(*) ! coordinates of element CHARACTER, INTENT(OUT) :: chval ! character value to be read INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVG1C SUBROUTINE NCVPT (NCID,VARID,START,COUNTS,VALUES, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be written INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be written REAL, INTENT(IN) :: VALUES(*) ! real values to be written INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVPT SUBROUTINE NCVPTC (NCID,VARID,START,COUNTS,STRING,LENSTR, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be written INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be written CHARACTER (*), INTENT(IN) :: STRING ! string value to be written INTEGER, INTENT(IN) :: LENSTR ! declared length of string INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVPTC SUBROUTINE NCVPTG (NCID,VARID,START,COUNTS,STRIDES,IMAP,VALUES, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be written INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be written INTEGER, INTENT(IN) :: STRIDES(*) ! dimensional strides INTEGER, INTENT(IN) :: IMAP(*) ! index mapping vector REAL, INTENT(IN) :: VALUES(*) ! real values to be written INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVPTG SUBROUTINE NCVPGC (NCID,VARID,START,COUNTS,STRIDES,IMAP,STRING,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be written INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be written INTEGER, INTENT(IN) :: STRIDES(*) ! dimensional strides INTEGER, INTENT(IN) :: IMAP(*) ! index mapping vector CHARACTER (*), INTENT(IN) :: STRING ! string value to be written INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVPGC SUBROUTINE NCVGT (NCID,VARID,START,COUNTS, values,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be read INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be read REAL, INTENT(OUT) :: values ! real values to be read INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVGT SUBROUTINE NCVGTC (NCID,VARID,START,COUNTS, string,LENSTR,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be read INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be read CHARACTER (*), INTENT(OUT) :: string ! string value to be read INTEGER, INTENT(IN) :: LENSTR ! declared length of string INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVGTC SUBROUTINE NCVGTG (NCID,VARID,START,COUNTS,STRIDES,IMAP,values,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be read INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be read INTEGER, INTENT(IN) :: STRIDES(*) ! dimensional strides INTEGER, INTENT(IN) :: IMAP(*) ! index mapping vector REAL, INTENT(OUT) :: values ! real values to be read INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVGTG SUBROUTINE NCVGGC (NCID,VARID,START,COUNTS,STRIDES,IMAP,string,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID INTEGER, INTENT(IN) :: START(*) ! corner of array of values to be read INTEGER, INTENT(IN) :: COUNTS(*) ! edges of array of values to be read INTEGER, INTENT(IN) :: STRIDES(*) ! dimensional strides INTEGER, INTENT(IN) :: IMAP(*) ! index mapping vector CHARACTER (*), INTENT(OUT) :: string ! string value to be read INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVGGC SUBROUTINE NCVREN (NCID,VARID,VARNAME, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID CHARACTER (*), INTENT(IN) :: VARNAME ! name for variable INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCVREN SUBROUTINE NCAPT (NCID,VARID,ATTNAME,DATATYPE,ATTLEN,VALUES, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID or NCGLOBAL CHARACTER (*), INTENT(IN) :: ATTNAME ! attribute name INTEGER, INTENT(IN) :: DATATYPE ! type, one of NCBYTE, ..., NCDOUBLE INTEGER, INTENT(IN) :: ATTLEN ! number of attribute values REAL, INTENT(IN) :: VALUES(*) ! real values to be written INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCAPT SUBROUTINE NCAPTC (NCID,VARID,ATTNAME,DATATYPE,LENSTR,STRING, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID or NCGLOBAL CHARACTER (*), INTENT(IN) :: ATTNAME ! attribute name INTEGER, INTENT(IN) :: DATATYPE ! type, one of NCBYTE, ..., NCDOUBLE INTEGER, INTENT(IN) :: LENSTR ! declared length of string CHARACTER (*), INTENT(IN) :: STRING ! string value to be written INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCAPTC SUBROUTINE NCAINQ (NCID,VARID,ATTNAME, datatype,attlen,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID or NCGLOBAL CHARACTER (*), INTENT(IN) :: ATTNAME ! attribute name INTEGER, INTENT(OUT) :: datatype ! type, one of NCBYTE, ..., NCDOUBLE INTEGER, INTENT(OUT) :: attlen ! number of attribute values INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCAINQ SUBROUTINE NCAGT (NCID,VARID,ATTNAME, values,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID or NCGLOBAL CHARACTER (*), INTENT(IN) :: ATTNAME ! attribute name REAL, INTENT(OUT) :: values ! real values to be read INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCAGT SUBROUTINE NCAGTC (NCID,VARID,ATTNAME, string,LENSTR,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID or NCGLOBAL CHARACTER (*), INTENT(IN) :: ATTNAME ! attribute name CHARACTER (*), INTENT(OUT) :: string ! string value to be read INTEGER, INTENT(IN) :: LENSTR ! declared length of string INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCAGTC SUBROUTINE NCACPY (INNCID,INVARID,ATTNAME,OUTNCID,OUTVARID, rcode) INTEGER, INTENT(IN) :: INNCID ! input netCDF ID INTEGER, INTENT(IN) :: INVARID ! input variable ID CHARACTER (*), INTENT(IN) :: ATTNAME ! attribute name INTEGER, INTENT(IN) :: OUTNCID ! output netCDF ID INTEGER, INTENT(IN) :: OUTVARID ! output variable ID INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCACPY SUBROUTINE NCANAM (NCID,VARID,ATTNUM, attname,rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID or NCGLOBAL INTEGER, INTENT(IN) :: ATTNUM ! attribute number CHARACTER (*), INTENT(OUT) :: attname ! attribute name INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCANAM SUBROUTINE NCAREN (NCID,VARID,ATTNAME,NEWNAME, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID or NCGLOBAL CHARACTER (*), INTENT(IN) :: ATTNAME ! attribute name CHARACTER (*), INTENT(IN) :: NEWNAME ! new attribute name INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCAREN SUBROUTINE NCADEL (NCID,VARID,ATTNAME, rcode) INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: VARID ! variable ID or NCGLOBAL CHARACTER (*), INTENT(IN) :: ATTNAME ! attribute name INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END SUBROUTINE NCADEL FUNCTION NCTLEN (DATATYPE, rcode) INTEGER NCTLEN INTEGER, INTENT(IN) :: DATATYPE ! type, one of NCBYTE, ..., NCDOUBLE INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END FUNCTION NCTLEN SUBROUTINE NCPOPT (NCOPTS) INTEGER, INTENT(IN) :: NCOPTS ! error-handling option flag END SUBROUTINE NCPOPT SUBROUTINE NCGOPT (ncopts) INTEGER, INTENT(OUT) :: ncopts ! error-handling option flag END SUBROUTINE NCGOPT FUNCTION NCSFIL (NCID,FILLMODE, rcode) INTEGER NCSFIL INTEGER, INTENT(IN) :: NCID ! netCDF ID, returned by NCCRE or NCOPN INTEGER, INTENT(IN) :: FILLMODE ! NCNOFILL or NCFILL INTEGER, INTENT(OUT) :: rcode ! returned error code, 0 if no errors END FUNCTION NCSFIL END INTERFACE