netcdf-c/libnczarr/zclose.c
Dennis Heimbigner 9380790ea8 Support MSYS2/Mingw platform
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.
2021-12-23 22:18:56 -07:00

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;
}