Merge branch 'master' into ansifix.dmh

This commit is contained in:
Ward Fisher 2019-01-02 22:26:59 -08:00
commit c21820a1ae
24 changed files with 11097 additions and 893 deletions

View File

@ -550,13 +550,12 @@ if test "x$enable_large_file_tests" = xyes; then
fi
# Does the user want to run benchmarks?
AC_MSG_CHECKING([whether benchmarks should be run (experimental)])
AC_MSG_CHECKING([whether benchmarks should be run])
AC_ARG_ENABLE([benchmarks],
[AS_HELP_STRING([--enable-benchmarks],
[Run benchmarks. This is an experimental feature. You must fetch
sample data files from the Unidata ftp site to use these benchmarks.
The benchmarks are a bunch of extra tests, which are timed. We use these
tests to check netCDF performance.])])
[Run benchmarks. This will cause sample data files from the Unidata ftp
site to be fetched. The benchmarks are a bunch of extra tests, which
are timed. We use these tests to check netCDF performance.])])
test "x$enable_benchmarks" = xyes || enable_benchmarks=no
AC_MSG_RESULT($enable_benchmarks)
AM_CONDITIONAL(BUILD_BENCHMARKS, [test x$enable_benchmarks = xyes])

View File

@ -1,5 +1,6 @@
This directory contains various scripts for debugging by Dennis
Heimbigner @ Unidata.
DO NOT DELETE.
USE AT YOUR OWN PERIL.

View File

@ -36,7 +36,7 @@ check_inq_format(int ncid, int expected_format, int expected_extended_format, in
if (nc_inq_format_extended(ncid, NULL, &mode)) ERR;
if (mode != expected_mode) {
printf("expected_mode %x mode %x\n", expected_mode, mode);
//ERR;
/*ERR;*/
}
}
{

View File

@ -105,7 +105,6 @@ int hdf5_set_log_level();
int rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
int rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
int delete_existing_dimscale_dataset(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T *dim);
int nc4_rec_match_dimscales(NC_GRP_INFO_T *grp);
/* Write metadata. */
int nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order);
@ -137,7 +136,6 @@ extern hid_t NC4_image_init(NC_FILE_INFO_T* h5);
extern void NC4_image_finalize(void*);
/* These functions are internal to the libhdf5 directory. */
int nc4_detect_preserve_dimids(NC_GRP_INFO_T *grp, nc_bool_t *bad_coord_orderp);
int nc4_get_fill_value(NC_FILE_INFO_T *h5, NC_VAR_INFO_T *var, void **fillp);

View File

@ -141,10 +141,10 @@ typedef struct NC_VAR_INFO
{
NC_OBJ hdr;
char *hdf5_name; /* used if different from name */
struct NC_GRP_INFO* container; /* containing group */
struct NC_GRP_INFO *container; /* containing group */
size_t ndims;
int *dimids;
NC_DIM_INFO_T** dim;
NC_DIM_INFO_T **dim;
nc_bool_t is_new_var; /* True if variable is newly created */
nc_bool_t was_coord_var; /* True if variable was a coordinate var, but either the dim or var has been renamed */
nc_bool_t became_coord_var; /* True if variable _became_ a coordinate var, because either the dim or var has been renamed */
@ -154,7 +154,7 @@ typedef struct NC_VAR_INFO
nc_bool_t written_to; /* True if variable has data written to it */
struct NC_TYPE_INFO *type_info;
int atts_not_read; /* If true, the atts have not yet been read. */
NCindex* att; /* NCindex<NC_ATT_INFO_T*> */
NCindex *att; /* NCindex<NC_ATT_INFO_T*> */
nc_bool_t no_fill; /* True if no fill value is defined for var */
void *fill_value;
size_t *chunksizes;
@ -172,7 +172,7 @@ typedef struct NC_VAR_INFO
/* Stuff for arbitrary filters */
unsigned int filterid;
size_t nparams;
unsigned int* params;
unsigned int *params;
} NC_VAR_INFO_T;
typedef struct NC_FIELD_INFO

View File

