mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-03 08:01:25 +08:00
9380790ea8
re: The current netcdf-c release has some problems with the mingw platform on windows. Mostly they are path issues. Changes to support mingw+msys2: ------------------------------- * Enable option of looking into the windows registry to find the mingw root path. In aid of proper path handling. * Add mingw+msys as a specific platform in configure.ac and move testing of the platform to the front so it is available early. * Handle mingw X libncpoco (dynamic loader) properly even though mingw does not yet support it. * Handle mingw X plugins properly even though mingw does not yet support it. * Alias pwd='pwd -W' to better handle paths in shell scripts. * Plus a number of other minor compile irritations. * Disallow the use of multiple nc_open's on the same file for windows (and mingw) because windows does not seem to handle these properly. Not sure why we did not catch this earlier. * Add mountpoint info to dpathmgr.c to help support mingw. * Cleanup dpathmgr conversions. Known problems: --------------- * I have not been able to get shared libraries to work, so plugins/filters must be disabled. * There is some kind of problem with libcurl that I have not solved, so all uses of libcurl (currently DAP+Byterange) must be disabled. Misc. other fixes: ------------------ * Cleanup the relationship between ENABLE_PLUGINS and various other flags in CMakeLists.txt and configure.ac. * Re-arrange the TESTDIRS order in Makefile.am. * Add pseudo-breakpoint to nclog.[ch] for debugging. * Improve the documentation of the path manager code in ncpathmgr.h * Add better support for relative paths in dpathmgr.c * Default the mode args to NCfopen to include "b" (binary) for windows. * Add optional debugging output in various places. * Make sure that everything builds with plugins disabled. * Fix numerous (s)printf inconsistencies betweenb the format spec and the arguments.
299 lines
7.6 KiB
C
299 lines
7.6 KiB
C
/*********************************************************************
|
|
* Copyright 1993, UCAR/Unidata
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
*********************************************************************/
|
|
|
|
#include "zincludes.h"
|
|
#include "zfilter.h"
|
|
|
|
/* Forward */
|
|
static int zclose_group(NC_GRP_INFO_T*);
|
|
static int zclose_gatts(NC_GRP_INFO_T*);
|
|
static int zclose_vars(NC_GRP_INFO_T*);
|
|
static int zclose_dims(NC_GRP_INFO_T*);
|
|
static int zclose_types(NC_GRP_INFO_T*);
|
|
static int zclose_type(NC_TYPE_INFO_T* type);
|
|
static int zwrite_vars(NC_GRP_INFO_T *grp);
|
|
|
|
/**************************************************/
|
|
|
|
/**
|
|
* @internal This function will recurse through an open ZARR file and
|
|
* release resources. All ZARR annotations reclaimed
|
|
*
|
|
* @param file Pointer to ZARR file info struct.
|
|
* @param abort True if this is an abort.
|
|
*
|
|
* @return ::NC_NOERR No error.
|
|
* @return ::NC_ENCZARR could not close the file.
|
|
* @author Dennis Heimbigner
|
|
*/
|
|
int
|
|
ncz_close_file(NC_FILE_INFO_T* file, int abort)
|
|
{
|
|
int stat = NC_NOERR;
|
|
NCZ_FILE_INFO_T* zinfo = NULL;
|
|
|
|
ZTRACE(2,"file=%s abort=%d",file->hdr.name,abort);
|
|
|
|
if(!abort) {
|
|
/* Flush | create all chunks for all vars */
|
|
if((stat=zwrite_vars(file->root_grp))) goto done;
|
|
}
|
|
|
|
/* Internal close to reclaim zarr annotations */
|
|
if((stat = zclose_group(file->root_grp)))
|
|
goto done;
|
|
|
|
zinfo = file->format_file_info;
|
|
|
|
if((stat = nczmap_close(zinfo->map,(abort && zinfo->created)?1:0)))
|
|
goto done;
|
|
NCZ_freestringvec(0,zinfo->envv_controls);
|
|
NC_authfree(zinfo->auth);
|
|
nullfree(zinfo);
|
|
|
|
done:
|
|
return ZUNTRACE(stat);
|
|
}
|
|
|
|
/**************************************************/
|
|
/**
|
|
* @internal Recursively free zarr annotations for a group (and everything
|
|
* it contains).
|
|
*
|
|
* @param grp Pointer to group info struct.
|
|
*
|
|
* @return ::NC_NOERR No error.
|
|
* @author Dennis Heimbigner
|
|
*/
|
|
static int
|
|
zclose_group(NC_GRP_INFO_T *grp)
|
|
{
|
|
int stat = NC_NOERR;
|
|
NCZ_GRP_INFO_T* zgrp;
|
|
int i;
|
|
|
|
assert(grp && grp->format_grp_info != NULL);
|
|
LOG((3, "%s: grp->name %s", __func__, grp->hdr.name));
|
|
|
|
/* Recursively call this function for each child, if any, stopping
|
|
* if there is an error. */
|
|
for(i=0; i<ncindexsize(grp->children); i++) {
|
|
if ((stat = zclose_group((NC_GRP_INFO_T*)ncindexith(grp->children,i))))
|
|
goto done;
|
|
}
|
|
|
|
/* Close resources associated with global attributes. */
|
|
if ((stat = zclose_gatts(grp)))
|
|
goto done;
|
|
|
|
/* Close resources associated with vars. */
|
|
if ((stat = zclose_vars(grp)))
|
|
goto done;
|
|
|
|
/* Close resources associated with dims. */
|
|
if ((stat = zclose_dims(grp)))
|
|
goto done;
|
|
|
|
/* Close resources associated with types. */
|
|
if ((stat = zclose_types(grp)))
|
|
goto done;
|
|
|
|
/* Close the zgroup. */
|
|
zgrp = grp->format_grp_info;
|
|
LOG((4, "%s: closing group %s", __func__, grp->hdr.name));
|
|
nullfree(zgrp);
|
|
grp->format_grp_info = NULL; /* avoid memory errors */
|
|
|
|
done:
|
|
return stat;
|
|
}
|
|
|
|
/**
|
|
* @internal Close resources for global atts in a group.
|
|
*
|
|
* @param grp Pointer to group info struct.
|
|
*
|
|
* @return ::NC_NOERR No error.
|
|
* @author Dennis Heimbigner
|
|
*/
|
|
static int
|
|
zclose_gatts(NC_GRP_INFO_T* grp)
|
|
{
|
|
int stat = NC_NOERR;
|
|
NC_ATT_INFO_T *att;
|
|
int a;
|
|
for(a = 0; a < ncindexsize(grp->att); a++) {
|
|
NCZ_ATT_INFO_T* zatt = NULL;
|
|
att = (NC_ATT_INFO_T* )ncindexith(grp->att, a);
|
|
assert(att && att->format_att_info != NULL);
|
|
zatt = att->format_att_info;
|
|
nullfree(zatt);
|
|
att->format_att_info = NULL; /* avoid memory errors */
|
|
}
|
|
return stat;
|
|
}
|
|
|
|
/**
|
|
* @internal Close resources for vars in a group.
|
|
*
|
|
* @param grp Pointer to group info struct.
|
|
*
|
|
* @return ::NC_NOERR No error.
|
|
* @author Dennis Heimbigner
|
|
*/
|
|
static int
|
|
zclose_vars(NC_GRP_INFO_T* grp)
|
|
{
|
|
int stat = NC_NOERR;
|
|
NC_VAR_INFO_T* var;
|
|
NCZ_VAR_INFO_T* zvar;
|
|
NC_ATT_INFO_T* att;
|
|
int a, i;
|
|
|
|
for(i = 0; i < ncindexsize(grp->vars); i++) {
|
|
var = (NC_VAR_INFO_T*)ncindexith(grp->vars, i);
|
|
assert(var && var->format_var_info);
|
|
zvar = var->format_var_info;;
|
|
for(a = 0; a < ncindexsize(var->att); a++) {
|
|
NCZ_ATT_INFO_T* zatt;
|
|
att = (NC_ATT_INFO_T*)ncindexith(var->att, a);
|
|
assert(att && att->format_att_info);
|
|
zatt = att->format_att_info;
|
|
nullfree(zatt);
|
|
att->format_att_info = NULL; /* avoid memory errors */
|
|
}
|
|
#ifdef ENABLE_NCZARR_FILTERS
|
|
/* Reclaim filters */
|
|
if(var->filters != NULL) {
|
|
(void)NCZ_filter_freelist(var);
|
|
}
|
|
var->filters = NULL;
|
|
#endif
|
|
/* Reclaim the type */
|
|
(void)zclose_type(var->type_info);
|
|
NCZ_free_chunk_cache(zvar->cache);
|
|
/* reclaim xarray */
|
|
nclistfreeall(zvar->xarray);
|
|
nullfree(zvar);
|
|
var->format_var_info = NULL; /* avoid memory errors */
|
|
}
|
|
return stat;
|
|
}
|
|
|
|
/**
|
|
* @internal Close resources for dims in a group.
|
|
*
|
|
* @param grp Pointer to group info struct.
|
|
*
|
|
* @return ::NC_NOERR No error.
|
|
* @author Dennis Heimbigner
|
|
*/
|
|
static int
|
|
zclose_dims(NC_GRP_INFO_T* grp)
|
|
{
|
|
int stat = NC_NOERR;
|
|
NC_DIM_INFO_T* dim;
|
|
int i;
|
|
|
|
for(i = 0; i < ncindexsize(grp->dim); i++) {
|
|
NCZ_DIM_INFO_T* zdim;
|
|
dim = (NC_DIM_INFO_T*)ncindexith(grp->dim, i);
|
|
assert(dim && dim->format_dim_info);
|
|
zdim = dim->format_dim_info;
|
|
nullfree(zdim);
|
|
dim->format_dim_info = NULL; /* avoid memory errors */
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
/**
|
|
* @internal Close resources for a single type. Set values to
|
|
* 0 after closing types. Because of type reference counters, these
|
|
* closes can be called multiple times.
|
|
*
|
|
* @param type Pointer to type struct.
|
|
*
|
|
* @return ::NC_NOERR No error.
|
|
* @author Dennis Heimbigner
|
|
*/
|
|
static int
|
|
zclose_type(NC_TYPE_INFO_T* type)
|
|
{
|
|
int stat = NC_NOERR;
|
|
NCZ_TYPE_INFO_T* ztype;
|
|
|
|
assert(type && type->format_type_info != NULL);
|
|
/* Get Zarr-specific type info. */
|
|
ztype = type->format_type_info;
|
|
nullfree(ztype);
|
|
type->format_type_info = NULL; /* avoid memory errors */
|
|
return stat;
|
|
}
|
|
|
|
/**
|
|
* @internal Close 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.
|
|
* Warning: note that atomic types are not covered here; this
|
|
* is only for user-defined types.
|
|
*
|
|
* @param grp Pointer to group info struct.
|
|
*
|
|
* @return ::NC_NOERR No error.
|
|
* @author Dennis Heimbigner
|
|
*/
|
|
static int
|
|
zclose_types(NC_GRP_INFO_T* grp)
|
|
{
|
|
int stat = NC_NOERR;
|
|
int i;
|
|
NC_TYPE_INFO_T* type;
|
|
|
|
for(i = 0; i < ncindexsize(grp->type); i++)
|
|
{
|
|
type = (NC_TYPE_INFO_T*)ncindexith(grp->type, i);
|
|
if((stat = zclose_type(type))) goto done;
|
|
}
|
|
done:
|
|
return stat;
|
|
}
|
|
|
|
/**
|
|
* @internal Recursively flush/create all data for all vars.
|
|
*
|
|
* @param grp Pointer to group info struct whose vars need to be written
|
|
*
|
|
* @return ::NC_NOERR No error.
|
|
* @author Dennis Heimbigner
|
|
*/
|
|
static int
|
|
zwrite_vars(NC_GRP_INFO_T *grp)
|
|
{
|
|
int stat = NC_NOERR;
|
|
int i;
|
|
|
|
assert(grp && grp->format_grp_info != NULL);
|
|
LOG((3, "%s: grp->name %s", __func__, grp->hdr.name));
|
|
|
|
/* Write all vars for this group breadth first */
|
|
for(i = 0; i < ncindexsize(grp->vars); i++) {
|
|
NC_VAR_INFO_T* var = (NC_VAR_INFO_T*)ncindexith(grp->vars, i);
|
|
if((stat = ncz_write_var(var))) goto done;
|
|
}
|
|
|
|
/* Recursively call this function for each child group, if any, stopping
|
|
* if there is an error. */
|
|
for(i=0; i<ncindexsize(grp->children); i++) {
|
|
if ((stat = zwrite_vars((NC_GRP_INFO_T*)ncindexith(grp->children,i))))
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
return stat;
|
|
}
|
|
|
|
|