a clean commit for #383

This commit is contained in:
Wei-keng Liao 2017-12-20 20:53:30 -06:00
parent 0f7118107e
commit 0f4a85b9f2
18 changed files with 360 additions and 116 deletions

View File

@ -1302,6 +1302,11 @@ IF(SIZEOF_UINT)
SET(HAVE_UINT TRUE)
ENDIF(SIZEOF_UINT)
CHECK_TYPE_SIZE("schar" SIZEOF_SCHAR)
IF(SIZEOF_SCHAR)
SET(HAVE_SCHAR TRUE)
ENDIF(SIZEOF_SCHAR)
CHECK_TYPE_SIZE("long" SIZEOF_LONG)
CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG)
IF(SIZEOF_LONG_LONG)

View File

@ -158,7 +158,8 @@ NC3_def_var(int ncid, const char *name,
extern int
NC3_inq_var(int ncid, int varid, char *name,
nc_type *xtypep, int *ndimsp, int *dimidsp, int *nattsp);
nc_type *xtypep, int *ndimsp, int *dimidsp, int *nattsp,
int *no_fill, void *fill_valuep);
extern int
NC3_inq_varid(int ncid, const char *name, int *varidp);
@ -166,6 +167,8 @@ NC3_inq_varid(int ncid, const char *name, int *varidp);
extern int
NC3_rename_var(int ncid, int varid, const char *name);
extern int
NC3_def_var_fill(int,int,int,const void*);
extern int
NC3_put_vara(int ncid, int varid,

View File

@ -186,6 +186,7 @@ typedef struct NC_var {
nc_type type; /* the discriminant */
size_t len; /* the total length originally allocated */
off_t begin;
int no_fill; /* whether fill mode is ON or OFF */
} NC_var;
typedef struct NC_vararray {

View File

@ -9,7 +9,9 @@
#ifndef _DISPATCH_H
#define _DISPATCH_H
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -250,6 +252,7 @@ int (*inq_var_all)(int ncid, int varid, char *name, nc_type *xtypep,
);
int (*var_par_access)(int, int, int);
int (*def_var_fill)(int, int, int, const void*);
/* Note the following may still be invoked by netcdf client code
even when the file is a classic file; they will just return an error or
@ -289,7 +292,6 @@ int (*def_opaque)(int, size_t, const char*, nc_type*);
int (*def_var_deflate)(int, int, int, int, int);
int (*def_var_fletcher32)(int, int, int);
int (*def_var_chunking)(int, int, int, const size_t*);
int (*def_var_fill)(int, int, int, const void*);
int (*def_var_endian)(int, int, int);
int (*def_var_filter)(int, int, unsigned int, size_t, const unsigned int*);
int (*set_var_chunk_cache)(int, int, size_t, size_t, float);

View File

@ -137,6 +137,7 @@ NCDEFAULT_put_varm,
NCD2_inq_var_all,
NCD2_var_par_access,
NCD2_def_var_fill,
#ifdef USE_NETCDF4
NCD2_show_metadata,
@ -172,7 +173,6 @@ NCD2_def_opaque,
NCD2_def_var_deflate,
NCD2_def_var_fletcher32,
NCD2_def_var_chunking,
NCD2_def_var_fill,
NCD2_def_var_endian,
NCD2_def_var_filter,
NCD2_set_var_chunk_cache,
@ -2434,6 +2434,15 @@ NCD2_var_par_access(int ncid, int p2, int p3)
return THROW(NC_ENOPAR);
}
int
NCD2_def_var_fill(int ncid, int p2, int p3, const void* p4)
{
NC* drno;
int ret;
if((ret = NC_check_id(ncid, (NC**)&drno)) != NC_NOERR) return THROW(ret);
ret = nc_def_var_fill(getnc3id(drno), p2, p3, p4);
return THROW(ret);
}
#ifdef USE_NETCDF4
@ -2763,16 +2772,6 @@ NCD2_def_var_chunking(int ncid, int p2, int p3, const size_t* p4)
return THROW(ret);
}
int
NCD2_def_var_fill(int ncid, int p2, int p3, const void* p4)
{
NC* drno;
int ret;
if((ret = NC_check_id(ncid, (NC**)&drno)) != NC_NOERR) return THROW(ret);
ret = nc_def_var_fill(getnc3id(drno), p2, p3, p4);
return THROW(ret);
}
int
NCD2_def_var_endian(int ncid, int p2, int p3)
{

View File

@ -158,6 +158,9 @@ NCD2_rename_var(int ncid, int varid, const char *name);
extern int
NCD2_var_par_access(int, int, int);
extern int
NCD2_def_var_fill(int, int, int, const void *);
/* netCDF4 API only */
#ifdef USE_NETCDF4
extern int
@ -241,9 +244,6 @@ NCD2_var_par_access(int, int, int);
extern int
NCD2_def_var_chunking(int, int, int, const size_t *);
extern int
NCD2_def_var_fill(int, int, int, const void *);
extern int
NCD2_def_var_endian(int, int, int);

View File

@ -853,6 +853,7 @@ NCDEFAULT_put_varm,
NCD4_inq_var_all,
NCD4_var_par_access,
NCD4_def_var_fill,
#ifdef USE_NETCDF4
NCD4_show_metadata,
@ -888,7 +889,6 @@ NCD4_def_opaque,
NCD4_def_var_deflate,
NCD4_def_var_fletcher32,
NCD4_def_var_chunking,
NCD4_def_var_fill,
NCD4_def_var_endian,
NCD4_def_var_filter,
NCD4_set_var_chunk_cache,

View File

@ -538,6 +538,79 @@ NC_getshape(int ncid, int varid, int ndims, size_t* shape)
return status;
}
/*! Set the fill value for a variable.
\ingroup variables
\param ncid NetCDF ID, from a previous call to nc_open or
nc_create.
\param varid Variable ID.
\param no_fill Set to NC_NOFILL to turn off fill mode for this
variable. Set to NC_FILL (the default) to turn on fill mode for the
variable.
\param fill_value the fill value to be used for this variable. Must be
the same type as the variable. This must point to enough free memory
to hold one element of the data type of the variable. (For example, an
NC_INT will require 4 bytes for it's fill value, which is also an
NC_INT.)
* @returns ::NC_NOERR No error.
* @returns ::NC_EBADID Bad ID.
* @returns ::NC_ENOTINDEFINE Not in define mode. This is returned for
netCDF classic, 64-bit offset, or 64-bit data files, or for netCDF-4 files,
when they were created with NC_STRICT_NC3 flag. See \ref nc_create.
* @returns ::NC_EPERM Attempt to create object in read-only file.
\section nc_def_var_fill_example Example
In this example from libsrc4/tst_vars.c, a variable is defined, and
the fill mode turned off. Then nc_inq_fill() is used to check that the
setting is correct. Then some data are written to the variable. Since
the data that are written do not cover the full extent of the
variable, the missing values will just be random. If fill value mode
was turned on, the missing values would get the fill value.
\code
#define DIM7_LEN 2
#define DIM7_NAME "dim_7_from_Indiana"
#define VAR7_NAME "var_7_from_Idaho"
#define NDIMS 1
int dimids[NDIMS];
size_t index[NDIMS];
int varid;
int no_fill;
unsigned short ushort_data = 42, ushort_data_in, fill_value_in;
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
&varid)) ERR;
if (nc_def_var_fill(ncid, varid, 1, NULL)) ERR;
if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
if (!no_fill) ERR;
index[0] = 1;
if (nc_put_var1_ushort(ncid, varid, index, &ushort_data)) ERR;
index[0] = 0;
if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR;
if (nc_close(ncid)) ERR;
\endcode
*/
int
nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
{
NC* ncp;
int stat = NC_check_id(ncid,&ncp);
if(stat != NC_NOERR) return stat;
return ncp->dispatch->def_var_fill(ncid,varid,no_fill,fill_value);
}
#ifdef USE_NETCDF4
/** \ingroup variables
@ -899,80 +972,6 @@ nc_def_var_chunking(int ncid, int varid, int storage,
chunksizesp);
}
/*! Set the fill value for a netCDF4/HDF5 variable.
\ingroup variables
\param ncid NetCDF ID, from a previous call to nc_open or
nc_create.
\param varid Variable ID.
\param no_fill Set to NC_NOFILL to turn off fill mode for this
variable. Set to NC_FILL (the default) to turn on fill mode for the
variable.
\param fill_value the fill value to be used for this variable. Must be
the same type as the variable. This must point to enough free memory
to hold one element of the data type of the variable. (For example, an
NC_INT will require 4 bytes for it's fill value, which is also an
NC_INT.)
* @returns ::NC_NOERR No error.
* @returns ::NC_EBADID Bad ID.
* @returns ::NC_ENOTNC4 Not a netCDF-4 file.
* @returns ::NC_ENOTINDEFINE Not in define mode. This is returned for
netCDF classic or 64-bit offset files, or for netCDF-4 files, when
they wwere created with NC_STRICT_NC3 flag. See \ref nc_create.
* @returns ::NC_EPERM Attempt to create object in read-only file.
\section nc_def_var_fill_example Example
In this example from libsrc4/tst_vars.c, a variable is defined, and
the fill mode turned off. Then nc_inq_fill() is used to check that the
setting is correct. Then some data are written to the variable. Since
the data that are written do not cover the full extent of the
variable, the missing values will just be random. If fill value mode
was turned on, the missing values would get the fill value.
\code
#define DIM7_LEN 2
#define DIM7_NAME "dim_7_from_Indiana"
#define VAR7_NAME "var_7_from_Idaho"
#define NDIMS 1
int dimids[NDIMS];
size_t index[NDIMS];
int varid;
int no_fill;
unsigned short ushort_data = 42, ushort_data_in, fill_value_in;
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
&varid)) ERR;
if (nc_def_var_fill(ncid, varid, 1, NULL)) ERR;
if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
if (!no_fill) ERR;
index[0] = 1;
if (nc_put_var1_ushort(ncid, varid, index, &ushort_data)) ERR;
index[0] = 0;
if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR;
if (nc_close(ncid)) ERR;
\endcode
*/
int
nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
{
NC* ncp;
int stat = NC_check_id(ncid,&ncp);
if(stat != NC_NOERR) return stat;
return ncp->dispatch->def_var_fill(ncid,varid,no_fill,fill_value);
}
/**
@ingroup variables

View File

@ -836,6 +836,18 @@ NC3_put_att(
if(nelems != 0 && value == NULL)
return NC_EINVAL; /* Null arg */
if (varid != NC_GLOBAL && !strcmp(name, _FillValue)) {
/* Fill value must be of the same data type */
if (type != ncp->vars.value[varid]->type) return NC_EBADTYPE;
/* Fill value must have exactly one value */
if (nelems != 1) return NC_EINVAL;
/* Only allow for variables defined in initial define mode */
if (ncp->old != NULL && varid < ncp->old->vars.nelems)
return NC_ELATEFILL; /* try put attribute for an old variable */
}
attrpp = NC_findattr(ncap, name);
/* 4 cases: exists X indef */

View File

@ -73,7 +73,6 @@ static int NC3_def_opaque(int,size_t,const char*,nc_type*);
static int NC3_def_var_deflate(int,int,int,int,int);
static int NC3_def_var_fletcher32(int,int,int);
static int NC3_def_var_chunking(int,int,int,const size_t*);
static int NC3_def_var_fill(int,int,int,const void*);
static int NC3_def_var_endian(int,int,int);
static int NC3_def_var_filter(int, int, unsigned int, size_t, const unsigned int*);
@ -129,6 +128,7 @@ NCDEFAULT_put_varm,
NC3_inq_var_all,
NC3_var_par_access,
NC3_def_var_fill,
#ifdef USE_NETCDF4
NC3_show_metadata,
@ -164,7 +164,6 @@ NC3_def_opaque,
NC3_def_var_deflate,
NC3_def_var_fletcher32,
NC3_def_var_chunking,
NC3_def_var_fill,
NC3_def_var_endian,
NC3_def_var_filter,
NC3_set_var_chunk_cache,
@ -198,13 +197,12 @@ NC3_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
unsigned int* idp, size_t* nparamsp, unsigned int* params
)
{
int stat = NC3_inq_var(ncid,varid,name,xtypep,ndimsp,dimidsp,nattsp);
int stat = NC3_inq_var(ncid,varid,name,xtypep,ndimsp,dimidsp,nattsp,no_fill,fill_valuep);
if(stat) return stat;
if(shufflep) *shufflep = 0;
if(deflatep) *deflatep = 0;
if(fletcher32p) *fletcher32p = 0;
if(contiguousp) *contiguousp = NC_CONTIGUOUS;
if(no_fill) *no_fill = 1;
if(endiannessp) return NC_ENOTNC4;
if(idp) return NC_ENOTNC4;
if(nparamsp) return NC_ENOTNC4;
@ -506,12 +504,6 @@ NC3_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksiz
return NC_ENOTNC4;
}
static int
NC3_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
{
return NC_ENOTNC4;
}
static int
NC3_def_var_endian(int ncid, int varid, int endianness)
{

View File

@ -490,12 +490,13 @@ fillerup(NC3_INFO *ncp)
NC_var **varpp;
assert(!NC_readonly(ncp));
assert(NC_dofill(ncp));
/* loop thru vars */
varpp = ncp->vars.value;
for(ii = 0; ii < ncp->vars.nelems; ii++, varpp++)
{
if ((*varpp)->no_fill) continue;
if(IS_RECVAR(*varpp))
{
/* skip record variables */
@ -538,6 +539,9 @@ fill_added_recs(NC3_INFO *gnu, NC3_INFO *old)
for(; varid < (int)gnu->vars.nelems; varid++)
{
const NC_var *const gnu_varp = *(gnu_varpp + varid);
if (gnu_varp->no_fill) continue;
if(!IS_RECVAR(gnu_varp))
{
/* skip non-record variables */
@ -566,6 +570,9 @@ fill_added(NC3_INFO *gnu, NC3_INFO *old)
for(; varid < (int)gnu->vars.nelems; varid++)
{
const NC_var *const gnu_varp = *(gnu_varpp + varid);
if (gnu_varp->no_fill) continue;
if(IS_RECVAR(gnu_varp))
{
/* skip record variables */
@ -840,7 +847,7 @@ NC_endef(NC3_INFO *ncp,
if(status != NC_NOERR)
return status;
if(NC_dofill(ncp))
/* fill mode is now per variable */
{
if(NC_IsNew(ncp))
{
@ -1432,7 +1439,7 @@ int
NC3_set_fill(int ncid,
int fillmode, int *old_mode_ptr)
{
int status;
int i, status;
NC *nc;
NC3_INFO* nc3;
int oldmode;
@ -1473,6 +1480,14 @@ NC3_set_fill(int ncid,
if(old_mode_ptr != NULL)
*old_mode_ptr = oldmode;
/* loop thru all variables to set/overwrite its fill mode */
for (i=0; i<nc3->vars.nelems; i++)
nc3->vars.value[i]->no_fill = (fillmode == NC_NOFILL);
/* once the file's fill mode is set, any new variables defined after
* this call will check NC_dofill(nc3) and set their no_fill accordingly.
* See NC3_def_var() */
return NC_NOERR;
}

View File

@ -16,6 +16,7 @@
#include "ncx.h"
#include "rnd.h"
#include "ncutf8.h"
#include "nc3dispatch.h"
#ifndef OFF_T_MAX
#if 0
@ -637,6 +638,13 @@ NC3_def_var( int ncid, const char *name, nc_type type,
if(varidp != NULL)
*varidp = (int)ncp->vars.nelems -1; /* varid */
/* set the variable's fill mode */
if (NC_dofill(ncp))
varp->no_fill = 0;
else
varp->no_fill = 1;
return NC_NOERR;
}
@ -673,7 +681,9 @@ NC3_inq_var(int ncid,
nc_type *typep,
int *ndimsp,
int *dimids,
int *nattsp)
int *nattsp,
int *no_fillp,
void *fill_valuep)
{
int status;
NC *nc;
@ -714,6 +724,18 @@ NC3_inq_var(int ncid,
*nattsp = (int) varp->attrs.nelems;
}
if (no_fillp != NULL) *no_fillp = varp->no_fill;
if (fill_valuep != NULL) {
status = nc_get_att(ncid, varid, _FillValue, fill_valuep);
if (status != NC_NOERR && status != NC_ENOTATT)
return status;
if (status == NC_ENOTATT) {
status = NC3_inq_default_fill_value(varp->type, fill_valuep);
if (status != NC_NOERR) return status;
}
}
return NC_NOERR;
}
@ -799,3 +821,55 @@ NC3_rename_var(int ncid, int varid, const char *unewname)
return NC_NOERR;
}
int
NC3_def_var_fill(int ncid,
int varid,
int no_fill,
const void *fill_value)
{
int status;
NC *nc;
NC3_INFO* ncp;
NC_var *varp;
status = NC_check_id(ncid, &nc);
if(status != NC_NOERR)
return status;
ncp = NC3_DATA(nc);
if(NC_readonly(ncp))
{
return NC_EPERM;
}
if(!NC_indef(ncp))
{
return NC_ENOTINDEFINE;
}
varp = elem_NC_vararray(&ncp->vars, (size_t)varid);
if(varp == NULL)
return NC_ENOTVAR;
if (no_fill)
varp->no_fill = 1;
else
varp->no_fill = 0;
/* Are we setting a fill value? */
if (fill_value != NULL && !varp->no_fill) {
/* If there's a _FillValue attribute, delete it. */
status = NC3_del_att(ncid, varid, _FillValue);
if (status != NC_NOERR && status != NC_ENOTATT)
return status;
/* Create/overwrite attribute _FillValue */
status = NC3_put_att(ncid, varid, _FillValue, varp->type, 1, fill_value, varp->type);
if (status != NC_NOERR) return status;
}
return NC_NOERR;
}

View File

@ -57,6 +57,7 @@ NCDEFAULT_put_varm,
NC4_inq_var_all,
NC4_var_par_access,
NC4_def_var_fill,
NC4_show_metadata,
NC4_inq_unlimdims,
@ -92,7 +93,6 @@ NC4_def_opaque,
NC4_def_var_deflate,
NC4_def_var_fletcher32,
NC4_def_var_chunking,
NC4_def_var_fill,
NC4_def_var_endian,
NC4_def_var_filter,
NC4_set_var_chunk_cache,

View File

@ -1171,7 +1171,7 @@ NCP_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
if(deflatep) *deflatep = 0;
if(fletcher32p) *fletcher32p = 0;
if(contiguousp) *contiguousp = NC_CONTIGUOUS;
if(no_fill) *no_fill = 1;
if(no_fill) ncmpi_inq_var_fill(nc->int_ncid, varid, no_fill, fill_valuep);
if(endiannessp) return NC_ENOTNC4;
if(idp) return NC_ENOTNC4;
if(nparamsp) return NC_ENOTNC4;
@ -1179,6 +1179,15 @@ NCP_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
return NC_NOERR;
}
static int
NCP_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
{
NC* nc;
int status = NC_check_id(ncid, &nc);
if(status != NC_NOERR) return status;
return ncmpi_def_var_fill(nc->int_ncid, varid, no_fill, fill_value);
}
static int
NCP_var_par_access(int ncid, int varid, int par_access)
{
@ -1492,12 +1501,6 @@ NCP_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksiz
return NC_ENOTNC4;
}
static int
NCP_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
{
return NC_ENOTNC4;
}
static int
NCP_def_var_endian(int ncid, int varid, int endianness)
{
@ -1563,6 +1566,7 @@ NCP_put_varm,
NCP_inq_var_all,
NCP_var_par_access,
NCP_def_var_fill,
#ifdef USE_NETCDF4
NCP_show_metadata,
@ -1599,7 +1603,6 @@ NCP_def_opaque,
NCP_def_var_deflate,
NCP_def_var_fletcher32,
NCP_def_var_chunking,
NCP_def_var_fill,
NCP_def_var_endian,
NCP_def_var_filter,
NCP_set_var_chunk_cache,

View File

@ -30,7 +30,7 @@ TARGET_LINK_LIBRARIES(nc_test
)
# Some extra stand-alone tests
SET(TESTS t_nc tst_small tst_misc tst_norm tst_names tst_nofill tst_nofill2 tst_nofill3 tst_meta tst_inq_type tst_global_fillval)
SET(TESTS t_nc tst_small tst_misc tst_norm tst_names tst_nofill tst_nofill2 tst_nofill3 tst_meta tst_inq_type tst_utf8_validate tst_utf8_phrases tst_global_fillval tst_max_var_dims tst_formats tst_def_var_fill)
IF(NOT HAVE_BASH)
SET(TESTS ${TESTS} tst_atts3)

View File

@ -20,7 +20,7 @@ TEST_EXTENSIONS = .sh
TESTPROGRAMS = t_nc tst_small nc_test tst_misc tst_norm tst_names \
tst_nofill tst_nofill2 tst_nofill3 tst_atts3 tst_meta tst_inq_type \
tst_utf8_validate tst_utf8_phrases tst_global_fillval \
tst_max_var_dims tst_formats
tst_max_var_dims tst_formats tst_def_var_fill
if USE_NETCDF4
TESTPROGRAMS += tst_atts tst_put_vars tst_elatefill

View File

@ -2361,6 +2361,23 @@ ifdef(`PNETCDF', `
ELSE_NOK
}
}
/* enter redef mode and add a new variable, check NC_ELATEFILL */
err = APIFunc(redef)(ncid);
IF (err != NC_NOERR)
error("redef: %s", APIFunc(strerror)(err));
/* it is not allowed to define fill value when variable already exists */
err = APIFunc(def_var_fill)(ncid, 0, 0, &value);
IF (err != NC_ELATEFILL)
error("redef: expect NC_ELATEFILL but got %s", nc_err_code_name(err));
err = APIFunc(def_var)(ncid, "new_var", NC_INT, 0, NULL, &varid);
IF (err != NC_NOERR)
error("redef: %s", APIFunc(strerror)(err));
err = APIFunc(def_var_fill)(ncid, varid, 0, &value);
IF (err != NC_NOERR)
error("def_var_fill: %s", APIFunc(strerror)(err));
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));

122
nc_test/tst_def_var_fill.c Normal file
View File

@ -0,0 +1,122 @@
/* This is part of the netCDF package.
* Copyright 2005 University Corporation for Atmospheric Research/Unidata
* See COPYRIGHT file for conditions of use.
*
* Test per-variable fill mode for classic file formats.
*
* Author: Wei-keng Liao.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h> /* basename() */
#include <netcdf.h>
#define CHECK_ERR { \
if (err != NC_NOERR) { \
nerrs++; \
printf("Error at line %d in %s: (%s)\n", \
__LINE__,__FILE__,nc_strerror(err)); \
} \
}
#define NY 8
#define NX 5
int main(int argc, char** argv) {
char filename[256];
int i, j, err, nerrs=0, ncid, varid[2], dimid[2], *buf;
size_t start[2], count[2];
if (argc > 2) {
printf("Usage: %s [filename]\n",argv[0]);
return 1;
}
if (argc == 2) snprintf(filename, 256, "%s", argv[1]);
else strcpy(filename, "testfile.nc");
char *cmd_str = (char*)malloc(strlen(argv[0]) + 256);
sprintf(cmd_str, "*** TESTING C %s for def_var_fill ", basename(argv[0]));
printf("%-66s ------ ", cmd_str); fflush(stdout);
free(cmd_str);
/* create a new file for writing ----------------------------------------*/
err = nc_create(filename, NC_CLOBBER, &ncid); CHECK_ERR
/* define dimension */
err = nc_def_dim(ncid, "Y", NY, &dimid[0]); CHECK_ERR
err = nc_def_dim(ncid, "X", NX, &dimid[1]); CHECK_ERR
/* define variables */
err = nc_def_var(ncid, "var_nofill", NC_INT, 2, dimid, &varid[0]); CHECK_ERR
err = nc_def_var(ncid, "var_fill", NC_INT, 2, dimid, &varid[1]); CHECK_ERR
/* set fill mode for variables */
err = nc_def_var_fill(ncid, varid[0], 1, NULL); CHECK_ERR
err = nc_def_var_fill(ncid, varid[1], 0, NULL); CHECK_ERR
err = nc_enddef(ncid); CHECK_ERR
/* write a subarray to both variables */
buf = (int*) malloc(NY*NX * sizeof(int));
for (i=0; i<NY*NX; i++) buf[i] = 5;
start[0] = 0;
start[1] = 2;
count[0] = NY;
count[1] = 2;
err = nc_put_vara_int(ncid, varid[0], start, count, buf); CHECK_ERR
err = nc_put_vara_int(ncid, varid[1], start, count, buf); CHECK_ERR
err = nc_close(ncid); CHECK_ERR
/* Now, reopen the file and read variables back */
err = nc_open(filename, NC_WRITE, &ncid); CHECK_ERR
/* get variable IDs */
err = nc_inq_varid(ncid, "var_nofill", &varid[0]); CHECK_ERR
err = nc_inq_varid(ncid, "var_fill", &varid[1]); CHECK_ERR
/* read variable "var_nofill" and check contents */
for (i=0; i<NY*NX; i++) buf[i] = -1;
err = nc_get_var_int(ncid, varid[0], buf); CHECK_ERR
for (i=0; i<NY; i++) {
for (j=0; j<NX; j++) {
if (2 <= j && j < 4) {
if (buf[i*NX+j] != 5) {
printf("Error at line %d in %s: expect get buf[%d]=%d but got %d\n",
__LINE__,__FILE__,i*NX+j, 5, buf[i*NX+j]);
nerrs++;
}
}
else if (buf[i*NX+j] == NC_FILL_INT) {
printf("Warning at line %d in %s: get buf[%d] same as NC_FILL_INT\n",
__LINE__,__FILE__,i*NX+j);
}
}
}
/* read variable "var_fill" and check contents */
for (i=0; i<NY*NX; i++) buf[i] = -1;
err = nc_get_var_int(ncid, varid[1], buf); CHECK_ERR
for (i=0; i<NY; i++) {
for (j=0; j<NX; j++) {
int expect = NC_FILL_INT;
if (2 <= j && j< 4) expect = 5;
if (buf[i*NX+j] != expect) {
printf("Error at line %d in %s: expect get buf[%d]=%d but got %d\n",
__LINE__,__FILE__,i*NX+j, expect, buf[i*NX+j]);
nerrs++;
}
}
}
err = nc_close(ncid); CHECK_ERR
free(buf);
if (nerrs) printf("fail with %d mismatches\n",nerrs);
else printf("pass\n");
return (nerrs > 0);
}