@ -6,8 +6,6 @@
* info and/or displaying provenance info.
*
* @author Dennis Heimbigner, Ward Fisher
*/
/**
It has come to pass that we can't guarantee that this information is
contained only within netcdf4 files. As a result, we need

View File

@ -122,7 +122,7 @@ NCD4_reclaimMeta(NCD4meta* dataset)
for(i=0;i<nclistlength(dataset->allnodes);i++) {
NCD4node* node = (NCD4node*)nclistget(dataset->allnodes,i);
reclaimNode(node);
}
}
nullfree(dataset->error.parseerror);
nullfree(dataset->error.message);
nullfree(dataset->error.context);
@ -193,7 +193,7 @@ build(NCD4meta* builder, NCD4node* root)
case NC_STRUCT:
/* We need to compute the field offsets in order to compute the struct size */
computeOffsets(builder,x);
break;
break;
}
}
@ -279,7 +279,7 @@ buildGroups(NCD4meta* builder, NCD4node* parent)
fprintf(stderr,"build group: %s\n",parent->name);
#endif
/* Define any group level attributes */
if((ret = buildAttributes(builder,parent))) goto done;
if((ret = buildAttributes(builder,parent))) goto done;
for(i=0;i<nclistlength(parent->groups);i++) {
NCD4node* g = (NCD4node*)nclistget(parent->groups,i);
@ -302,7 +302,7 @@ buildDimension(NCD4meta* builder, NCD4node* dim)
NCD4node* group = NCD4_groupFor(dim);
if(dim->dim.isunlimited) {
NCCHECK((nc_def_dim(group->meta.id,dim->name,NC_UNLIMITED,&dim->meta.id)));
} else {
} else {
NCCHECK((nc_def_dim(group->meta.id,dim->name,(size_t)dim->dim.size,&dim->meta.id)));
}
done:
@ -315,7 +315,7 @@ buildEnumeration(NCD4meta* builder, NCD4node* en)
int i,ret = NC_NOERR;
NCD4node* group = NCD4_groupFor(en);
NCCHECK((nc_def_enum(group->meta.id,en->basetype->meta.id,en->name,&en->meta.id)));
for(i=0;i<nclistlength(en->en.econsts);i++) {
for(i=0;i<nclistlength(en->en.econsts);i++) {
NCD4node* ec = (NCD4node*)nclistget(en->en.econsts,i);
NCCHECK((nc_insert_enum(group->meta.id, en->meta.id, ec->name, ec->en.ecvalue.i8)));
}
@ -334,7 +334,7 @@ buildOpaque(NCD4meta* builder, NCD4node* op)
/* Two cases, with and without UCARTAGORIGTYPE */
if(op->nc4.orig.name != NULL) {
name = op->nc4.orig.name;
group = op->nc4.orig.group;
group = op->nc4.orig.group;
}
NCCHECK((nc_def_opaque(group->meta.id,op->opaque.size,name,&op->meta.id)));
done:
@ -384,8 +384,8 @@ static int
buildMetaData(NCD4meta* builder, NCD4node* var)
{
int ret = NC_NOERR;
if((ret = buildAttributes(builder,var))) goto done;
if((ret = buildMaps(builder,var))) goto done;
if((ret = buildAttributes(builder,var))) goto done;
if((ret = buildMaps(builder,var))) goto done;
done:
return THROW(ret);
}
@ -476,7 +476,7 @@ buildStructureType(NCD4meta* builder, NCD4node* structtype)
/* Step 2: See if already defined */
if(nc_inq_typeid(group->meta.id,name,&tid) == NC_NOERR) {/* Already exists */
FAIL(NC_ENAMEINUSE,"Inferred type name conflict",name);
}
}
/* Since netcdf does not support forward references,
we presume all field types are defined */
@ -509,7 +509,7 @@ buildVlenType(NCD4meta* builder, NCD4node* vlentype)
/* See if already defined */
if(nc_inq_typeid(group->meta.id,name,&tid) == NC_NOERR) {/* Already exists */
FAIL(NC_ENAMEINUSE,"Inferred type name conflict",name);
}
}
/* Get the baseline type */
basetype = vlentype->basetype;
@ -533,7 +533,7 @@ buildCompound(NCD4meta* builder, NCD4node* cmpdtype, NCD4node* group, char* name
NCCHECK((nc_def_compound(group->meta.id,(size_t)cmpdtype->meta.memsize,name,&cmpdtype->meta.id)));
/* Step 3: add the fields to type */
for(i=0;i<nclistlength(cmpdtype->vars);i++) {
for(i=0;i<nclistlength(cmpdtype->vars);i++) {
int rank;
int dimsizes[NC_MAX_VAR_DIMS];
NCD4node* field = (NCD4node*)nclistget(cmpdtype->vars,i);
@ -579,7 +579,7 @@ buildAtomicVar(NCD4meta* builder, NCD4node* var)
savevarbyid(group,var);
/* Build attributes and map attributes */
if((ret = buildMetaData(builder,var))) goto done;
if((ret = buildMetaData(builder,var))) goto done;
done:
return THROW(ret);
}
@ -601,7 +601,7 @@ buildStructure(NCD4meta* builder, NCD4node* structvar)
savevarbyid(group,structvar);
/* Build attributes and map attributes WRT the variable */
if((ret = buildMetaData(builder,structvar))) goto done;
if((ret = buildMetaData(builder,structvar))) goto done;
done:
return THROW(ret);
@ -623,7 +623,7 @@ buildSequence(NCD4meta* builder, NCD4node* seq)
savevarbyid(group,seq);
/* Build attributes and map attributes WRT the variable */
if((ret = buildMetaData(builder,seq))) goto done;
if((ret = buildMetaData(builder,seq))) goto done;
done:
return THROW(ret);
@ -682,7 +682,7 @@ getFieldFQN(NCD4node* field, const char* tail)
ncbytescat(fqn,tail);
result = ncbytesextract(fqn);
ncbytesfree(fqn);
return result;
return result;
}
static size_t
@ -755,7 +755,7 @@ compileAttrValues(NCD4meta* builder, NCD4node* attr, void** memoryp, NClist* blo
/* Force type match */
basetype = (attr->basetype = container->basetype);
} else {/* Fail */
FAIL(NC_EBADTYPE,"_FillValue/Variable type mismatch: %s:%s",container->name,attr->name);
FAIL(NC_EBADTYPE,"_FillValue/Variable type mismatch: %s:%s",container->name,attr->name);
}
}
}
@ -962,7 +962,7 @@ markfixedsize(NCD4meta* meta)
if(n->sort != NCD4_TYPE) continue;
switch (n->subsort) {
case NC_STRUCT:
for(j=0;j<nclistlength(n->vars);j++) {
for(j=0;j<nclistlength(n->vars);j++) {
NCD4node* field = (NCD4node*)nclistget(n->vars,j);
if(!field->basetype->meta.isfixedsize) {
fixed = 0;
@ -973,7 +973,7 @@ markfixedsize(NCD4meta* meta)
break;
case NC_ENUM:
n->meta.isfixedsize = 1;
break;
break;
default: /* leave as is */
break;
}
@ -1009,32 +1009,32 @@ computeOffsets(NCD4meta* builder, NCD4node* cmpd)
} else if(ftype->subsort == NC_SEQ) { /* VLEN */
alignment = nctypealignment(NC_VLEN);
assert(ftype->meta.memsize > 0); size=ftype->meta.memsize;
//size = NCD4_computeTypeSize(builder,ftype);
/*size = NCD4_computeTypeSize(builder,ftype);*/
} else if(ftype->subsort == NC_OPAQUE) {
/* Either fixed or a vlen */
assert(ftype->meta.memsize > 0); size=ftype->meta.memsize;
if(ftype->opaque.size == 0) {/* treat like vlen */
alignment = nctypealignment(NC_VLEN);
//size = NCD4_computeTypeSize(builder,ftype);
/*size = NCD4_computeTypeSize(builder,ftype);*/
} else { /* fixed size */
alignment = nctypealignment(NC_OPAQUE);
//size = NCD4_computeTypeSize(builder,ftype);
/*size = NCD4_computeTypeSize(builder,ftype);*/
}
} else if(ftype->subsort == NC_ENUM) {
NCD4node* truetype = ftype->basetype;
alignment = nctypealignment(truetype->meta.id);
assert(ftype->meta.memsize > 0); size=ftype->meta.memsize;
//size = NCD4_computeTypeSize(builder,truetype);
/*size = NCD4_computeTypeSize(builder,truetype);*/
} else { /* Basically a primitive */
alignment = nctypealignment(ftype->meta.id);
assert(ftype->meta.memsize > 0); size=ftype->meta.memsize;
//size = NCD4_computeTypeSize(builder,ftype);
/*size = NCD4_computeTypeSize(builder,ftype);*/
}
#endif
if(alignment > largestalign)
largestalign = alignment;
/* Add possible padding wrt to previous field */
offset += getpadding(offset,alignment);
offset += getpadding(offset,alignment);
field->meta.offset = offset;
assert(ftype->meta.memsize > 0);
size = ftype->meta.memsize;
@ -1088,7 +1088,7 @@ NCD4_computeTypeSize(NCD4meta* builder, NCD4node* type)
}
break;
default: break; /* ignore */
}
}
type->meta.memsize = size;
return size;
}
@ -1117,7 +1117,7 @@ markdapsize(NCD4meta* meta)
switch (type->subsort) {
case NC_STRUCT:
totalsize = 0;
for(j=0;j<nclistlength(type->vars);j++) {
for(j=0;j<nclistlength(type->vars);j++) {
NCD4node* field = (NCD4node*)nclistget(type->vars,j);
size_t size = field->basetype->meta.dapsize;
if(size == 0) {
@ -1130,17 +1130,17 @@ markdapsize(NCD4meta* meta)
break;
case NC_SEQ:
type->meta.dapsize = 0; /* has no fixed size */
break;
break;
case NC_OPAQUE:
type->meta.dapsize = type->opaque.size;
break;
break;
case NC_ENUM:
type->meta.dapsize = type->basetype->meta.dapsize;
break;
break;
case NC_STRING:
type->meta.dapsize = 0; /* has no fixed size */
break;
default:
break;
default:
assert(type->subsort <= NC_UINT64);
/* Already assigned */
break;
@ -1148,4 +1148,3 @@ markdapsize(NCD4meta* meta)
}
return NC_NOERR;
}

View File

@ -75,6 +75,84 @@ NC_findreserved(const char* name)
return NULL;
}
/**
* @internal Recursively determine if there is a mismatch between
* order of coordinate creation and associated dimensions in this
* group or any subgroups, to find out if we have to handle that
* situation. Also check if there are any multidimensional coordinate
* variables defined, which require the same treatment to fix a
* potential bug when such variables occur in subgroups.
*
* @param grp Pointer to group info struct.
* @param bad_coord_orderp Pointer that gets 1 if there is a bad
* coordinate order.
*
* @returns NC_NOERR No error.
* @returns NC_EHDFERR HDF5 returned an error.
* @author Ed Hartnett
*/
static int
detect_preserve_dimids(NC_GRP_INFO_T *grp, nc_bool_t *bad_coord_orderp)
{
NC_VAR_INFO_T *var;
NC_GRP_INFO_T *child_grp;
int last_dimid = -1;
int retval;
int i;
/* Iterate over variables in this group */
for (i=0; i < ncindexsize(grp->vars); i++)
{
var = (NC_VAR_INFO_T*)ncindexith(grp->vars,i);
if (var == NULL) continue;
/* Only matters for dimension scale variables, with non-scalar dimensionality */
if (var->dimscale && var->ndims)
{
/* If the user writes coord vars in a different order then he
* defined their dimensions, then, when the file is reopened, the
* order of the dimids will change to match the order of the coord
* vars. Detect if this is about to happen. */
if (var->dimids[0] < last_dimid)
{
LOG((5, "%s: %s is out of order coord var", __func__, var->hdr.name));
*bad_coord_orderp = NC_TRUE;
return NC_NOERR;
}
last_dimid = var->dimids[0];
/* If there are multidimensional coordinate variables defined, then
* it's also necessary to preserve dimension IDs when the file is
* reopened ... */
if (var->ndims > 1)
{
LOG((5, "%s: %s is multidimensional coord var", __func__, var->hdr.name));
*bad_coord_orderp = NC_TRUE;
return NC_NOERR;
}
/* Did the user define a dimension, end define mode, reenter define
* mode, and then define a coordinate variable for that dimension?
* If so, dimensions will be out of order. */
if (var->is_new_var || var->became_coord_var)
{
LOG((5, "%s: coord var defined after enddef/redef", __func__));
*bad_coord_orderp = NC_TRUE;
return NC_NOERR;
}
}
}
/* If there are any child groups, check them also for this condition. */
for (i = 0; i < ncindexsize(grp->children); i++)
{
if (!(child_grp = (NC_GRP_INFO_T *)ncindexith(grp->children, i)))
continue;
if ((retval = detect_preserve_dimids(child_grp, bad_coord_orderp)))
return retval;
}
return NC_NOERR;
}
/**
* @internal This function will write all changed metadata and flush
* HDF5 file to disk.
@ -127,7 +205,7 @@ sync_netcdf4_file(NC_FILE_INFO_T *h5)
/* Check to see if the coordinate order is messed up. If
* detected, propagate to all groups to consistently store
* dimids. */
if ((retval = nc4_detect_preserve_dimids(h5->root_grp, &bad_coord_order)))
if ((retval = detect_preserve_dimids(h5->root_grp, &bad_coord_order)))
return retval;
/* Write all the metadata. */

View File

@ -106,7 +106,8 @@ nc4_hdf5_finalize(void)
* @author Ed Hartnett
*/
static int
find_var_dim_max_length(NC_GRP_INFO_T *grp, int varid, int dimid, size_t *maxlen)
find_var_dim_max_length(NC_GRP_INFO_T *grp, int varid, int dimid,
size_t *maxlen)
{
hid_t datasetid = 0, spaceid = 0;
NC_VAR_INFO_T *var;
@ -230,30 +231,27 @@ nc4_rec_find_hdf_type(NC_FILE_INFO_T *h5, hid_t target_hdf_typeid)
int
nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len)
{
NC_GRP_INFO_T *g;
NC_VAR_INFO_T *var;
int retval;
int i;
assert(grp && len);
LOG((3, "nc4_find_dim_len: grp->name %s dimid %d", grp->hdr.name, dimid));
LOG((3, "%s: grp->name %s dimid %d", __func__, grp->hdr.name, dimid));
/* If there are any groups, call this function recursively on
* them. */
for(i=0;i<ncindexsize(grp->children);i++) {
g = (NC_GRP_INFO_T*)ncindexith(grp->children,i);
if(g == NULL) continue;
if ((retval = nc4_find_dim_len(g, dimid, len)))
for (i = 0; i < ncindexsize(grp->children); i++)
if ((retval = nc4_find_dim_len((NC_GRP_INFO_T*)ncindexith(grp->children, i),
dimid, len)))
return retval;
}
/* For all variables in this group, find the ones that use this
* dimension, and remember the max length. */
for (i=0; i < ncindexsize(grp->vars); i++)
for (i = 0; i < ncindexsize(grp->vars); i++)
{
size_t mylen;
var = (NC_VAR_INFO_T*)ncindexith(grp->vars,i);
if (var == NULL) continue;
var = (NC_VAR_INFO_T *)ncindexith(grp->vars, i);
assert(var);
/* Find max length of dim in this variable... */
if ((retval = find_var_dim_max_length(grp, var->hdr.id, dimid, &mylen)))
@ -283,7 +281,8 @@ nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len)
* @author Quincey Koziol, Ed Hartnett
*/
int
nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T *dim)
nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var,
NC_DIM_INFO_T *dim)
{
int retval;
@ -314,10 +313,6 @@ nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T
return NC_ENOMEM;
}
/* Remove the atts that go with being a coordinate var. */
/* if ((retval = remove_coord_atts(coord_var->hdf_datasetid))) */
/* return retval; */
/* Detach dimension from variable */
coord_var->dimscale = NC_FALSE;
dim->coord_var = NULL;
@ -351,7 +346,8 @@ nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T
* @author Ed Hartnett
*/
int
delete_existing_dimscale_dataset(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T *dim)
delete_existing_dimscale_dataset(NC_GRP_INFO_T *grp, int dimid,
NC_DIM_INFO_T *dim)
{
NC_HDF5_DIM_INFO_T *hdf5_dim;
NC_HDF5_GRP_INFO_T *hdf5_grp;
@ -512,39 +508,20 @@ exit:
}
/**
* @internal Recursively free HDF5 objects for a group (and everything
* it contains).
* @internal Close HDF5 resources for global atts in a group.
*
* @param grp Pointer to group info struct.
*
* @return ::NC_NOERR No error.
* @return ::NC_EHDFERR HDF5 error.
* @author Ed Hartnett
*/
int
nc4_rec_grp_HDF5_del(NC_GRP_INFO_T *grp)
static int
close_gatts(NC_GRP_INFO_T *grp)
{
NC_VAR_INFO_T *var;
NC_HDF5_VAR_INFO_T *hdf5_var;
NC_DIM_INFO_T *dim;
NC_ATT_INFO_T *att;
NC_HDF5_GRP_INFO_T *hdf5_grp;
int a;
int i;
int retval;
assert(grp && grp->format_grp_info);
LOG((3, "%s: grp->name %s", __func__, grp->hdr.name));
hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
/* Recursively call this function for each child, if any, stopping
* if there is an error. */
for (i = 0; i < ncindexsize(grp->children); i++)
if ((retval = nc4_rec_grp_HDF5_del((NC_GRP_INFO_T *)ncindexith(grp->children,
i))))
return retval;
/* Close HDF5 resources associated with global attributes. */
for (a = 0; a < ncindexsize(grp->att); a++)
{
NC_HDF5_ATT_INFO_T *hdf5_att;
@ -558,8 +535,26 @@ nc4_rec_grp_HDF5_del(NC_GRP_INFO_T *grp)
H5Tclose(hdf5_att->native_hdf_typeid) < 0)
return NC_EHDFERR;
}
return NC_NOERR;
}
/**
* @internal Close HDF5 resources for vars in a group.
*
* @param grp Pointer to group info struct.
*
* @return ::NC_NOERR No error.
* @return ::NC_EHDFERR HDF5 error.
* @author Ed Hartnett
*/
static int
close_vars(NC_GRP_INFO_T *grp)
{
NC_VAR_INFO_T *var;
NC_HDF5_VAR_INFO_T *hdf5_var;
NC_ATT_INFO_T *att;
int a, i;
/* Close HDF5 resources associated with vars. */
for (i = 0; i < ncindexsize(grp->vars); i++)
{
var = (NC_VAR_INFO_T *)ncindexith(grp->vars, i);
@ -603,7 +598,24 @@ nc4_rec_grp_HDF5_del(NC_GRP_INFO_T *grp)
}
}
/* Close HDF5 resources associated with dims. */
return NC_NOERR;
}
/**
* @internal Close HDF5 resources for dims in a group.
*
* @param grp Pointer to group info struct.
*
* @return ::NC_NOERR No error.
* @return ::NC_EHDFERR HDF5 error.
* @author Ed Hartnett
*/
static int
close_dims(NC_GRP_INFO_T *grp)
{
NC_DIM_INFO_T *dim;
int i;
for (i = 0; i < ncindexsize(grp->dim); i++)
{
NC_HDF5_DIM_INFO_T *hdf5_dim;
@ -619,9 +631,25 @@ nc4_rec_grp_HDF5_del(NC_GRP_INFO_T *grp)
return NC_EHDFERR;
}
/* Close HDF5 resources associated with types. Set values to 0
* after closing types. Because of type reference counters, these
* closes can be called multiple times. */
return NC_NOERR;
}
/**
* @internal Close HDF5 resources for types in a group. Set values to
* 0 after closing types. Because of type reference counters, these
* closes can be called multiple times.
*
* @param grp Pointer to group info struct.
*
* @return ::NC_NOERR No error.
* @return ::NC_EHDFERR HDF5 error.
* @author Ed Hartnett, Dennis Heimbigner
*/
static int
close_types(NC_GRP_INFO_T *grp)
{
int i;
for (i = 0; i < ncindexsize(grp->type); i++)
{
NC_TYPE_INFO_T *type;
@ -643,6 +671,54 @@ nc4_rec_grp_HDF5_del(NC_GRP_INFO_T *grp)
hdf5_type->native_hdf_typeid = 0;
}
return NC_NOERR;
}
/**
* @internal Recursively free HDF5 objects for a group (and everything
* it contains).
*
* @param grp Pointer to group info struct.
*
* @return ::NC_NOERR No error.
* @return ::NC_EHDFERR HDF5 error.
* @author Ed Hartnett
*/
int
nc4_rec_grp_HDF5_del(NC_GRP_INFO_T *grp)
{
NC_HDF5_GRP_INFO_T *hdf5_grp;
int i;
int retval;
assert(grp && grp->format_grp_info);
LOG((3, "%s: grp->name %s", __func__, grp->hdr.name));
hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
/* Recursively call this function for each child, if any, stopping
* if there is an error. */
for (i = 0; i < ncindexsize(grp->children); i++)
if ((retval = nc4_rec_grp_HDF5_del((NC_GRP_INFO_T *)ncindexith(grp->children,
i))))
return retval;
/* Close HDF5 resources associated with global attributes. */
if ((retval = close_gatts(grp)))
return retval;
/* Close HDF5 resources associated with vars. */
if ((retval = close_vars(grp)))
return retval;
/* Close HDF5 resources associated with dims. */
if ((retval = close_dims(grp)))
return retval;
/* Close HDF5 resources associated with types. */
if ((retval = close_types(grp)))
return retval;
/* Close the HDF5 group. */
LOG((4, "%s: closing group %s", __func__, grp->hdr.name));
if (hdf5_grp->hdf_grpid && H5Gclose(hdf5_grp->hdf_grpid) < 0)

File diff suppressed because it is too large Load Diff

View File

@ -744,16 +744,17 @@ exit:
static int
write_netcdf4_dimid(hid_t datasetid, int dimid)
{
hid_t dimid_spaceid, dimid_attid;
hid_t dimid_spaceid = -1, dimid_attid = -1;
htri_t attr_exists;
int retval = NC_NOERR;
/* Create the space. */
if ((dimid_spaceid = H5Screate(H5S_SCALAR)) < 0)
return NC_EHDFERR;
BAIL(NC_EHDFERR);
/* Does the attribute already exist? If so, don't try to create it. */
if ((attr_exists = H5Aexists(datasetid, NC_DIMID_ATT_NAME)) < 0)
return NC_EHDFERR;
BAIL(NC_EHDFERR);
if (attr_exists)
dimid_attid = H5Aopen_by_name(datasetid, ".", NC_DIMID_ATT_NAME,
H5P_DEFAULT, H5P_DEFAULT);
@ -762,21 +763,22 @@ write_netcdf4_dimid(hid_t datasetid, int dimid)
dimid_attid = H5Acreate(datasetid, NC_DIMID_ATT_NAME,
H5T_NATIVE_INT, dimid_spaceid, H5P_DEFAULT);
if (dimid_attid < 0)
return NC_EHDFERR;
BAIL(NC_EHDFERR);
/* Write it. */
LOG((4, "%s: writing secret dimid %d", __func__, dimid));
if (H5Awrite(dimid_attid, H5T_NATIVE_INT, &dimid) < 0)
return NC_EHDFERR;
BAIL(NC_EHDFERR);
exit:
/* Close stuff*/
if (H5Sclose(dimid_spaceid) < 0)
return NC_EHDFERR;
if (H5Aclose(dimid_attid) < 0)
return NC_EHDFERR;
if (dimid_spaceid >= 0 && H5Sclose(dimid_spaceid) < 0)
BAIL2(NC_EHDFERR);
if (dimid_attid >= 0 && H5Aclose(dimid_attid) < 0)
BAIL2(NC_EHDFERR);
return NC_NOERR;
return retval;
}
/**
@ -1364,70 +1366,53 @@ attach_dimscales(NC_GRP_INFO_T *grp)
{
NC_VAR_INFO_T *var;
NC_HDF5_VAR_INFO_T *hdf5_var;
NC_DIM_INFO_T *dim1;
int d, i;
int retval = NC_NOERR;
int d, v;
/* Attach dimension scales. */
for (i = 0; i < ncindexsize(grp->vars); i++)
for (v = 0; v < ncindexsize(grp->vars); v++)
{
/* Get pointer to var and HDF5-specific var info. */
var = (NC_VAR_INFO_T*)ncindexith(grp->vars, i);
var = (NC_VAR_INFO_T*)ncindexith(grp->vars, v);
assert(var && var->format_var_info);
hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info;
/* Scales themselves do not attach. But I really wish they
* would. */
if (var->dimscale)
continue;
/* Find the scale for each dimension, if any, and attach it. */
for (d = 0; d < var->ndims; d++)
{
/* If this is a multidimensional coordinate variable, it will
* have a special coords attribute (read earlier) with a list
* of the dimensions for this variable. */
}
else /* not a dimscale... */
{
/* Find the scale for each dimension, if any, and attach it. */
for (d = 0; d < var->ndims; d++)
/* Is there a dimscale for this dimension? */
if (var->dimscale_attached)
{
/* Is there a dimscale for this dimension? */
if (var->dimscale_attached)
if (!var->dimscale_attached[d])
{
if (!var->dimscale_attached[d])
{
NC_HDF5_DIM_INFO_T *hdf5_dim1;
hid_t dim_datasetid; /* Dataset ID for dimension */
dim1 = var->dim[d];
assert(dim1 && dim1->hdr.id == var->dimids[d] && dim1->format_dim_info);
hdf5_dim1 = (NC_HDF5_DIM_INFO_T *)dim1->format_dim_info;
hid_t dsid; /* Dataset ID for dimension */
assert(var->dim[d] && var->dim[d]->hdr.id == var->dimids[d] &&
var->dim[d]->format_dim_info);
LOG((2, "%s: attaching scale for dimid %d to var %s",
__func__, var->dimids[d], var->hdr.name));
LOG((2, "%s: attaching scale for dimid %d to var %s",
__func__, var->dimids[d], var->hdr.name));
/* Find dataset ID for dimension */
if (dim1->coord_var)
dim_datasetid = ((NC_HDF5_VAR_INFO_T *)(dim1->coord_var->format_var_info))->hdf_datasetid;
else
dim_datasetid = hdf5_dim1->hdf_dimscaleid;
if(!(dim_datasetid > 0))
assert(dim_datasetid > 0);
if (H5DSattach_scale(hdf5_var->hdf_datasetid, dim_datasetid, d) < 0)
BAIL(NC_EHDFERR);
var->dimscale_attached[d] = NC_TRUE;
}
/* Find dataset ID for dimension */
if (var->dim[d]->coord_var)
dsid = ((NC_HDF5_VAR_INFO_T *)(var->dim[d]->coord_var->format_var_info))->hdf_datasetid;
else
dsid = ((NC_HDF5_DIM_INFO_T *)var->dim[d]->format_dim_info)->hdf_dimscaleid;
assert(dsid > 0);
/* If we didn't find a dimscale to attach, that's a problem! */
if (!var->dimscale_attached[d])
{
LOG((0, "no dimscale found!"));
return NC_EDIMSCALE;
}
/* Attach the scale. */
if (H5DSattach_scale(hdf5_var->hdf_datasetid, dsid, d) < 0)
return NC_EHDFERR;
var->dimscale_attached[d] = NC_TRUE;
}
}
}
}
exit:
return retval;
return NC_NOERR;
}
/**
@ -1551,14 +1536,11 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
{
replace_existing_var = NC_TRUE;
var->fill_val_changed = NC_FALSE;
/* If the variable is going to be replaced,
we need to flag any other attributes associated
with the variable as 'dirty', or else
*only* the fill value attribute will be copied over
and the rest will be lost. See:
* https://github.com/Unidata/netcdf-c/issues/239 */
/* If the variable is going to be replaced, we need to flag any
other attributes associated with the variable as 'dirty', or
else *only* the fill value attribute will be copied over and
the rest will be lost. See
https://github.com/Unidata/netcdf-c/issues/239 */
flag_atts_dirty(var->att);
}
@ -1568,93 +1550,66 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
* this object exists in the HDF group. */
if (var->became_coord_var)
{
NC_DIM_INFO_T *d1;
int i;
for (i = 0; i < ncindexsize(grp->dim); i++)
if ((NC_DIM_INFO_T *)ncindexlookup(grp->dim, var->hdr.name))
{
d1 = (NC_DIM_INFO_T*)ncindexith(grp->dim,i);
assert(d1);
if (!strcmp(d1->hdr.name, var->hdr.name))
{
nc_bool_t exists;
nc_bool_t exists;
if ((retval = var_exists(hdf5_grp->hdf_grpid, var->hdr.name, &exists)))
return retval;
if (exists)
{
/* Indicate that the variable already exists, and should be replaced */
replace_existing_var = NC_TRUE;
flag_atts_dirty(var->att);
break;
}
if ((retval = var_exists(hdf5_grp->hdf_grpid, var->hdr.name, &exists)))
return retval;
if (exists)
{
/* Indicate that the variable already exists, and should
* be replaced. */
replace_existing_var = NC_TRUE;
flag_atts_dirty(var->att);
}
}
}
/* Check dims if the variable will be replaced, so that the
* dimensions will be de-attached and re-attached correctly. (Note:
* There's a temptation to merge this loop over the dimensions with
* the prior loop over dimensions, but that blurs the line over the
* purpose of them, so they are currently separate. If performance
* becomes an issue here, it would be possible to merge them. -QAK)
*/
* dimensions will be de-attached and re-attached correctly. */
if (replace_existing_var)
{
int i;
NC_DIM_INFO_T *d1;
for (i = 0; i < ncindexsize(grp->dim); i++)
/* Is there a dim with this var's name? */
if ((d1 = (NC_DIM_INFO_T *)ncindexlookup(grp->dim, var->hdr.name)))
{
NC_DIM_INFO_T *d1;
NC_HDF5_DIM_INFO_T *hdf5_d1;
nc_bool_t exists;
assert(d1->format_dim_info && d1->hdr.name);
/* Get info about the dim, including HDF5-specific info. */
d1 = (NC_DIM_INFO_T *)ncindexith(grp->dim, i);
assert(d1 && d1->format_dim_info && d1->hdr.name);
hdf5_d1 = (NC_HDF5_DIM_INFO_T *)d1->format_dim_info;
if (!strcmp(d1->hdr.name, var->hdr.name))
if ((retval = var_exists(hdf5_grp->hdf_grpid, var->hdr.name, &exists)))
return retval;
if (exists)
{
nc_bool_t exists;
hid_t dsid;
if ((retval = var_exists(hdf5_grp->hdf_grpid, var->hdr.name,
&exists)))
/* Find dataset ID for dimension */
if (d1->coord_var)
dsid = ((NC_HDF5_VAR_INFO_T *)d1->coord_var->format_var_info)->hdf_datasetid;
else
dsid = ((NC_HDF5_DIM_INFO_T *)d1->format_dim_info)->hdf_dimscaleid;
assert(dsid > 0);
/* If we're replacing an existing dimscale dataset, go to
* every var in the file and detach this dimension scale,
* because we have to delete it. */
if ((retval = rec_detach_scales(grp->nc4_info->root_grp,
var->dimids[0], dsid)))
return retval;
if (exists)
{
hid_t dim_datasetid; /* Dataset ID for dimension */
/* Find dataset ID for dimension */
if (d1->coord_var)
dim_datasetid = ((NC_HDF5_VAR_INFO_T *)(d1->coord_var->format_var_info))->hdf_datasetid;
else
dim_datasetid = hdf5_d1->hdf_dimscaleid;
assert(dim_datasetid > 0);
/* If we're replacing an existing dimscale dataset, go to
* every var in the file and detach this dimension scale,
* because we have to delete it. */
if ((retval = rec_detach_scales(grp->nc4_info->root_grp,
var->dimids[0], dim_datasetid)))
return retval;
break;
}
}
}
}
/* If this is not a dimension scale, do this stuff. */
/* If this is not a dimension scale, remove any attached scales,
* and delete dimscale attributes from the var. */
if (var->was_coord_var && var->dimscale_attached)
{
/* If the variable already exists in the file, Remove any dimension scale
* attributes from it, if they exist. */
/* (The HDF5 Dimension Scale API should really have an API routine
* for making a dataset not a scale. -QAK) */
if (var->created)
{
if ((retval = remove_coord_atts(hdf5_var->hdf_datasetid)))
BAIL(retval);
}
return retval;
if (var->dimscale_attached)
{
@ -1665,21 +1620,20 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
{
if (var->dimscale_attached[d])
{
hid_t dim_datasetid; /* Dataset ID for dimension */
NC_DIM_INFO_T *dim1 = var->dim[d];
NC_HDF5_DIM_INFO_T *hdf5_dim1;
assert(dim1 && dim1->hdr.id == var->dimids[d] && dim1->format_dim_info);
hdf5_dim1 = (NC_HDF5_DIM_INFO_T *)dim1->format_dim_info;
hid_t dsid; /* Dataset ID for dimension */
assert(var->dim[d] && var->dim[d]->hdr.id == var->dimids[d] &&
var->dim[d]->format_dim_info);
/* Find dataset ID for dimension */
if (dim1->coord_var)
dim_datasetid = ((NC_HDF5_VAR_INFO_T *)dim1->coord_var->format_var_info)->hdf_datasetid;
if (var->dim[d]->coord_var)
dsid = ((NC_HDF5_VAR_INFO_T *)var->dim[d]->coord_var->format_var_info)->hdf_datasetid;
else
dim_datasetid = hdf5_dim1->hdf_dimscaleid;
assert(dim_datasetid > 0);
dsid = ((NC_HDF5_DIM_INFO_T *)var->dim[d]->format_dim_info)->hdf_dimscaleid;
assert(dsid > 0);
if (H5DSdetach_scale(hdf5_var->hdf_datasetid, dim_datasetid, d) < 0)
BAIL(NC_EHDFERR);
/* Detach this dim scale. */
if (H5DSdetach_scale(hdf5_var->hdf_datasetid, dsid, d) < 0)
return NC_EHDFERR;
var->dimscale_attached[d] = NC_FALSE;
}
}
@ -1691,7 +1645,7 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
{
/* Free the HDF5 dataset id. */
if (hdf5_var->hdf_datasetid && H5Dclose(hdf5_var->hdf_datasetid) < 0)
BAIL(NC_EHDFERR);
return NC_EHDFERR;
hdf5_var->hdf_datasetid = 0;
/* Now delete the variable. */
@ -1710,7 +1664,7 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
if (write_dimid && var->ndims)
if ((retval = write_netcdf4_dimid(hdf5_var->hdf_datasetid,
var->dimids[0])))
BAIL(retval);
return retval;
}
if (replace_existing_var)
@ -1741,13 +1695,11 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
{
/* Write attributes for this var. */
if ((retval = write_attlist(var->att, var->hdr.id, grp)))
BAIL(retval);
return retval;
var->attr_dirty = NC_FALSE;
}
return NC_NOERR;
exit:
return retval;
}
/**
@ -1765,9 +1717,11 @@ exit:
static int
write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
{
hid_t spaceid = -1, create_propid = -1;
NC_HDF5_GRP_INFO_T *hdf5_grp;
NC_HDF5_DIM_INFO_T *hdf5_dim;
int retval;
hsize_t *new_size = NULL;
int retval = NC_NOERR;
assert(dim && dim->format_dim_info && grp && grp->format_grp_info);
@ -1781,14 +1735,13 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
* without an associated variable.) */
if (!hdf5_dim->hdf_dimscaleid)
{
hid_t spaceid, create_propid;
hsize_t dims[1], max_dims[1], chunk_dims[1] = {1};
char dimscale_wo_var[NC_MAX_NAME];
LOG((4, "%s: creating dim %s", __func__, dim->hdr.name));
/* Sanity check */
assert(NULL == dim->coord_var);
assert(!dim->coord_var);
/* Create a property list. If this dimension scale is
* unlimited (i.e. it's an unlimited dimension), then set
@ -1796,7 +1749,7 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
if ((create_propid = H5Pcreate(H5P_DATASET_CREATE)) < 0)
BAIL(NC_EHDFERR);
/* RJ: this suppose to be FALSE that is defined in H5 private.h as 0 */
/* Turn off recording of times associated with this object. */
if (H5Pset_obj_track_times(create_propid,0)<0)
BAIL(NC_EHDFERR);
@ -1813,20 +1766,18 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
if ((spaceid = H5Screate_simple(1, dims, max_dims)) < 0)
BAIL(NC_EHDFERR);
/* Turn on creation-order tracking. */
if (H5Pset_attr_creation_order(create_propid, H5P_CRT_ORDER_TRACKED|
H5P_CRT_ORDER_INDEXED) < 0)
BAIL(NC_EHDFERR);
/* Create the dataset that will be the dimension scale. */
LOG((4, "%s: about to H5Dcreate1 a dimscale dataset %s", __func__, dim->hdr.name));
if ((hdf5_dim->hdf_dimscaleid = H5Dcreate1(hdf5_grp->hdf_grpid, dim->hdr.name, H5T_IEEE_F32BE,
spaceid, create_propid)) < 0)
BAIL(NC_EHDFERR);
/* Close the spaceid and create_propid. */
if (H5Sclose(spaceid) < 0)
BAIL(NC_EHDFERR);
if (H5Pclose(create_propid) < 0)
LOG((4, "%s: about to H5Dcreate1 a dimscale dataset %s", __func__,
dim->hdr.name));
if ((hdf5_dim->hdf_dimscaleid = H5Dcreate2(hdf5_grp->hdf_grpid, dim->hdr.name,
H5T_IEEE_F32BE, spaceid,
H5P_DEFAULT, create_propid,
H5P_DEFAULT)) < 0)
BAIL(NC_EHDFERR);
/* Indicate that this is a scale. Also indicate that not
@ -1846,11 +1797,10 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
/* If this is a dimension without a variable, then update
* the secret length information at the end of the NAME
* attribute. */
v1 = (NC_VAR_INFO_T*)ncindexlookup(grp->vars,dim->hdr.name);
v1 = (NC_VAR_INFO_T *)ncindexlookup(grp->vars, dim->hdr.name);
if (v1)
{
NC_HDF5_VAR_INFO_T *hdf5_v1;
hsize_t *new_size = NULL;
int d1;
hdf5_v1 = (NC_HDF5_VAR_INFO_T *)v1->format_var_info;
@ -1864,11 +1814,8 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
assert(v1->dim[d1] && v1->dim[d1]->hdr.id == v1->dimids[d1]);
new_size[d1] = v1->dim[d1]->len;
}
if (H5Dset_extent(hdf5_v1->hdf_datasetid, new_size) < 0) {
free(new_size);
if (H5Dset_extent(hdf5_v1->hdf_datasetid, new_size) < 0)
BAIL(NC_EHDFERR);
}
free(new_size);
}
}
@ -1880,90 +1827,17 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
if ((retval = write_netcdf4_dimid(hdf5_dim->hdf_dimscaleid, dim->hdr.id)))
BAIL(retval);
return NC_NOERR;
exit:
if (spaceid > 0 && H5Sclose(spaceid) < 0)
BAIL2(NC_EHDFERR);
if (create_propid > 0 && H5Pclose(create_propid) < 0)
BAIL2(NC_EHDFERR);
if (new_size)
free(new_size);
return retval;
}
/**
* @internal Recursively determine if there is a mismatch between
* order of coordinate creation and associated dimensions in this
* group or any subgroups, to find out if we have to handle that
* situation. Also check if there are any multidimensional coordinate
* variables defined, which require the same treatment to fix a
* potential bug when such variables occur in subgroups.
*
* @param grp Pointer to group info struct.
* @param bad_coord_orderp Pointer that gets 1 if there is a bad
* coordinate order.
*
* @returns NC_NOERR No error.
* @returns NC_EHDFERR HDF5 returned an error.
* @author Ed Hartnett
*/
int
nc4_detect_preserve_dimids(NC_GRP_INFO_T *grp, nc_bool_t *bad_coord_orderp)
{
NC_VAR_INFO_T *var;
NC_GRP_INFO_T *child_grp;
int last_dimid = -1;
int retval;
int i;
/* Iterate over variables in this group */
for (i=0; i < ncindexsize(grp->vars); i++)
{
var = (NC_VAR_INFO_T*)ncindexith(grp->vars,i);
if (var == NULL) continue;
/* Only matters for dimension scale variables, with non-scalar dimensionality */
if (var->dimscale && var->ndims)
{
/* If the user writes coord vars in a different order then he
* defined their dimensions, then, when the file is reopened, the
* order of the dimids will change to match the order of the coord
* vars. Detect if this is about to happen. */
if (var->dimids[0] < last_dimid)
{
LOG((5, "%s: %s is out of order coord var", __func__, var->hdr.name));
*bad_coord_orderp = NC_TRUE;
return NC_NOERR;
}
last_dimid = var->dimids[0];
/* If there are multidimensional coordinate variables defined, then
* it's also necessary to preserve dimension IDs when the file is
* reopened ... */
if (var->ndims > 1)
{
LOG((5, "%s: %s is multidimensional coord var", __func__, var->hdr.name));
*bad_coord_orderp = NC_TRUE;
return NC_NOERR;
}
/* Did the user define a dimension, end define mode, reenter define
* mode, and then define a coordinate variable for that dimension?
* If so, dimensions will be out of order. */
if (var->is_new_var || var->became_coord_var)
{
LOG((5, "%s: coord var defined after enddef/redef", __func__));
*bad_coord_orderp = NC_TRUE;
return NC_NOERR;
}
}
}
/* If there are any child groups, check them also for this condition. */
for (i = 0; i < ncindexsize(grp->children); i++)
{
if (!(child_grp = (NC_GRP_INFO_T *)ncindexith(grp->children, i)))
continue;
if ((retval = nc4_detect_preserve_dimids(child_grp, bad_coord_orderp)))
return retval;
}
return NC_NOERR;
}
/**
* @internal Recursively write all the metadata in a group. Groups and
* types have all already been written. Propagate bad cooordinate
@ -1999,11 +1873,9 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order)
/* Set the pointers to the beginning of the list of dims & vars in this
* group. */
dim_index = 0;
var_index = 0;
/* prime the loop */
dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,dim_index);
var = (NC_VAR_INFO_T*)ncindexith(grp->vars,var_index);
dim = (NC_DIM_INFO_T *)ncindexith(grp->dim, dim_index);
var = (NC_VAR_INFO_T *)ncindexith(grp->vars, var_index);
/* Because of HDF5 ordering the dims and vars have to be stored in
* this way to ensure that the dims and coordinate vars come out in
* the correct order. */
@ -2025,7 +1897,7 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order)
coord_varid = dim->coord_var->hdr.id;
found_coord = NC_TRUE;
}
dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,++dim_index);
dim = (NC_DIM_INFO_T *)ncindexith(grp->dim, ++dim_index);
}
/* Write each var. When we get to the coord var we are waiting
@ -2036,16 +1908,19 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order)
return retval;
if (found_coord && var->hdr.id == coord_varid)
wrote_coord = NC_TRUE;
var = (NC_VAR_INFO_T*)ncindexith(grp->vars,++var_index);
var = (NC_VAR_INFO_T *)ncindexith(grp->vars, ++var_index);
}
} /* end while */
/* Attach dimscales to vars in this group. */
if ((retval = attach_dimscales(grp)))
return retval;
/* If there are any child groups, write their metadata. */
for(i=0;i<ncindexsize(grp->children);i++) {
if((child_grp = (NC_GRP_INFO_T*)ncindexith(grp->children,i)) == NULL) continue;
for (i = 0; i < ncindexsize(grp->children); i++)
{
child_grp = (NC_GRP_INFO_T *)ncindexith(grp->children, i);
assert(child_grp);
if ((retval = nc4_rec_write_metadata(child_grp, bad_coord_order)))
return retval;
}

View File

@ -258,7 +258,7 @@ nc4_find_grp_h5_var(int ncid, int varid, NC_FILE_INFO_T **h5, NC_GRP_INFO_T **gr
}
/**
* @internal Find a dim in a grp (or its parents).
* @internal Find a dim in the file.
*
* @param grp Pointer to group info struct.
* @param dimid Dimension ID to find.
@ -268,7 +268,7 @@ nc4_find_grp_h5_var(int ncid, int varid, NC_FILE_INFO_T **h5, NC_GRP_INFO_T **gr
*
* @return ::NC_NOERR No error.
* @return ::NC_EBADDIM Dimension not found.
* @author Ed Hartnett
* @author Ed Hartnett, Dennis Heimbigner
*/
int
nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim,
@ -510,6 +510,7 @@ nc4_var_list_add2(NC_GRP_INFO_T *grp, const char *name, NC_VAR_INFO_T **var)
if (!(new_var = calloc(1, sizeof(NC_VAR_INFO_T))))
return NC_ENOMEM;
new_var->hdr.sort = NCVAR;
new_var->container = grp;
/* These are the HDF5-1.8.4 defaults. */
new_var->chunk_cache_size = nc4_chunk_cache_size;
@ -565,7 +566,7 @@ nc4_var_set_ndims(NC_VAR_INFO_T *var, int ndims)
return NC_ENOMEM;
/* Initialize dimids to illegal values (-1). See the comment
in nc4hdf.c#nc4_rec_match_dimscales. */
in nc4_rec_match_dimscales(). */
memset(var->dimids, -1, ndims * sizeof(int));
}

