diff --git a/CMakeInstallation.cmake b/CMakeInstallation.cmake index 80714b8b1..18be367f7 100644 --- a/CMakeInstallation.cmake +++ b/CMakeInstallation.cmake @@ -38,6 +38,7 @@ SET(CPACK_SOURCE_IGNORE_FILES "${CPACK_SOURCE_IGNORE_FILES}" "/obsolete/" "/unknown/" ".*~" + ".git/" ) ### @@ -56,9 +57,9 @@ IF(WIN32) SET(CPACK_NSIS_CONTACT "support-netcdf@unidata.ucar.edu") SET(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) SET(CPACK_NSIS_MENU_LINKS - "http://www.unidata.ucar.edu/netcdf" "Unidata Website" - "http://www.unidata.ucar.edu/netcdf/docs" "NetCDF Stable Documentation" - "http://www.unidata.ucar.edu/netcdf/docs_rc" "NetCDF Unstable Documentation") + "http://www.unidata.ucar.edu/software/netcdf" "Unidata Website" + "http://www.unidata.ucar.edu/software/netcdf/docs" "NetCDF Stable Documentation" + "http://www.unidata.ucar.edu/software/netcdf/docs_rc" "NetCDF Unstable Documentation") ENDIF() @@ -103,7 +104,7 @@ ENDIF() IF(APPLE) SET(CPACK_SOURCE_GENERATOR "TGZ") - SET(CPACK_GENERATOR "PackageMaker" "STGZ" "TBZ2" "TGZ" "ZIP") + SET(CPACK_GENERATOR "productbuild" "STGZ" "TBZ2" "TGZ" "ZIP") ENDIF() ## diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d9d7e561..0a77fde27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ IF(MSVC) ENDIF() #Add custom CMake Module -SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/" +SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/" CACHE INTERNAL "Location of our custom CMake modules.") # auto-configure style checks, other CMake modules. diff --git a/include/hdf5internal.h b/include/hdf5internal.h index 764e06e59..0d8435c74 100644 --- a/include/hdf5internal.h +++ b/include/hdf5internal.h @@ -135,7 +135,14 @@ int nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_IN 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. */ +/* Create HDF5 dataset for dim without a coord var. */ +extern int nc4_create_dim_wo_var(NC_DIM_INFO_T *dim); + +/* Give a var a secret HDF5 name, for use when there is a dim of this + * name, but the var is not a coord var of that dim. */ +extern int nc4_give_var_secret_name(NC_VAR_INFO_T *var); + +/* Get the fill value for a var. */ int nc4_get_fill_value(NC_FILE_INFO_T *h5, NC_VAR_INFO_T *var, void **fillp); diff --git a/include/nc4internal.h b/include/nc4internal.h index e750ec63d..4088062b5 100644 --- a/include/nc4internal.h +++ b/include/nc4internal.h @@ -153,7 +153,7 @@ typedef struct NC_VAR_INFO nc_bool_t created; /* Variable has already been created (_not_ that it was just created) */ 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. */ + int atts_read; /* If true, the atts have been read. */ nc_bool_t meta_read; /* True if this vars metadata has been completely read. */ nc_bool_t coords_read; /* True if this var has hidden coordinates att, and it has been read. */ NCindex *att; /* NCindex */ @@ -229,7 +229,7 @@ typedef struct NC_GRP_INFO void *format_grp_info; struct NC_FILE_INFO *nc4_info; struct NC_GRP_INFO *parent; - int atts_not_read; + int atts_read; /* True if atts have been read for this group. */ NCindex* children; /* NCindex */ NCindex* dim; /* NCindex * */ NCindex* att; /* NCindex * */ diff --git a/include/ncconfigure.h b/include/ncconfigure.h index aa00d09a6..66fe1ffc8 100644 --- a/include/ncconfigure.h +++ b/include/ncconfigure.h @@ -89,4 +89,8 @@ typedef unsigned short ushort; typedef unsigned int uint; #endif +#ifndef NC_UNUSED +#define NC_UNUSED(var) (void)var +#endif + #endif /* NCCONFIGURE_H */ diff --git a/libdispatch/dparallel.c b/libdispatch/dparallel.c index 730ba94b3..0823d9668 100644 --- a/libdispatch/dparallel.c +++ b/libdispatch/dparallel.c @@ -102,6 +102,11 @@ int nc_create_par(const char *path, int cmode, MPI_Comm comm, MPI_Info info, int *ncidp) { #ifndef USE_PARALLEL + NC_UNUSED(path); + NC_UNUSED(cmode); + NC_UNUSED(comm); + NC_UNUSED(info); + NC_UNUSED(ncidp); return NC_ENOPAR; #else NC_MPI_INFO data; @@ -201,6 +206,11 @@ nc_open_par(const char *path, int omode, MPI_Comm comm, MPI_Info info, int *ncidp) { #ifndef USE_PARALLEL + NC_UNUSED(path); + NC_UNUSED(omode); + NC_UNUSED(comm); + NC_UNUSED(info); + NC_UNUSED(ncidp); return NC_ENOPAR; #else NC_MPI_INFO mpi_data; @@ -249,6 +259,11 @@ nc_open_par_fortran(const char *path, int omode, int comm, int info, int *ncidp) { #ifndef USE_PARALLEL + NC_UNUSED(path); + NC_UNUSED(omode); + NC_UNUSED(comm); + NC_UNUSED(info); + NC_UNUSED(ncidp); return NC_ENOPAR; #else MPI_Comm comm_c; @@ -348,6 +363,9 @@ int nc_var_par_access(int ncid, int varid, int par_access) { #ifndef USE_PARALLEL + NC_UNUSED(ncid); + NC_UNUSED(varid); + NC_UNUSED(par_access); return NC_ENOPAR; #else int stat = NC_NOERR; @@ -403,6 +421,11 @@ nc_create_par_fortran(const char *path, int cmode, int comm, int info, int *ncidp) { #ifndef USE_PARALLEL + NC_UNUSED(path); + NC_UNUSED(cmode); + NC_UNUSED(comm); + NC_UNUSED(info); + NC_UNUSED(ncidp); return NC_ENOPAR; #else MPI_Comm comm_c; diff --git a/libdispatch/drc.c b/libdispatch/drc.c index 2ad784472..318b42ec9 100644 --- a/libdispatch/drc.c +++ b/libdispatch/drc.c @@ -396,8 +396,8 @@ rcsearch(const char* prefix, const char* rcname, char** pathp) { char* path = NULL; FILE* f = NULL; - int plen = strlen(prefix); - int rclen = strlen(rcname); + size_t plen = strlen(prefix); + size_t rclen = strlen(rcname); int ret = NC_NOERR; size_t pathlen = plen+rclen+1; /*+1 for '/' */ diff --git a/libdispatch/dutil.c b/libdispatch/dutil.c index 927c6d690..e4df1ea7b 100644 --- a/libdispatch/dutil.c +++ b/libdispatch/dutil.c @@ -210,7 +210,7 @@ NC_mktmp(const char* base) char spid[7]; if(rno < 0) rno = -rno; snprintf(spid,sizeof(spid),"%06d",rno); - strncat(tmp,spid,sizeof(tmp)); + strncat(tmp,spid,sizeof(tmp) - strlen(tmp) - 1); } #endif /* HAVE_MKTEMP */ #ifdef _MSC_VER diff --git a/libdispatch/nclog.c b/libdispatch/nclog.c index bcf94e310..7263fee12 100644 --- a/libdispatch/nclog.c +++ b/libdispatch/nclog.c @@ -213,6 +213,7 @@ Each line will be sent using nclog with the specified tag. void nclogtextn(int tag, const char* text, size_t count) { + NC_UNUSED(tag); if(!nclogging || nclogstream == NULL) return; fwrite(text,1,count,nclogstream); fflush(nclogstream); diff --git a/libdispatch/nctime.c b/libdispatch/nctime.c index aed5ac984..08df27bb1 100644 --- a/libdispatch/nctime.c +++ b/libdispatch/nctime.c @@ -23,6 +23,7 @@ #include #include #include +#include "ncconfigure.h" #include "nctime.h" static int cuErrOpts; /* Error options */ @@ -309,7 +310,7 @@ cdParseRelunits(cdCalenType timetype, char* relunits, cdUnitTime* unit, cdCompTi char charunits[CD_MAX_RELUNITS]; char basetime_1[CD_MAX_CHARTIME]; char basetime_2[CD_MAX_CHARTIME]; - char basetime[CD_MAX_CHARTIME]; + char basetime[2 * CD_MAX_CHARTIME + 1]; int nconv1, nconv2, nconv; /* Parse the relunits */ @@ -659,6 +660,7 @@ Cdh2e(CdTime *htime, double *etime) static int cdValidateTime(cdCalenType timetype, cdCompTime comptime) { + NC_UNUSED(timetype); if(comptime.month<1 || comptime.month>12){ cdError("Error on time conversion: invalid month = %hd\n",comptime.month); return 1; diff --git a/libdispatch/ncuri.c b/libdispatch/ncuri.c index 03a741965..a023cf673 100644 --- a/libdispatch/ncuri.c +++ b/libdispatch/ncuri.c @@ -67,7 +67,7 @@ static char* queryallow = static char* userpwdallow = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!$&'()*+,-.;=_~?#/"; -#ifndef HAVE_STRNCMP +#ifndef HAVE_STRNDUP #define strndup ncstrndup /* Not all systems have strndup, so provide one*/ char* @@ -258,7 +258,7 @@ ncuriparse(const char* uri0, NCURI** durip) isfile = (strcmp(tmp.protocol,"file")==0); if(isfile) { - int l = strlen(p); /* to test if we have enough characters */ + size_t l = strlen(p); /* to test if we have enough characters */ hashost = 0; /* always */ if(l >= 2 && p[1] == ':' && strchr(DRIVELETTERS,p[0]) != NULL) { /* case 1 */ ; /* p points to the start of the path */ diff --git a/libhdf4/hdf4file.c b/libhdf4/hdf4file.c index 3d8eb4b3a..f97ff37aa 100644 --- a/libhdf4/hdf4file.c +++ b/libhdf4/hdf4file.c @@ -415,6 +415,7 @@ nc4_var_list_add_full(NC_GRP_INFO_T* grp, const char* name, int ndims, nc_type x (*var)->created = NC_TRUE; (*var)->written_to = NC_TRUE; (*var)->format_var_info = format_var_info; + (*var)->atts_read = 1; /* Fill special type_info struct for variable type information. */ if ((retval = nc4_set_var_type(xtype, endianness, type_size, type_name, @@ -630,6 +631,7 @@ NC_HDF4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, assert(nc4_info && nc4_info->root_grp); h5 = nc4_info; h5->no_write = NC_TRUE; + h5->root_grp->atts_read = 1; /* Allocate data to hold HDF4 specific file data. */ if (!(hdf4_file = malloc(sizeof(NC_HDF4_FILE_INFO_T)))) diff --git a/libhdf5/hdf5attr.c b/libhdf5/hdf5attr.c index 3aeb8ce97..978c33c2b 100644 --- a/libhdf5/hdf5attr.c +++ b/libhdf5/hdf5attr.c @@ -27,13 +27,14 @@ static int getattlist(NC_GRP_INFO_T *grp, int varid, NC_VAR_INFO_T **varp, NCindex **attlist) { - NC_VAR_INFO_T* var; int retval; + assert(grp && attlist); + if (varid == NC_GLOBAL) { /* Do we need to read the atts? */ - if (grp->atts_not_read) + if (!grp->atts_read) if ((retval = nc4_read_atts(grp, NULL))) return retval; @@ -43,12 +44,14 @@ getattlist(NC_GRP_INFO_T *grp, int varid, NC_VAR_INFO_T **varp, } else { + NC_VAR_INFO_T *var; + if (!(var = (NC_VAR_INFO_T *)ncindexith(grp->vars, varid))) return NC_ENOTVAR; assert(var->hdr.id == varid); /* Do we need to read the atts? */ - if (var->atts_not_read) + if (!var->atts_read) if ((retval = nc4_read_atts(grp, var))) return retval; diff --git a/libhdf5/hdf5create.c b/libhdf5/hdf5create.c index b09f26fcc..cf2ef4010 100644 --- a/libhdf5/hdf5create.c +++ b/libhdf5/hdf5create.c @@ -66,6 +66,7 @@ nc4_create_file(const char *path, int cmode, size_t initialsz, BAIL(retval); nc4_info = NC4_DATA(nc); assert(nc4_info && nc4_info->root_grp); + nc4_info->root_grp->atts_read = 1; /* Add struct to hold HDF5-specific file metadata. */ if (!(nc4_info->format_file_info = calloc(1, sizeof(NC_HDF5_FILE_INFO_T)))) diff --git a/libhdf5/hdf5file.c b/libhdf5/hdf5file.c index a40c3b767..395d9fd64 100644 --- a/libhdf5/hdf5file.c +++ b/libhdf5/hdf5file.c @@ -727,7 +727,7 @@ NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp) if (nattsp) { /* Do we need to read the atts? */ - if (grp->atts_not_read) + if (!grp->atts_read) if ((retval = nc4_read_atts(grp, NULL))) return retval; diff --git a/libhdf5/hdf5grp.c b/libhdf5/hdf5grp.c index 058dab6f8..588273aa5 100644 --- a/libhdf5/hdf5grp.c +++ b/libhdf5/hdf5grp.c @@ -67,6 +67,11 @@ NC4_def_grp(int parent_ncid, const char *name, int *new_ncid) return retval; if (!(g->format_grp_info = calloc(1, sizeof(NC_HDF5_GRP_INFO_T)))) return NC_ENOMEM; + + /* For new groups, there are no atts to read from file. */ + g->atts_read = 1; + + /* Return the ncid to the user. */ if (new_ncid) *new_ncid = grp->nc4_info->controller->ext_ncid | g->hdr.id; diff --git a/libhdf5/hdf5internal.c b/libhdf5/hdf5internal.c index 7b74dc7b5..a88ed9b01 100644 --- a/libhdf5/hdf5internal.c +++ b/libhdf5/hdf5internal.c @@ -385,7 +385,7 @@ delete_dimscale_dataset(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T *dim) * @param dim Pointer to dimension info struct. * * @return ::NC_NOERR No error. - * @author Quincey Koziol + * @author Quincey Koziol, Ed Hartnett */ int nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim) @@ -406,14 +406,14 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim) hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info; hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info; - /* Detach dimscales from the [new] coordinate variable */ + /* Detach dimscales from the [new] coordinate variable. */ if (var->dimscale_attached) { int dims_detached = 0; int finished = 0; int d; - /* Loop over all dimensions for variable */ + /* Loop over all dimensions for variable. */ for (d = 0; d < var->ndims && !finished; d++) { /* Is there a dimscale attached to this axis? */ @@ -439,7 +439,8 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim) /* Find dataset ID for dimension */ if (dim1->coord_var) - dim_datasetid = ((NC_HDF5_VAR_INFO_T *)(dim1->coord_var->format_var_info))->hdf_datasetid; + dim_datasetid = ((NC_HDF5_VAR_INFO_T *) + (dim1->coord_var->format_var_info))->hdf_datasetid; else dim_datasetid = hdf5_dim1->hdf_dimscaleid; @@ -450,7 +451,8 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim) if (dim_datasetid > 0) { LOG((3, "detaching scale from %s", var->hdr.name)); - if (H5DSdetach_scale(hdf5_var->hdf_datasetid, dim_datasetid, d) < 0) + if (H5DSdetach_scale(hdf5_var->hdf_datasetid, + dim_datasetid, d) < 0) BAIL(NC_EHDFERR); } var->dimscale_attached[d] = NC_FALSE; @@ -462,7 +464,7 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim) } } /* next variable dimension */ - /* Release & reset the array tracking attached dimscales */ + /* Release & reset the array tracking attached dimscales. */ free(var->dimscale_attached); var->dimscale_attached = NULL; need_to_reattach_scales++; @@ -476,31 +478,32 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim) BAIL(NC_EHDFERR); hdf5_dim->hdf_dimscaleid = 0; - /* Now delete the dimscale's dataset - (it will be recreated later, if necessary) */ + /* Now delete the dimscale's dataset (it will be recreated + later, if necessary). */ if (H5Gunlink(hdf5_grp->hdf_grpid, dim->hdr.name) < 0) return NC_EDIMMETA; } - /* Attach variable to dimension */ + /* Attach variable to dimension. */ var->dimscale = NC_TRUE; dim->coord_var = var; /* Check if this variable used to be a coord. var */ if (need_to_reattach_scales || (var->was_coord_var && grp != NULL)) { - /* Reattach the scale everywhere it is used. */ - /* (Recall that netCDF dimscales are always 1-D) */ + /* Reattach the scale everywhere it is used. (Recall that netCDF + * dimscales are always 1-D) */ if ((retval = rec_reattach_scales(grp->nc4_info->root_grp, var->dimids[0], hdf5_var->hdf_datasetid))) return retval; - /* Set state transition indicator (cancels earlier transition) */ + /* Set state transition indicator (cancels earlier + * transition). */ var->was_coord_var = NC_FALSE; } - else - /* Set state transition indicator */ - var->became_coord_var = NC_TRUE; + + /* Set state transition indicator */ + var->became_coord_var = NC_TRUE; exit: return retval; @@ -837,7 +840,7 @@ nc4_hdf5_find_grp_var_att(int ncid, int varid, const char *name, int attnum, if (varid == NC_GLOBAL) { /* Do we need to read the atts? */ - if (my_grp->atts_not_read) + if (!my_grp->atts_read) if ((retval = nc4_read_atts(my_grp, NULL))) return retval; @@ -849,7 +852,7 @@ nc4_hdf5_find_grp_var_att(int ncid, int varid, const char *name, int attnum, return NC_ENOTVAR; /* Do we need to read the var attributes? */ - if (my_var->atts_not_read) + if (!my_var->atts_read) if ((retval = nc4_read_atts(my_grp, my_var))) return retval; diff --git a/libhdf5/hdf5open.c b/libhdf5/hdf5open.c index b0fae521f..70d9a0cc6 100644 --- a/libhdf5/hdf5open.c +++ b/libhdf5/hdf5open.c @@ -1308,7 +1308,7 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name, H5Iinc_ref(hdf5_var->hdf_datasetid); /* Increment number of objects using ID */ incr_id_rc++; /* Indicate that we've incremented the ref. count (for errors) */ var->created = NC_TRUE; - var->atts_not_read = 1; /* Don't read var atts until user asks for one. */ + var->atts_read = 0; /* Try and read the dimids from the COORDINATES attribute. If it's * not present, we will have to do dimsscale matching to locate the @@ -2112,9 +2112,9 @@ nc4_read_atts(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var) /* Remember that we have read the atts for this var or group. */ if (var) - var->atts_not_read = 0; + var->atts_read = 1; else - grp->atts_not_read = 0; + grp->atts_read = 1; return NC_NOERR; } @@ -2569,9 +2569,6 @@ rec_read_metadata(NC_GRP_INFO_T *grp) BAIL(retval); } - /* Defer the reading of global atts until someone asks for one. */ - grp->atts_not_read = 1; - /* When reading existing file, mark all variables as written. */ for (i = 0; i < ncindexsize(grp->vars); i++) ((NC_VAR_INFO_T *)ncindexith(grp->vars, i))->written_to = NC_TRUE; diff --git a/libhdf5/hdf5var.c b/libhdf5/hdf5var.c index 46a8383e8..dc3176d70 100644 --- a/libhdf5/hdf5var.c +++ b/libhdf5/hdf5var.c @@ -220,6 +220,36 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var) return NC_NOERR; } +/** + * @internal Give a var a secret HDF5 name. This is needed when a var + * is defined with the same name as a dim, but it is not a coord var + * of that dim. In that case, the var uses a secret name inside the + * HDF5 file. + * + * @param var Pointer to var info. + * @param name Name to use for base of secret name. + * + * @returns ::NC_NOERR No error. + * @returns ::NC_EMAXNAME Name too long to fit secret prefix. + * @returns ::NC_ENOMEM Out of memory. + * @author Ed Hartnett + */ +static int +give_var_secret_name(NC_VAR_INFO_T *var, const char *name) +{ + /* Set a different hdf5 name for this variable to avoid name + * clash. */ + if (strlen(name) + strlen(NON_COORD_PREPEND) > NC_MAX_NAME) + return NC_EMAXNAME; + if (!(var->hdf5_name = malloc((strlen(NON_COORD_PREPEND) + + strlen(name) + 1) * sizeof(char)))) + return NC_ENOMEM; + + sprintf(var->hdf5_name, "%s%s", NON_COORD_PREPEND, name); + + return NC_NOERR; +} + /** * @internal This is called when a new netCDF-4 variable is defined * with nc_def_var(). @@ -410,6 +440,7 @@ NC4_def_var(int ncid, const char *name, nc_type xtype, var->is_new_var = NC_TRUE; var->meta_read = NC_TRUE; + var->atts_read = NC_TRUE; /* Point to the type, and increment its ref. count */ var->type_info = type; @@ -501,17 +532,8 @@ NC4_def_var(int ncid, const char *name, nc_type xtype, * and this var has the same name. */ dim = (NC_DIM_INFO_T*)ncindexlookup(grp->dim,norm_name); if (dim && (!var->ndims || dimidsp[0] != dim->hdr.id)) - { - /* Set a different hdf5 name for this variable to avoid name - * clash. */ - if (strlen(norm_name) + strlen(NON_COORD_PREPEND) > NC_MAX_NAME) - BAIL(NC_EMAXNAME); - if (!(var->hdf5_name = malloc((strlen(NON_COORD_PREPEND) + - strlen(norm_name) + 1) * sizeof(char)))) - BAIL(NC_ENOMEM); - - sprintf(var->hdf5_name, "%s%s", NON_COORD_PREPEND, norm_name); - } + if ((retval = give_var_secret_name(var, var->hdr.name))) + BAIL(retval); /* If this is a coordinate var, it is marked as a HDF5 dimension * scale. (We found dim above.) Otherwise, allocate space to @@ -1038,6 +1060,8 @@ NC4_rename_var(int ncid, int varid, const char *name) NC_HDF5_GRP_INFO_T *hdf5_grp; NC_FILE_INFO_T *h5; NC_VAR_INFO_T *var; + NC_DIM_INFO_T *other_dim; + int use_secret_name = 0; int retval = NC_NOERR; if (!name) @@ -1081,10 +1105,31 @@ NC4_rename_var(int ncid, int varid, const char *name) (h5->cmode & NC_CLASSIC_MODEL)) return NC_ENOTINDEFINE; + /* Is there another dim with this name, for which this var will not + * be a coord var? If so, we have to create a dim without a + * variable for the old name. */ + if ((other_dim = (NC_DIM_INFO_T *)ncindexlookup(grp->dim, name)) && + strcmp(name, var->dim[0]->hdr.name)) + { + /* Create a dim without var dataset for old dim. */ + if ((retval = nc4_create_dim_wo_var(other_dim))) + return retval; + + /* Give this var a secret HDF5 name so it can co-exist in file + * with dim wp var dataset. Base the secret name on the new var + * name. */ + if ((retval = give_var_secret_name(var, name))) + return retval; + use_secret_name++; + } + /* Change the HDF5 file, if this var has already been created there. */ if (var->created) { + char *hdf5_name; + hdf5_name = use_secret_name ? var->hdf5_name: (char *)name; + /* Do we need to read var metadata? */ if (!var->meta_read) if ((retval = nc4_get_var_meta(var))) @@ -1106,7 +1151,7 @@ NC4_rename_var(int ncid, int varid, const char *name) } LOG((3, "Moving dataset %s to %s", var->hdr.name, name)); - if (H5Gmove(hdf5_grp->hdf_grpid, var->hdr.name, name) < 0) + if (H5Gmove(hdf5_grp->hdf_grpid, var->hdr.name, hdf5_name) < 0) BAIL(NC_EHDFERR); } diff --git a/libhdf5/nc4hdf.c b/libhdf5/nc4hdf.c index 679629451..9b68ff399 100644 --- a/libhdf5/nc4hdf.c +++ b/libhdf5/nc4hdf.c @@ -1707,6 +1707,92 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid) return NC_NOERR; } +/** + * @internal Write a HDF5 dataset which is a dimension without a + * coordinate variable. This is a special 1-D dataset. + * + * @param dim Pointer to dim info struct. + * @param grp Pointer to group info struct. + * @param write_dimid + * + * @returns ::NC_NOERR No error. + * @returns ::NC_EPERM Read-only file. + * @returns ::NC_EHDFERR HDF5 returned error. + * @author Ed Hartnett + */ +int +nc4_create_dim_wo_var(NC_DIM_INFO_T *dim) +{ + NC_HDF5_DIM_INFO_T *hdf5_dim; + NC_HDF5_GRP_INFO_T *hdf5_grp; + hid_t spaceid = -1, create_propid = -1; + hsize_t dims[1], max_dims[1], chunk_dims[1] = {1}; + char dimscale_wo_var[NC_MAX_NAME]; + int retval = NC_NOERR; + + LOG((4, "%s: creating dim %s", __func__, dim->hdr.name)); + + /* Sanity check */ + assert(!dim->coord_var); + + /* Get HDF5-specific dim and group info. */ + hdf5_grp = (NC_HDF5_GRP_INFO_T *)dim->container->format_grp_info; + hdf5_dim = (NC_HDF5_DIM_INFO_T *)dim->format_dim_info; + + /* Create a property list. */ + if ((create_propid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + BAIL(NC_EHDFERR); + + /* Turn off recording of times associated with this object. */ + if (H5Pset_obj_track_times(create_propid, 0) < 0) + BAIL(NC_EHDFERR); + + /* Set size of dataset to size of dimension. */ + dims[0] = dim->len; + max_dims[0] = dim->len; + + /* If this dimension scale is unlimited (i.e. it's an unlimited + * dimension), then set up chunking, with a chunksize of 1. */ + if (dim->unlimited) + { + max_dims[0] = H5S_UNLIMITED; + if (H5Pset_chunk(create_propid, 1, chunk_dims) < 0) + BAIL(NC_EHDFERR); + } + + /* Set up space. */ + 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 = 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 + * be shown to the user as a variable. It is hidden. It is + * a DIM WITHOUT A VARIABLE! */ + sprintf(dimscale_wo_var, "%s%10d", DIM_WITHOUT_VARIABLE, (int)dim->len); + if (H5DSset_scale(hdf5_dim->hdf_dimscaleid, dimscale_wo_var) < 0) + BAIL(NC_EHDFERR); + +exit: + if (spaceid > 0 && H5Sclose(spaceid) < 0) + BAIL2(NC_EHDFERR); + if (create_propid > 0 && H5Pclose(create_propid) < 0) + BAIL2(NC_EHDFERR); + return retval; +} + /** * @internal Write a dimension. * @@ -1722,76 +1808,21 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid) 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; - hsize_t *new_size = NULL; int retval = NC_NOERR; assert(dim && dim->format_dim_info && grp && grp->format_grp_info); /* Get HDF5-specific dim and group info. */ hdf5_dim = (NC_HDF5_DIM_INFO_T *)dim->format_dim_info; - hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info; /* If there's no dimscale dataset for this dim, create one, * and mark that it should be hidden from netCDF as a * variable. (That is, it should appear as a dimension * without an associated variable.) */ if (!hdf5_dim->hdf_dimscaleid) - { - 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(!dim->coord_var); - - /* Create a property list. If this dimension scale is - * unlimited (i.e. it's an unlimited dimension), then set - * up chunking, with a chunksize of 1. */ - if ((create_propid = H5Pcreate(H5P_DATASET_CREATE)) < 0) - BAIL(NC_EHDFERR); - - /* Turn off recording of times associated with this object. */ - if (H5Pset_obj_track_times(create_propid,0)<0) - BAIL(NC_EHDFERR); - - dims[0] = dim->len; - max_dims[0] = dim->len; - if (dim->unlimited) - { - max_dims[0] = H5S_UNLIMITED; - if (H5Pset_chunk(create_propid, 1, chunk_dims) < 0) - BAIL(NC_EHDFERR); - } - - /* Set up space. */ - 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 = 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 - * be shown to the user as a variable. It is hidden. It is - * a DIM WITHOUT A VARIABLE! */ - sprintf(dimscale_wo_var, "%s%10d", DIM_WITHOUT_VARIABLE, (int)dim->len); - if (H5DSset_scale(hdf5_dim->hdf_dimscaleid, dimscale_wo_var) < 0) - BAIL(NC_EHDFERR); - } + if ((retval = nc4_create_dim_wo_var(dim))) + BAIL(retval); /* Did we extend an unlimited dimension? */ if (dim->extended) @@ -1806,6 +1837,7 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid) if (v1) { NC_HDF5_VAR_INFO_T *hdf5_v1; + hsize_t *new_size; int d1; hdf5_v1 = (NC_HDF5_VAR_INFO_T *)v1->format_var_info; @@ -1821,6 +1853,7 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid) } if (H5Dset_extent(hdf5_v1->hdf_datasetid, new_size) < 0) BAIL(NC_EHDFERR); + free(new_size); } } @@ -1833,12 +1866,6 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid) BAIL(retval); 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; } diff --git a/libsrc/posixio.c b/libsrc/posixio.c index 328b13aaf..ed7993b22 100644 --- a/libsrc/posixio.c +++ b/libsrc/posixio.c @@ -184,7 +184,11 @@ blksize(int fd) return 8192; } /* else, silent in the face of error */ +#else + NC_UNUSED(fd); #endif +#else + NC_UNUSED(fd); #endif return (size_t) 2 * pagesize(); } @@ -445,6 +449,7 @@ px_rel(ncio_px *const pxp, off_t offset, int rflags) && offset < pxp->bf_offset + (off_t) pxp->bf_extent); assert(pIf(fIsSet(rflags, RGN_MODIFIED), fIsSet(pxp->bf_rflags, RGN_WRITE))); + NC_UNUSED(offset); if(fIsSet(rflags, RGN_MODIFIED)) { @@ -797,6 +802,7 @@ px_double_buffer(ncio *const nciop, off_t to, off_t from, int status = NC_NOERR; void *src; void *dest; + NC_UNUSED(rflags); #if INSTRUMENT fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n", @@ -1152,6 +1158,7 @@ ncio_spx_rel(ncio *const nciop, off_t offset, int rflags) assert(offset < pxp->bf_offset + X_ALIGN); assert(pxp->bf_cnt % X_ALIGN == 0 ); #endif + NC_UNUSED(offset); if(fIsSet(rflags, RGN_MODIFIED)) { @@ -1400,6 +1407,7 @@ ncio_spx_move(ncio *const nciop, off_t to, off_t from, static int ncio_spx_sync(ncio *const nciop) { + NC_UNUSED(nciop); /* NOOP */ return NC_NOERR; } @@ -1592,6 +1600,7 @@ posixio_create(const char *path, int ioflags, int oflags = (O_RDWR|O_CREAT); int fd; int status; + NC_UNUSED(parameters); if(initialsz < (size_t)igeto + igetsz) initialsz = (size_t)igeto + igetsz; @@ -1736,6 +1745,7 @@ posixio_open(const char *path, int oflags = fIsSet(ioflags, NC_WRITE) ? O_RDWR : O_RDONLY; int fd = -1; int status = 0; + NC_UNUSED(parameters); if(path == NULL || *path == 0) return EINVAL; diff --git a/libsrc4/nc4var.c b/libsrc4/nc4var.c index 7c9b55c53..a60c1a184 100644 --- a/libsrc4/nc4var.c +++ b/libsrc4/nc4var.c @@ -390,6 +390,9 @@ int NC4_var_par_access(int ncid, int varid, int par_access) { #ifndef USE_PARALLEL4 + NC_UNUSED(ncid); + NC_UNUSED(varid); + NC_UNUSED(par_access); return NC_ENOPAR; #else NC *nc; diff --git a/nc_test4/Makefile.am b/nc_test4/Makefile.am index 4988be622..613427dcb 100644 --- a/nc_test4/Makefile.am +++ b/nc_test4/Makefile.am @@ -144,10 +144,10 @@ tst_floats2_*.cdl tst_ints2_*.cdl tst_shorts2_*.cdl tst_elena_*.cdl \ tst_simple*.cdl tst_chunks.cdl pr_A1.* tauu_A1.* usi_01.* thetau_01.* \ tst_*.h5 tst_grp_rename.cdl tst_grp_rename.dmp ref_grp_rename.cdl \ foo1.nc tst_*.h4 test.nc testszip.nc test.h5 szip_dump.cdl \ -perftest.txt bigmeta.nc bigvars.nc run_par_test.sh *.gz MSGCPP_*.nc \ +perftest.txt bigmeta.nc bigvars.nc *.gz MSGCPP_*.nc \ floats*.nc floats*.cdl shorts*.nc shorts*.cdl ints*.nc ints*.cdl -DISTCLEANFILES = findplugin.sh +DISTCLEANFILES = findplugin.sh run_par_test.sh # If valgrind is present, add valgrind targets. @VALGRIND_CHECK_RULES@ diff --git a/nc_test4/tst_rename2.c b/nc_test4/tst_rename2.c index 5382e7813..e50ff29e5 100644 --- a/nc_test4/tst_rename2.c +++ b/nc_test4/tst_rename2.c @@ -25,11 +25,18 @@ See \ref copyright file for more info. #define DIM_X "x" #define DIM_Y "y" #define DIM_Z "z" +#define VAR_NAME_START "lon" +#define VAR_NAME_END "lo" +#define DIM_NAME_START "lon" +#define DIM_NAME_END "lo" #define DIM1_LEN 4 #define NDIM1 1 #define NDIM3 3 #define NUM_ENDDEF_SETTINGS 2 +#define D1_NAME "d1" +#define D2_NAME "d2" +#define TMP_NAME "t1" int main(int argc, char **argv) @@ -147,5 +154,124 @@ main(int argc, char **argv) SUMMARIZE_ERR; } /* next format */ + +#define FILE_NAME1 "tst_dims_foo1.nc" +#define DIM_NAME "lat_T42" +#define VAR_NAME DIM_NAME +#define DIM_NAME2 "lat" +#define VAR_NAME2 DIM_NAME2 +#define RANK_lat_T42 1 + fprintf(stderr,"*** test renaming with sync..."); + { + int ncid, dimid, varid; + char file_name[NC_MAX_NAME + 1]; + char name[NC_MAX_NAME + 1]; + + /* Create file with dim and associated coordinate var. */ + sprintf(file_name, "%s_sync.nc", TEST_NAME); + if (nc_create(file_name, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; + if (nc_def_dim(ncid, DIM_NAME_END, DIM1_LEN, &dimid)) ERR; + if (nc_def_var(ncid, DIM_NAME_END, NC_INT, NDIM1, &dimid, &varid)) ERR; + if (nc_close(ncid)) ERR; + + if (nc_create(file_name, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; + if (nc_def_dim(ncid, DIM_NAME_START, DIM1_LEN, &dimid)) ERR; + if (nc_def_var(ncid, DIM_NAME_END, NC_INT, NDIM1, &dimid, &varid)) ERR; + if (nc_close(ncid)) ERR; + + if (nc_open(file_name, NC_WRITE, &ncid)) ERR; + if (nc_rename_dim(ncid, dimid, DIM_NAME_END)) ERR; + if (nc_close(ncid)) ERR; + + /* Reopen file and check, */ + if (nc_open(file_name, NC_WRITE, &ncid)) ERR; + if (nc_inq_dimid(ncid, DIM_NAME_END, &dimid)) ERR; + if (nc_inq_varid(ncid, DIM_NAME_END, &varid)) ERR; + if (nc_inq_dimname(ncid, dimid, name)) ERR; + if (strcmp(name, DIM_NAME_END)) ERR; + if (nc_inq_varname(ncid, varid, name)) ERR; + if (strcmp(name, DIM_NAME_END)) ERR; + if (nc_close(ncid)) ERR; + } + SUMMARIZE_ERR; + fprintf(stderr,"*** test renaming with sync..."); + { + int ncid, dimid, varid; + char file_name[NC_MAX_NAME + 1]; + char name[NC_MAX_NAME + 1]; + + /* Create file with dim and associated coordinate var. */ + sprintf(file_name, "%s_sync.nc", TEST_NAME); + if (nc_create(file_name, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; + if (nc_def_dim(ncid, DIM_NAME_START, DIM1_LEN, &dimid)) ERR; + if (nc_def_var(ncid, VAR_NAME_START, NC_INT, NDIM1, &dimid, &varid)) ERR; + if (nc_close(ncid)) ERR; + + /* nc_set_log_level(4); */ + /* Open the file and rename the var. */ + if (nc_open(file_name, NC_WRITE, &ncid)) ERR; + if (nc_inq_dimid(ncid, DIM_NAME_START, &dimid)) ERR; + if (nc_inq_varid(ncid, VAR_NAME_START, &varid)) ERR; + if (nc_rename_var(ncid, varid, VAR_NAME_END)) ERR; + + /* Sync to disk. Now the file has one dim and one var. The dim + * is a dimscale only dataset, and the var is a dataset with a + * dimscale attached pointing to the dim. */ + /* if (nc_sync(ncid)) ERR; */ + if (nc_close(ncid)) ERR; + if (nc_open(file_name, NC_WRITE, &ncid)) ERR; + /* Now rename the dim to the same name as the var. After this + * there will be one dataset, called DIM_NAME_END, which will be + * a dimscale. */ + if (nc_rename_dim(ncid, dimid, DIM_NAME_END)) ERR; + if (nc_close(ncid)) ERR; + + /* Reopen file and check, */ + if (nc_open(file_name, NC_WRITE, &ncid)) ERR; + if (nc_inq_dimid(ncid, DIM_NAME_END, &dimid)) ERR; + if (nc_inq_varid(ncid, VAR_NAME_END, &varid)) ERR; + if (nc_inq_dimname(ncid, dimid, name)) ERR; + if (strcmp(name, DIM_NAME_END)) ERR; + if (nc_inq_varname(ncid, varid, name)) ERR; + if (strcmp(name, VAR_NAME_END)) ERR; + if (nc_close(ncid)) ERR; + } + SUMMARIZE_ERR; + fprintf(stderr,"*** test renaming non-coord var to same name as dim..."); + { + int ncid, dimid1, dimid2, varid1, varid2; + int dimid_in, varid_in; + char file_name[NC_MAX_NAME + 1]; + + /* Create file with dim and associated coordinate var. */ + sprintf(file_name, "%s_non_coord_to_dim.nc", TEST_NAME); + if (nc_create(file_name, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; + if (nc_def_dim(ncid, D1_NAME, DIM1_LEN, &dimid1)) ERR; + if (nc_def_dim(ncid, D2_NAME, DIM1_LEN, &dimid2)) ERR; + if (nc_def_var(ncid, D1_NAME, NC_INT, NDIM1, &dimid1, &varid1)) ERR; + if (nc_def_var(ncid, D2_NAME, NC_INT, NDIM1, &dimid2, &varid2)) ERR; + if (nc_close(ncid)) ERR; + + /* Open the file and rename the vars. */ + /* nc_set_log_level(4); */ + if (nc_open(file_name, NC_WRITE, &ncid)) ERR; + if (nc_rename_var(ncid, varid1, TMP_NAME)) ERR; + if (nc_rename_var(ncid, varid2, D1_NAME)) ERR; + if (nc_close(ncid)) ERR; + + /* Reopen file and check, */ + if (nc_open(file_name, NC_WRITE, &ncid)) ERR; + if (nc_inq_dimid(ncid, D1_NAME, &dimid_in)) ERR; + if (dimid_in != dimid1) ERR; + if (nc_inq_dimid(ncid, D2_NAME, &dimid_in)) ERR; + if (dimid_in != dimid2) ERR; + if (nc_inq_dimid(ncid, TMP_NAME, &dimid_in) != NC_EBADDIM) ERR; + if (nc_inq_varid(ncid, TMP_NAME, &varid_in)) ERR; + if (varid_in != varid1) ERR; + if (nc_inq_varid(ncid, D1_NAME, &varid_in)) ERR; + if (varid_in != varid2) ERR; + if (nc_close(ncid)) ERR; + } + SUMMARIZE_ERR; FINAL_RESULTS; }