View File

@ -160,9 +160,7 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
return retval;
assert(grp && h5);
/* Walk through the list of vars, and return the info about the one
with a matching varid. If the varid is -1, find the global
atts and call it a day. */
/* If the varid is -1, find the global atts and call it a day. */
if (varid == NC_GLOBAL && nattsp)
{
*nattsp = ncindexcount(grp->att);

View File

@ -16,7 +16,7 @@ CREATE3=tst_inmemory3_create
FILE4=tst_inmemory4
CREATE4=tst_inmemory4_create
# For tst_open_mem
# For tst_open_mem NETCDF4 only
OMEMFILE=f03tst_open_mem.nc
echo ""
@ -26,8 +26,9 @@ HASHDF5=`${top_builddir}/nc-config --has-hdf5`
# Execute the core of the inmemory tests
${execdir}/tst_inmemory
exit
if test "x$HASNC4" = xyes ; then
${execdir}/tst_open_mem ${srcdir}/${OMEMFILE}
fi
echo "**** Test ncdump of the resulting inmemory data"
${NCDUMP} -n "${FILE3}" ${FILE3}.nc > ${FILE3}.cdl
@ -36,8 +37,9 @@ diff -wb ${FILE3}.cdl ${CREATE3}.cdl
if test "x$HASHDF5" = "xyes" ; then
${NCDUMP} ${FILE4}.nc > ${FILE4}.cdl
${NCDUMP} ${CREATE4}.nc > ${CREATE4}.cdl
${NCDUMP} -n ${FILE4} ${CREATE4}.nc > ${CREATE4}.cdl
diff -wb ${FILE4}.cdl ${CREATE4}.cdl
fi
# cleanup
rm -f ${FILE3}.nc ${FILE4}.nc ${CREATE3}.nc ${CREATE4}.nc

View File

@ -61,8 +61,8 @@ extern int H5Eprint1(FILE * stream);
#define NVARS0 3 /* # variables in define_metadata */
#define VAR0_NAME "nightlife"
#define VAR1_NAME "time"
#define VAR2_NAME "taxi_distance"
#define VAR1_NAME "taxi_distance"
#define VAR2_NAME "time"
/* Variable added by modify_file */
#define VAR3_NAME "miles"
@ -270,19 +270,19 @@ define_metadata(int ncid)
{
int stat = NC_NOERR;
int dimid[MAXDIMS], varid0, varid1, varid2;
short short_data[DIM1_LEN];
size_t start[1] = {0};
size_t count[1] = {DIM1_LEN};
int dimprod = (DIM0_LEN*DIM1_LEN);
int i;
float float_data;
int nightdata[DIM0_LEN*DIM1_LEN] ;
short taxi_distance[DIM1_LEN] ;
/* Create data to write */
float_data = FLOATVAL;
for (i = 0; i < DIM1_LEN; i++)
short_data[i] = i;
taxi_distance[i] = i;
for (i = 0; i < dimprod; i++)
nightdata[i] = (100*i);
@ -294,13 +294,13 @@ define_metadata(int ncid)
CHECK(nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimid[1]));
CHECK(nc_def_var(ncid, VAR0_NAME, NC_INT, 2, dimid, &varid0));
CHECK(nc_def_var(ncid, VAR1_NAME, NC_FLOAT, 0, NULL, &varid1));
CHECK(nc_def_var(ncid, VAR2_NAME, NC_SHORT, 1, &dimid[1], &varid2));
CHECK(nc_def_var(ncid, VAR1_NAME, NC_SHORT, 1, &dimid[1], &varid1));
CHECK(nc_def_var(ncid, VAR2_NAME, NC_FLOAT, 0, NULL, &varid2));
CHECK(nc_enddef(ncid));
CHECK(nc_put_vara_float(ncid, varid1, NULL, NULL, &float_data));
CHECK(nc_put_vara_short(ncid, varid2, start, count, short_data));
CHECK(nc_put_vara_short(ncid, varid1, start, count, taxi_distance));
CHECK(nc_put_var_float(ncid, varid2, &float_data));
{
size_t start[2] = {0,0};
@ -406,6 +406,7 @@ verify_file(int ncid, int modified, int extra)
float float_data_in;
int milesdata_in[MAXDIMLEN];
int expenses_in[MAXDIMLEN];
short taxi_distance_in[MAXDIMLEN];
int dimprod = DIM0_LEN * DIM1_LEN;
#ifdef USE_HDF5
int tmp;
@ -455,18 +456,23 @@ verify_file(int ncid, int modified, int extra)
if (strcmp(name_in, VAR0_NAME) || type_in != NC_INT || ndims_in != NDIMS0 ||
dimid_in[0] != 0 || dimid_in[1] != 1 || natts_in != 0) CHECK(NC_EINVAL);
CHECK(nc_inq_var(ncid, varid[1], name_in, &type_in, &ndims_in, dimid_in, &natts_in));
if (strcmp(name_in, VAR1_NAME) || type_in != NC_FLOAT || ndims_in != 0 ||
natts_in != 0) CHECK(NC_EINVAL);
if (strcmp(name_in, VAR1_NAME) || type_in != NC_SHORT || ndims_in != 1 || dimid_in[0] != 1 || natts_in != 0)
CHECK(NC_EINVAL);
CHECK(nc_inq_var(ncid, varid[2], name_in, &type_in, &ndims_in, dimid_in, &natts_in));
if (strcmp(name_in, VAR2_NAME) || type_in != NC_SHORT || ndims_in != 1 ||
dimid_in[0] != 1 || natts_in != 0) CHECK(NC_EINVAL);
if (strcmp(name_in, VAR2_NAME) || type_in != NC_FLOAT || ndims_in != 0 || natts_in != 0)
CHECK(NC_EINVAL);
CHECK(nc_get_var_int(ncid, varid[0], nightdata_in));
for(i=0;i<dimprod;i++) {
if(nightdata_in[i] != (100*i)) CHECK(NC_EINVAL);
}
CHECK(nc_get_vara_float(ncid, varid[1], NULL, NULL, &float_data_in));
CHECK(nc_get_var_short(ncid, varid[1], taxi_distance_in));
for(i=0;i<DIM1_LEN;i++) {
if(taxi_distance_in[i] != (i)) CHECK(NC_EINVAL);
}
CHECK(nc_get_var_float(ncid, varid[2], &float_data_in));
if (float_data_in != FLOATVAL) CHECK(NC_EINVAL);
if(modified) {

View File

@ -178,7 +178,7 @@ int main(int argc, char **argv) {
}
SUMMARIZE_ERR;
#endif // USE_HDF5
#endif /*USE_HDF5*/
printf("* Finished.\n");

View File

@ -42,8 +42,12 @@ readfile(const char* path, NC_memio* memio)
#else
f = fopen(path,"r");
#endif
if(f == NULL)
{status = errno; goto done;}
if(f == NULL) {
fprintf(stderr,"cannot open file: %s\n",path);
fflush(stderr);
status = errno;
goto done;
}
/* get current filesize */
if(fseek(f,0,SEEK_END) < 0)
{status = errno; goto done;}
@ -67,6 +71,7 @@ readfile(const char* path, NC_memio* memio)
if(memio) {
memio->size = (size_t)filesize;
memio->memory = memory;
memory = NULL;
}
done:
if(status != NC_NOERR && memory != NULL)
@ -93,6 +98,8 @@ main(int argc, char** argv)
goto exit;
if((retval = nc_close(ncid)))
goto exit;
if(mem.memory)
free(mem.memory);
return 0;
exit:
fprintf(stderr,"retval=%d\n",retval);

View File

@ -72,9 +72,10 @@ endif # BUILD_V2
# If benchmarks were turned on, build and run a bunch more tests.
if BUILD_BENCHMARKS
check_PROGRAMS += tst_create_files bm_file tst_chunks3 tst_ar4 \
tst_ar4_3d tst_ar4_4d bm_many_objs tst_h_many_atts bm_many_atts \
tst_files2 tst_files3 tst_mem tst_knmi bm_netcdf4_recs
check_PROGRAMS += tst_create_files bm_file tst_chunks3 tst_ar4 \
tst_ar4_3d tst_ar4_4d bm_many_objs tst_h_many_atts bm_many_atts \
tst_files2 tst_files3 tst_mem tst_knmi bm_netcdf4_recs tst_wrf_reads \
tst_attsperf
bm_netcdf4_recs_SOURCES = bm_netcdf4_recs.c tst_utils.c
bm_many_atts_SOURCES = bm_many_atts.c tst_utils.c
@ -86,10 +87,11 @@ tst_ar4_SOURCES = tst_ar4.c tst_utils.c
tst_h_many_atts_SOURCES = tst_h_many_atts.c tst_utils.c
bm_file_SOURCES = bm_file.c tst_utils.c
tst_knmi_SOURCES = tst_knmi.c tst_utils.c
tst_wrf_reads_SOURCES = tst_wrf_reads.c tst_utils.c
TESTS += tst_ar4_3d tst_create_files run_bm_test1.sh run_bm_elena.sh \
run_bm_test2.sh run_tst_chunks.sh tst_files2 tst_files3 tst_mem \
run_knmi_bm.sh
run_knmi_bm.sh tst_wrf_reads tst_attsperf
# tst_create_files creates files for other tests.
run_bm_test1.log: tst_create_files.log
@ -130,8 +132,8 @@ TESTS += run_par_test.sh
endif
if ENABLE_METADATA_PERF
check_PROGRAMS += bigmeta openbigmeta tst_attsperf
TESTS += tst_attsperf perftest.sh
check_PROGRAMS += bigmeta openbigmeta
TESTS += perftest.sh
endif
EXTRA_DIST = run_par_test.sh.in run_par_bm_test.sh.in run_bm_test1.sh \

View File

@ -398,47 +398,47 @@ main(int argc, char **argv)
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
/* printf("**** testing 2D coordinate variable..."); */
printf("**** testing 2D coordinate variable...");
/* { */
/* #define VAR_NAME "Britany" */
/* #define NDIMS 2 */
/* #define TEXT_LEN 15 */
/* #define D0_NAME "time" */
/* #define D1_NAME "tl" */
/* int ncid, nvars_in, varids_in[1]; */
/* int time_dimids[NDIMS], time_id; */
/* size_t time_count[NDIMS], time_index[NDIMS] = {0, 0}; */
/* const char ttext[TEXT_LEN]="20051224.150000"; */
/* int nvars, ndims, ngatts, unlimdimid; */
/* int ndims_in, natts_in, dimids_in[NDIMS]; */
/* char var_name_in[NC_MAX_NAME + 1]; */
/* nc_type xtype_in; */
{
#define VAR_NAME "Britany"
#define NDIMS 2
#define TEXT_LEN 15
#define D0_NAME "time"
#define D1_NAME "tl"
int ncid, nvars_in, varids_in[1];
int time_dimids[NDIMS], time_id;
size_t time_count[NDIMS], time_index[NDIMS] = {0, 0};
const char ttext[TEXT_LEN]="20051224.150000";
int nvars, ndims, ngatts, unlimdimid;
int ndims_in, natts_in, dimids_in[NDIMS];
char var_name_in[NC_MAX_NAME + 1];
nc_type xtype_in;
/* /\* Create a netcdf-4 file with 2D coordinate var. *\/ */
/* if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; */
/* Create a netcdf-4 file with 2D coordinate var. */
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
/* if (nc_def_dim(ncid, D0_NAME, NC_UNLIMITED, &time_dimids[0])) ERR; */
/* if (nc_def_dim(ncid, D1_NAME, TEXT_LEN, &time_dimids[1])) ERR; */
/* if (nc_def_var(ncid, D0_NAME, NC_CHAR, NDIMS, time_dimids, &time_id)) ERR; */
if (nc_def_dim(ncid, D0_NAME, NC_UNLIMITED, &time_dimids[0])) ERR;
if (nc_def_dim(ncid, D1_NAME, TEXT_LEN, &time_dimids[1])) ERR;
if (nc_def_var(ncid, D0_NAME, NC_CHAR, NDIMS, time_dimids, &time_id)) ERR;
/* /\* Write one time to the coordinate variable. *\/ */
/* time_count[0] = 1; */
/* time_count[1] = TEXT_LEN; */
/* if (nc_put_vara_text(ncid, time_id, time_index, time_count, ttext)) ERR; */
/* if (nc_close(ncid)) ERR; */
/* Write one time to the coordinate variable. */
time_count[0] = 1;
time_count[1] = TEXT_LEN;
if (nc_put_vara_text(ncid, time_id, time_index, time_count, ttext)) ERR;
if (nc_close(ncid)) ERR;
/* /\* Open the file and check. *\/ */
/* if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; */
/* if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; */
/* if (nvars != 1 || ndims != 2 || ngatts != 0 || unlimdimid != 0) ERR; */
/* if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR; */
/* if (nvars_in != 1 || varids_in[0] != 0) ERR; */
/* if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; */
/* if (strcmp(var_name_in, D0_NAME) || xtype_in != NC_CHAR || ndims_in != 2 || */
/* dimids_in[0] != 0 || dimids_in[1] != 1 || natts_in != 0) ERR; */
/* if (nc_close(ncid)) ERR; */
/* } */
/* SUMMARIZE_ERR; */
/* Open the file and check. */
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
if (nvars != 1 || ndims != 2 || ngatts != 0 || unlimdimid != 0) ERR;
if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
if (nvars_in != 1 || varids_in[0] != 0) ERR;
if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
if (strcmp(var_name_in, D0_NAME) || xtype_in != NC_CHAR || ndims_in != 2 ||
dimids_in[0] != 0 || dimids_in[1] != 1 || natts_in != 0) ERR;
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
FINAL_RESULTS;
}

View File

@ -17,142 +17,142 @@
#define VAR_NAME Y_NAME
#define XDIM_LEN 2
#define YDIM_LEN 5
#define CLAIR "Clair"
#define JAMIE "Jamie"
int
main(int argc, char **argv)
{
printf("\n*** Testing netcdf-4 variable functions, even more.\n");
/* printf("**** testing Jeff's dimension problem..."); */
/* { */
/* int varid, ncid, dims[NDIMS2], dims_in[NDIMS2]; */
/* int ndims, nvars, ngatts, unlimdimid, natts; */
/* char name_in[NC_MAX_NAME + 1]; */
/* nc_type type_in; */
/* size_t len_in; */
printf("**** testing Jeff's dimension problem...");
{
int varid, ncid, dims[NDIMS2], dims_in[NDIMS2];
int ndims, nvars, ngatts, unlimdimid, natts;
char name_in[NC_MAX_NAME + 1];
nc_type type_in;
size_t len_in;
/* if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR; */
/* if (nc_def_dim(ncid, X_NAME, XDIM_LEN, &dims[0])) ERR; */
/* if (nc_def_dim(ncid, Y_NAME, YDIM_LEN, &dims[1])) ERR; */
/* if (nc_def_var(ncid, VAR_NAME, NC_FLOAT, 2, dims, &varid)) ERR; */
/* if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; */
/* if (nvars != NUM_VARS || ndims != NDIMS2 || ngatts != 0 || unlimdimid != -1) ERR; */
/* if (nc_inq_var(ncid, 0, name_in, &type_in, &ndims, dims_in, &natts)) ERR; */
/* if (strcmp(name_in, VAR_NAME) || type_in != NC_FLOAT || ndims != NDIMS2 || */
/* dims_in[0] != dims[0] || dims_in[1] != dims[1] || natts != 0) ERR; */
/* if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; */
/* if (strcmp(name_in, X_NAME) || len_in != XDIM_LEN) ERR; */
/* if (nc_inq_dim(ncid, 1, name_in, &len_in)) ERR; */
/* if (strcmp(name_in, Y_NAME)) ERR; */
/* if (len_in != YDIM_LEN) ERR; */
/* if (nc_close(ncid)) ERR; */
if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
if (nc_def_dim(ncid, X_NAME, XDIM_LEN, &dims[0])) ERR;
if (nc_def_dim(ncid, Y_NAME, YDIM_LEN, &dims[1])) ERR;
if (nc_def_var(ncid, VAR_NAME, NC_FLOAT, 2, dims, &varid)) ERR;
if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
if (nvars != NUM_VARS || ndims != NDIMS2 || ngatts != 0 || unlimdimid != -1) ERR;
if (nc_inq_var(ncid, 0, name_in, &type_in, &ndims, dims_in, &natts)) ERR;
if (strcmp(name_in, VAR_NAME) || type_in != NC_FLOAT || ndims != NDIMS2 ||
dims_in[0] != dims[0] || dims_in[1] != dims[1] || natts != 0) ERR;
if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
if (strcmp(name_in, X_NAME) || len_in != XDIM_LEN) ERR;
if (nc_inq_dim(ncid, 1, name_in, &len_in)) ERR;
if (strcmp(name_in, Y_NAME)) ERR;
if (len_in != YDIM_LEN) ERR;
if (nc_close(ncid)) ERR;
/* /\* Open the file and check. *\/ */
/* if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; */
/* if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; */
/* if (nvars != NUM_VARS || ndims != NDIMS2 || ngatts != 0 || unlimdimid != -1) ERR; */
/* if (nc_inq_var(ncid, 0, name_in, &type_in, &ndims, dims_in, &natts)) ERR; */
/* if (strcmp(name_in, VAR_NAME) || type_in != NC_FLOAT || ndims != NDIMS2 || */
/* dims_in[0] != dims[0] || dims_in[1] != dims[1] || natts != 0) ERR; */
/* if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; */
/* if (strcmp(name_in, X_NAME) || len_in != XDIM_LEN) ERR; */
/* if (nc_inq_dim(ncid, 1, name_in, &len_in)) ERR; */
/* if (strcmp(name_in, Y_NAME)) ERR; */
/* if (len_in != YDIM_LEN) ERR; */
/* if (nc_close(ncid)) ERR; */
/* } */
/* SUMMARIZE_ERR; */
/* printf("**** testing chunking turned on by fletcher..."); */
/* { */
/* int varid, ncid, dims[NDIMS2]; */
/* int storage_in; */
/* size_t chunksizes_in[NDIMS2]; */
/* Open the file and check. */
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
if (nvars != NUM_VARS || ndims != NDIMS2 || ngatts != 0 || unlimdimid != -1) ERR;
if (nc_inq_var(ncid, 0, name_in, &type_in, &ndims, dims_in, &natts)) ERR;
if (strcmp(name_in, VAR_NAME) || type_in != NC_FLOAT || ndims != NDIMS2 ||
dims_in[0] != dims[0] || dims_in[1] != dims[1] || natts != 0) ERR;
if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
if (strcmp(name_in, X_NAME) || len_in != XDIM_LEN) ERR;
if (nc_inq_dim(ncid, 1, name_in, &len_in)) ERR;
if (strcmp(name_in, Y_NAME)) ERR;
if (len_in != YDIM_LEN) ERR;
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
printf("**** testing chunking turned on by fletcher...");
{
int varid, ncid, dims[NDIMS2];
int storage_in;
size_t chunksizes_in[NDIMS2];
/* if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR; */
/* if (nc_def_dim(ncid, X_NAME, XDIM_LEN, &dims[0])) ERR; */
/* if (nc_def_dim(ncid, Y_NAME, YDIM_LEN, &dims[1])) ERR; */
/* if (nc_def_var(ncid, VAR_NAME, NC_FLOAT, 2, dims, &varid)) ERR; */
/* if (nc_def_var_fletcher32(ncid, varid, NC_FLETCHER32)) ERR; */
/* if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksizes_in)) ERR; */
/* if (chunksizes_in[0] != XDIM_LEN || chunksizes_in[1] != YDIM_LEN) ERR; */
/* if (nc_close(ncid)) ERR; */
if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
if (nc_def_dim(ncid, X_NAME, XDIM_LEN, &dims[0])) ERR;
if (nc_def_dim(ncid, Y_NAME, YDIM_LEN, &dims[1])) ERR;
if (nc_def_var(ncid, VAR_NAME, NC_FLOAT, 2, dims, &varid)) ERR;
if (nc_def_var_fletcher32(ncid, varid, NC_FLETCHER32)) ERR;
if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksizes_in)) ERR;
if (chunksizes_in[0] != XDIM_LEN || chunksizes_in[1] != YDIM_LEN) ERR;
if (nc_close(ncid)) ERR;
/* /\* Open the file and check. *\/ */
/* if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; */
/* if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksizes_in)) ERR; */
/* if (chunksizes_in[0] != XDIM_LEN || chunksizes_in[1] != YDIM_LEN) ERR; */
/* if (nc_close(ncid)) ERR; */
/* } */
/* SUMMARIZE_ERR; */
/* printf("**** testing chunking turned on by shuffle..."); */
/* { */
/* int varid, ncid, dims[NDIMS2]; */
/* int storage_in; */
/* size_t chunksizes_in[NDIMS2]; */
/* Open the file and check. */
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksizes_in)) ERR;
if (chunksizes_in[0] != XDIM_LEN || chunksizes_in[1] != YDIM_LEN) ERR;
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
printf("**** testing chunking turned on by shuffle...");
{
int varid, ncid, dims[NDIMS2];
int storage_in;
size_t chunksizes_in[NDIMS2];
/* if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR; */
/* if (nc_def_dim(ncid, X_NAME, XDIM_LEN, &dims[0])) ERR; */
/* if (nc_def_dim(ncid, Y_NAME, YDIM_LEN, &dims[1])) ERR; */
/* if (nc_def_var(ncid, VAR_NAME, NC_FLOAT, 2, dims, &varid)) ERR; */
/* if (nc_def_var_deflate(ncid, varid, NC_SHUFFLE, 0, 0)) ERR; */
/* if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksizes_in)) ERR; */
/* if (chunksizes_in[0] != XDIM_LEN || chunksizes_in[1] != YDIM_LEN) ERR; */
/* if (nc_close(ncid)) ERR; */
if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
if (nc_def_dim(ncid, X_NAME, XDIM_LEN, &dims[0])) ERR;
if (nc_def_dim(ncid, Y_NAME, YDIM_LEN, &dims[1])) ERR;
if (nc_def_var(ncid, VAR_NAME, NC_FLOAT, 2, dims, &varid)) ERR;
if (nc_def_var_deflate(ncid, varid, NC_SHUFFLE, 0, 0)) ERR;
if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksizes_in)) ERR;
if (chunksizes_in[0] != XDIM_LEN || chunksizes_in[1] != YDIM_LEN) ERR;
if (nc_close(ncid)) ERR;
/* /\* Open the file and check. *\/ */
/* if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; */
/* if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksizes_in)) ERR; */
/* if (chunksizes_in[0] != XDIM_LEN || chunksizes_in[1] != YDIM_LEN) ERR; */
/* if (nc_close(ncid)) ERR; */
/* } */
/* SUMMARIZE_ERR; */
/* #define DIM_NAME "Distance_from_Mayo" */
/* #define VAR_NAME_2 "Rocky_Road_to_Dublin" */
/* #define NDIMS1 1 */
/* #define NUM_RECORDS 3 */
/* printf("**** testing extending var along unlimited dim with no coord var..."); */
/* { */
/* int varid, ncid, dimid; */
/* int ndims, nvars, natts, unlimdimid; */
/* size_t dim_len_in, index; */
/* int data = TEST_VAL_42; */
/* Open the file and check. */
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
if (nc_inq_var_chunking(ncid, varid, &storage_in, chunksizes_in)) ERR;
if (chunksizes_in[0] != XDIM_LEN || chunksizes_in[1] != YDIM_LEN) ERR;
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
#define DIM_NAME "Distance_from_Mayo"
#define VAR_NAME_2 "Rocky_Road_to_Dublin"
#define NDIMS1 1
#define NUM_RECORDS 3
printf("**** testing extending var along unlimited dim with no coord var...");
{
int varid, ncid, dimid;
int ndims, nvars, natts, unlimdimid;
size_t dim_len_in, index;
int data = TEST_VAL_42;
/* /\* Create the test file with one var, one unlimited dim. *\/ */
/* if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR; */
/* if (nc_def_dim(ncid, DIM_NAME, NC_UNLIMITED, &dimid)) ERR; */
/* if (nc_def_var(ncid, VAR_NAME_2, NC_INT, NDIMS1, &dimid, &varid)) ERR; */
/* Create the test file with one var, one unlimited dim. */
if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
if (nc_def_dim(ncid, DIM_NAME, NC_UNLIMITED, &dimid)) ERR;
if (nc_def_var(ncid, VAR_NAME_2, NC_INT, NDIMS1, &dimid, &varid)) ERR;
/* /\* Write some records. *\/ */
/* for (index = 0; index < NUM_RECORDS; index++) */
/* if (nc_put_var1_int(ncid, varid, &index, &data)) ERR; */
/* if (nc_close(ncid)) ERR; */
/* Write some records. */
for (index = 0; index < NUM_RECORDS; index++)
if (nc_put_var1_int(ncid, varid, &index, &data)) ERR;
if (nc_close(ncid)) ERR;
/* /\* Open the file and check. *\/ */
/* if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; */
/* if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; */
/* if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != 0) ERR; */
/* if (nc_inq_dim(ncid, dimid, NULL, &dim_len_in)) ERR; */
/* if (dim_len_in != NUM_RECORDS) ERR; */
/* Open the file and check. */
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != 0) ERR;
if (nc_inq_dim(ncid, dimid, NULL, &dim_len_in)) ERR;
if (dim_len_in != NUM_RECORDS) ERR;
/* /\* Now add more records. *\/ */
/* for (index = 3; index < NUM_RECORDS * 2; index++) */
/* if (nc_put_var1_int(ncid, varid, &index, &data)) ERR; */
/* if (nc_inq_dim(ncid, dimid, NULL, &dim_len_in)) ERR; */
/* Now add more records. */
for (index = 3; index < NUM_RECORDS * 2; index++)
if (nc_put_var1_int(ncid, varid, &index, &data)) ERR;
if (nc_inq_dim(ncid, dimid, NULL, &dim_len_in)) ERR;
/* if (dim_len_in != NUM_RECORDS * 2) ERR; */
if (dim_len_in != NUM_RECORDS * 2) ERR;
/* /\* Close the file. *\/ */
/* if (nc_close(ncid)) ERR; */
/* } */
/* SUMMARIZE_ERR; */
#define CLAIR "Clair"
#define JAMIE "Jamie"
/* Close the file. */
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
printf("**** testing type creation and destruction for atomic types...");
{
int varid1, varid2, ncid;
int ndims, nvars, natts, unlimdimid;
/* Create the test file with two scalar vars. */
nc_set_log_level(4);
/* nc_set_log_level(4); */
if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
if (nc_def_var(ncid, CLAIR, NC_INT, 0, NULL, &varid1)) ERR;
if (nc_def_var(ncid, JAMIE, NC_INT, 0, NULL, &varid2)) ERR;
@ -165,5 +165,36 @@ main(int argc, char **argv)
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
printf("**** testing scalar big endian vars...");
{
int varid1, varid2, ncid;
int ndims, nvars, natts, unlimdimid;
int test_val = TEST_VAL_42;
int test_val2 = TEST_VAL_42 * 2;
int data_in;
/* Create the test file with two scalar vars. */
nc_set_log_level(4);
if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
if (nc_def_var(ncid, CLAIR, NC_INT, 0, NULL, &varid1)) ERR;
if (nc_def_var_endian(ncid, varid1, NC_ENDIAN_BIG)) ERR;
if (nc_def_var(ncid, JAMIE, NC_INT, 0, NULL, &varid2)) ERR;
if (nc_def_var_endian(ncid, varid2, NC_ENDIAN_BIG)) ERR;
if (nc_enddef(ncid)) ERR;
if (nc_put_var(ncid, varid1, &test_val)) ERR;
if (nc_put_var(ncid, varid2, &test_val2)) ERR;
if (nc_close(ncid)) ERR;
/* Open the file and check. */
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
if (ndims != 0 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
if (nc_get_var(ncid, varid1, &data_in)) ERR;
if (data_in != TEST_VAL_42) ERR;
if (nc_get_var(ncid, varid2, &data_in)) ERR;
if (data_in != TEST_VAL_42 * 2) ERR;
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
FINAL_RESULTS;
}

9759
nc_test4/tst_wrf_reads.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -431,13 +431,15 @@ Internal equivalent of ncaux_reclaim_data.
/* It is helpful to have a structure that contains memory and an offset */
typedef struct Reclaim {char* memory; ptrdiff_t offset;} Reclaim;
static ptrdiff_t read_alignment(ptrdiff_t offset, unsigned long alignment);
static int bin_reclaim_datar(Symbol* tsym, Reclaim* reclaim);
#ifdef USE_NETCDF4
static ptrdiff_t read_alignment(ptrdiff_t offset, unsigned long alignment);
static int bin_reclaim_usertype(Symbol* tsym, Reclaim* reclaim);
static int bin_reclaim_compound(Symbol* tsym, Reclaim* reclaim);
static int bin_reclaim_vlen(Symbol* tsym, Reclaim* reclaim);
static int bin_reclaim_enum(Symbol* tsym, Reclaim* reclaim);
static int bin_reclaim_opaque(Symbol* tsym, Reclaim* reclaim);
#endif
int
binary_reclaim_data(Symbol* tsym, void* memory, size_t count)
@ -493,6 +495,7 @@ bin_reclaim_datar(Symbol* tsym, Reclaim* reclaimer)
return stat;
}
#ifdef USE_NETCDF4
static int
bin_reclaim_usertype(Symbol* tsym, Reclaim* reclaimer)
{
@ -587,6 +590,7 @@ bin_reclaim_compound(Symbol* tsym, Reclaim* reclaimer)
done:
return stat;
}
#endif /*USE_NETCDF4*/
#endif /*ENABLE_BINARY*/

View File

@ -52,7 +52,7 @@
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
* if you want the limit (max/min) macros for int types.
* if you want the limit (max/min) macros for int types.
*/
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
@ -69,7 +69,7 @@ typedef uint32_t flex_uint32_t;
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
@ -195,7 +195,7 @@ extern FILE *ncgin, *ncgout;
#define YY_LESS_LINENO(n)
#define YY_LINENO_REWIND_TO(ptr)
/* Return all but the first "n" matched characters back to the input stream. */
#define yyless(n) \
do \
@ -252,7 +252,7 @@ struct yy_buffer_state
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@ -1409,9 +1409,9 @@ extern int ncgwrap (void );
#endif
#ifndef YY_NO_UNPUT
static void yyunput (int c,char *buf_ptr );
#endif
#ifndef yytext_ptr
@ -1539,7 +1539,7 @@ YY_DECL
yy_state_type yy_current_state;
char *yy_cp, *yy_bp;
int yy_act;
if ( !(yy_init) )
{
(yy_init) = 1;
@ -2438,7 +2438,7 @@ static int yy_get_next_buffer (void)
{
yy_state_type yy_current_state;
char *yy_cp;
yy_current_state = (yy_start);
for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
@ -2494,7 +2494,7 @@ static int yy_get_next_buffer (void)
static void yyunput (int c, char * yy_bp )
{
char *yy_cp;
yy_cp = (yy_c_buf_p);
/* undo effects of setting up ncgtext */
@ -2539,7 +2539,7 @@ static int yy_get_next_buffer (void)
{
int c;
*(yy_c_buf_p) = (yy_hold_char);
if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
@ -2606,12 +2606,12 @@ static int yy_get_next_buffer (void)
/** Immediately switch to a different input stream.
* @param input_file A readable stream.
*
*
* @note This function does not reset the start condition to @c INITIAL .
*/
void ncgrestart (FILE * input_file )
{
if ( ! YY_CURRENT_BUFFER ){
ncgensure_buffer_stack ();
YY_CURRENT_BUFFER_LVALUE =
@ -2624,11 +2624,11 @@ static int yy_get_next_buffer (void)
/** Switch to a different input buffer.
* @param new_buffer The new input buffer.
*
*
*/
void ncg_switch_to_buffer (YY_BUFFER_STATE new_buffer )
{
/* TODO. We should be able to replace this entire function body
* with
* ncgpop_buffer_state();
@ -2668,13 +2668,13 @@ static void ncg_load_buffer_state (void)
/** Allocate and initialize an input buffer state.
* @param file A readable stream.
* @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
*
*
* @return the allocated buffer state.
*/
YY_BUFFER_STATE ncg_create_buffer (FILE * file, int size )
{
YY_BUFFER_STATE b;
b = (YY_BUFFER_STATE) ncgalloc(sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in ncg_create_buffer()" );
@ -2697,11 +2697,11 @@ static void ncg_load_buffer_state (void)
/** Destroy the buffer.
* @param b a buffer created with ncg_create_buffer()
*
*
*/
void ncg_delete_buffer (YY_BUFFER_STATE b )
{
if ( ! b )
return;
@ -2722,7 +2722,7 @@ static void ncg_load_buffer_state (void)
{
int oerrno = errno;
ncg_flush_buffer(b );
b->yy_input_file = file;
@ -2738,13 +2738,13 @@ static void ncg_load_buffer_state (void)
}
b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
errno = oerrno;
}
/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
*
*
*/
void ncg_flush_buffer (YY_BUFFER_STATE b )
{
@ -2773,7 +2773,7 @@ static void ncg_load_buffer_state (void)
* the current state. This function will allocate the stack
* if necessary.
* @param new_buffer The new state.
*
*
*/
void ncgpush_buffer_state (YY_BUFFER_STATE new_buffer )
{
@ -2803,7 +2803,7 @@ void ncgpush_buffer_state (YY_BUFFER_STATE new_buffer )
/** Removes and deletes the top of the stack, if present.
* The next element becomes the new top.
*
*
*/
void ncgpop_buffer_state (void)
{
@ -2827,7 +2827,7 @@ void ncgpop_buffer_state (void)
static void ncgensure_buffer_stack (void)
{
yy_size_t num_to_alloc;
if (!(yy_buffer_stack)) {
/* First allocation is just for 2 elements, since we don't know if this
@ -2840,9 +2840,9 @@ static void ncgensure_buffer_stack (void)
);
if ( ! (yy_buffer_stack) )
YY_FATAL_ERROR( "out of dynamic memory in ncgensure_buffer_stack()" );
memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
(yy_buffer_stack_max) = num_to_alloc;
(yy_buffer_stack_top) = 0;
return;
@ -2870,13 +2870,13 @@ static void ncgensure_buffer_stack (void)
/** Setup the input buffer state to scan directly from a user-specified character buffer.
* @param base the character buffer
* @param size the size in bytes of the character buffer
*
* @return the newly allocated buffer state object.
*
* @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE ncg_scan_buffer (char * base, yy_size_t size )
{
YY_BUFFER_STATE b;
if ( size < 2 ||
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
@ -2905,14 +2905,14 @@ YY_BUFFER_STATE ncg_scan_buffer (char * base, yy_size_t size )
/** Setup the input buffer state to scan a string. The next call to ncglex() will
* scan from a @e copy of @a str.
* @param yystr a NUL-terminated string to scan
*
*
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
* ncg_scan_bytes() instead.
*/
YY_BUFFER_STATE ncg_scan_string (yyconst char * yystr )
{
return ncg_scan_bytes(yystr,strlen(yystr) );
}
@ -2920,7 +2920,7 @@ YY_BUFFER_STATE ncg_scan_string (yyconst char * yystr )
* scan from a @e copy of @a bytes.
* @param yybytes the byte buffer to scan
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
*
*
* @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE ncg_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
@ -2929,7 +2929,7 @@ YY_BUFFER_STATE ncg_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len
char *buf;
yy_size_t n;
yy_size_t i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
buf = (char *) ncgalloc(n );
@ -2983,16 +2983,16 @@ static void yy_fatal_error (yyconst char* msg )
/* Accessor methods (get/set functions) to struct members. */
/** Get the current line number.
*
*
*/
int ncgget_lineno (void)
{
return ncglineno;
}
/** Get the input stream.
*
*
*/
FILE *ncgget_in (void)
{
@ -3000,7 +3000,7 @@ FILE *ncgget_in (void)
}
/** Get the output stream.
*
*
*/
FILE *ncgget_out (void)
{
@ -3008,7 +3008,7 @@ FILE *ncgget_out (void)
}
/** Get the length of the current token.
*
*
*/
yy_size_t ncgget_leng (void)
{
@ -3016,7 +3016,7 @@ yy_size_t ncgget_leng (void)
}
/** Get the current token.
*
*
*/
char *ncgget_text (void)
@ -3026,18 +3026,18 @@ char *ncgget_text (void)
/** Set the current line number.
* @param _line_number line number
*
*
*/
void ncgset_lineno (int _line_number )
{
ncglineno = _line_number;
}
/** Set the input stream. This does not discard the current
* input buffer.
* @param _in_str A readable stream.
*
*
* @see ncg_switch_to_buffer
*/
void ncgset_in (FILE * _in_str )
@ -3091,7 +3091,7 @@ static int yy_init_globals (void)
/* ncglex_destroy is for both reentrant and non-reentrant scanners. */
int ncglex_destroy (void)
{
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
ncg_delete_buffer(YY_CURRENT_BUFFER );
@ -3117,7 +3117,7 @@ int ncglex_destroy (void)
#ifndef yytext_ptr
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
{
int i;
for ( i = 0; i < n; ++i )
s1[i] = s2[i];
@ -3142,7 +3142,7 @@ void *ncgalloc (yy_size_t size )
void *ncgrealloc (void * ptr, yy_size_t size )
{
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
* that use void* generic pointers. It works with the latter
@ -3163,6 +3163,7 @@ void ncgfree (void * ptr )
#line 572 "ncgen.l"
static int
lexdebug(int token)
{
@ -3452,4 +3453,3 @@ collecttag(char* text, char** stagp)
}
return tag;
}

View File

@ -24,6 +24,7 @@ run_nc4_tests.sh XGetopt.c $(man_MANS)
# There is a netcdf classic and netcdf-4 test script, but don't run
# them for DLL builds.
#if !BUILD_DLL
TESTS = run_tests.sh
if USE_HDF5
TESTS += run_nc4_tests.sh