mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
Merge pull request #1474 from Unidata/gh1472.wif
Unit tests plus cmake infrastructure
This commit is contained in:
commit
525eaeb8e6
@ -935,6 +935,13 @@ IF(ENABLE_TESTS)
|
||||
|
||||
OPTION(ENABLE_FAILING_TESTS "Run tests which are known to fail, check to see if any have been fixed." OFF)
|
||||
|
||||
###
|
||||
# Option to turn on unit testing. See https://github.com/Unidata/netcdf-c/pull/1472 for more information.
|
||||
# Currently (August 21, 2019): Will not work with Visual Studio
|
||||
###
|
||||
IF(NOT MSVC)
|
||||
OPTION(ENABLE_UNIT_TESTS "Run Unit Tests." ON)
|
||||
ENDIF(NOT MSVC)
|
||||
###
|
||||
# End known-failures.
|
||||
###
|
||||
@ -1621,6 +1628,7 @@ MACRO(print_conf_summary)
|
||||
MESSAGE(STATUS "Parallel Tests: ${ENABLE_PARALLEL_TESTS}")
|
||||
MESSAGE(STATUS "Large File Tests: ${ENABLE_LARGE_FILE_TESTS}")
|
||||
MESSAGE(STATUS "Extreme Numbers: ${ENABLE_EXTREME_NUMBERS}")
|
||||
MESSAGE(STATUS "Unit Tests: ${ENABLE_UNIT_TESTS}")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE("")
|
||||
@ -1794,6 +1802,9 @@ IF(ENABLE_TESTS)
|
||||
IF(ENABLE_EXAMPLES)
|
||||
ADD_SUBDIRECTORY(examples)
|
||||
ENDIF()
|
||||
IF(ENABLE_UNIT_TESTS)
|
||||
ADD_SUBDIRECTORY(unit_test)
|
||||
ENDIF(ENABLE_UNIT_TESTS)
|
||||
ENDIF()
|
||||
|
||||
# Code to generate an export header
|
||||
|
@ -7,18 +7,24 @@ This file contains a high-level description of this package's evolution. Release
|
||||
|
||||
## 4.7.1 - TBD
|
||||
|
||||
* [Enhancement] Added unit_test directory, which contains unit tests
|
||||
for the libdispatch and libsrc4 code (and any other directories that
|
||||
want to put unit tests there). Use --disable-unit-tests to run without
|
||||
unit tests (ex. for code coverage analysis).
|
||||
See [GitHub #1458](https://github.com/Unidata/netcdf-c/issues/1458)
|
||||
|
||||
* [Bug Fix] Remove obsolete _CRAYMPP and LOCKNUMREC macros from
|
||||
code. Also brought documentation up to date in man page. These macros
|
||||
were used in ancient times, before modern parallel I/O systems were
|
||||
developed. Programmers interested in parallel I/O should see
|
||||
nc_open_par() and nc_create_par().
|
||||
See [GitHub #1436](https://github.com/Unidata/netcdf-c/issues/1459)
|
||||
See [GitHub #1459](https://github.com/Unidata/netcdf-c/issues/1459)
|
||||
|
||||
* [Enhancement] Remove obsolete and deprecated functions
|
||||
nc_set_base_pe() and nc_inq_base_pe() from the dispatch table. (Both
|
||||
functions are still supported in the library, this is an internal
|
||||
change only.)
|
||||
See [GitHub #1436](https://github.com/Unidata/netcdf-c/issues/1468)
|
||||
See [GitHub #1468](https://github.com/Unidata/netcdf-c/issues/1468)
|
||||
|
||||
* [Bug Fix] Reverted nccopy behavior so that if no -c parameters
|
||||
are given, then any default chunking is left to the netcdf-c library
|
||||
|
@ -33,48 +33,53 @@
|
||||
/* Always needed */
|
||||
#include "nc.h"
|
||||
|
||||
/** The file ID is stored in the first two bytes of ncid. */
|
||||
#define FILE_ID_MASK (0xffff0000)
|
||||
|
||||
/** The group ID is stored in the last two bytes of ncid. */
|
||||
#define GRP_ID_MASK (0x0000ffff)
|
||||
|
||||
/** File and group IDs are each 16 bits of the ncid. */
|
||||
#define ID_SHIFT (16)
|
||||
|
||||
typedef enum {GET, PUT} NC_PG_T;
|
||||
/* typedef enum {GET, PUT} NC_PG_T; */
|
||||
/** These are the different objects that can be in our hash-lists. */
|
||||
typedef enum {NCNAT, NCVAR, NCDIM, NCATT, NCTYP, NCFLD, NCGRP} NC_SORT;
|
||||
|
||||
/** The netCDF V2 error code. */
|
||||
#define NC_V2_ERR (-1)
|
||||
|
||||
/* The name of the root group. */
|
||||
/** The name of the root group. */
|
||||
#define NC_GROUP_NAME "/"
|
||||
|
||||
/** One mega-byte. */
|
||||
#define MEGABYTE 1048576
|
||||
|
||||
/*
|
||||
* limits of the external representation
|
||||
*/
|
||||
#define X_SCHAR_MIN (-128)
|
||||
#define X_SCHAR_MAX 127
|
||||
#define X_UCHAR_MAX 255U
|
||||
#define X_SHORT_MIN (-32768)
|
||||
#define X_SHRT_MIN X_SHORT_MIN /* alias compatible with limits.h */
|
||||
#define X_SHORT_MAX 32767
|
||||
#define X_SHRT_MAX X_SHORT_MAX /* alias compatible with limits.h */
|
||||
#define X_USHORT_MAX 65535U
|
||||
#define X_USHRT_MAX X_USHORT_MAX /* alias compatible with limits.h */
|
||||
#define X_INT_MIN (-2147483647-1)
|
||||
#define X_INT_MAX 2147483647
|
||||
#define X_LONG_MIN X_INT_MIN
|
||||
#define X_LONG_MAX X_INT_MAX
|
||||
#define X_UINT_MAX 4294967295U
|
||||
#define X_INT64_MIN (-9223372036854775807LL-1LL)
|
||||
#define X_INT64_MAX 9223372036854775807LL
|
||||
#define X_UINT64_MAX 18446744073709551615ULL
|
||||
#define X_SCHAR_MIN (-128) /**< Minimum signed char value. */
|
||||
#define X_SCHAR_MAX 127 /**< Maximum signed char value. */
|
||||
#define X_UCHAR_MAX 255U /**< Maximum unsigned char value. */
|
||||
#define X_SHORT_MIN (-32768) /**< Minumum short value. */
|
||||
#define X_SHRT_MIN X_SHORT_MIN /**< This alias is compatible with limits.h. */
|
||||
#define X_SHORT_MAX 32767 /**< Maximum short value. */
|
||||
#define X_SHRT_MAX X_SHORT_MAX /**< This alias is compatible with limits.h. */
|
||||
#define X_USHORT_MAX 65535U /**< Maximum unsigned short value. */
|
||||
#define X_USHRT_MAX X_USHORT_MAX /**< This alias is compatible with limits.h. */
|
||||
#define X_INT_MIN (-2147483647-1) /**< Minimum int value. */
|
||||
#define X_INT_MAX 2147483647 /**< Maximum int value. */
|
||||
#define X_LONG_MIN X_INT_MIN /**< Minimum long value. */
|
||||
#define X_LONG_MAX X_INT_MAX /**< Maximum long value. */
|
||||
#define X_UINT_MAX 4294967295U /**< Maximum unsigned int value. */
|
||||
#define X_INT64_MIN (-9223372036854775807LL-1LL) /**< Minimum int64 value. */
|
||||
#define X_INT64_MAX 9223372036854775807LL /**< Maximum int64 value. */
|
||||
#define X_UINT64_MAX 18446744073709551615ULL /**< Maximum unsigned int64 value. */
|
||||
#ifdef WIN32 /* Windows, of course, has to be a *little* different. */
|
||||
#define X_FLOAT_MAX 3.402823466e+38f
|
||||
#else
|
||||
#define X_FLOAT_MAX 3.40282347e+38f
|
||||
#define X_FLOAT_MAX 3.40282347e+38f /**< Maximum float value. */
|
||||
#endif /* WIN32 */
|
||||
#define X_FLOAT_MIN (-X_FLOAT_MAX)
|
||||
#define X_DOUBLE_MAX 1.7976931348623157e+308
|
||||
#define X_DOUBLE_MIN (-X_DOUBLE_MAX)
|
||||
#define X_FLOAT_MIN (-X_FLOAT_MAX) /**< Minimum float value. */
|
||||
#define X_DOUBLE_MAX 1.7976931348623157e+308 /**< Maximum double value. */
|
||||
#define X_DOUBLE_MIN (-X_DOUBLE_MAX) /**< Minimum double value. */
|
||||
|
||||
/** This is the number of netCDF atomic types. */
|
||||
#define NUM_ATOMIC_TYPES (NC_MAX_ATOMIC_TYPE + 1)
|
||||
@ -82,221 +87,263 @@ typedef enum {NCNAT, NCVAR, NCDIM, NCATT, NCTYP, NCFLD, NCGRP} NC_SORT;
|
||||
/** Number of parameters needed for ZLIB filter. */
|
||||
#define CD_NELEMS_ZLIB 1
|
||||
|
||||
/* Boolean type, to make the code easier to read */
|
||||
/** Get a pointer to the NC_FILE_INFO_T from dispatchdata field. */
|
||||
#define NC4_DATA(nc) ((NC_FILE_INFO_T *)(nc)->dispatchdata)
|
||||
|
||||
/** Set a pointer to the NC_FILE_INFO_T in the dispatchdata field. */
|
||||
#define NC4_DATA_SET(nc,data) ((nc)->dispatchdata = (void *)(data))
|
||||
|
||||
/* Reserved attribute flags: must be powers of 2. */
|
||||
/** Hidden dimscale-related, per-variable attributes; immutable and
|
||||
* unreadable thru API. */
|
||||
#define DIMSCALEFLAG 1
|
||||
|
||||
/** Readonly global attributes; readable, but immutable thru the
|
||||
* API. */
|
||||
#define READONLYFLAG 2
|
||||
|
||||
/** Subset of readonly flags; readable by name only thru the API. */
|
||||
#define NAMEONLYFLAG 4
|
||||
|
||||
/** Subset of readonly flags; Value is actually in file. */
|
||||
#define MATERIALIZEDFLAG 8
|
||||
|
||||
/* Generic reserved Attributes */
|
||||
#define NC_ATT_REFERENCE_LIST "REFERENCE_LIST" /**< HDF5 reference list attribute name. */
|
||||
#define NC_ATT_CLASS "CLASS" /**< HDF5 class atttribute name. */
|
||||
#define NC_ATT_DIMENSION_LIST "DIMENSION_LIST" /**< HDF5 dimension list attribute name. */
|
||||
#define NC_ATT_NAME "NAME" /**< HDF5 name atttribute name. */
|
||||
#define NC_ATT_COORDINATES COORDINATES /**< Coordinates atttribute name. */
|
||||
#define NC_ATT_FORMAT "_Format" /**< Format atttribute name. */
|
||||
|
||||
/** Boolean type, to make the code easier to read. */
|
||||
typedef enum {NC_FALSE = 0, NC_TRUE = 1} nc_bool_t;
|
||||
|
||||
/*Forward*/
|
||||
/* Forward declarations. */
|
||||
struct NC_GRP_INFO;
|
||||
struct NC_TYPE_INFO;
|
||||
|
||||
/*
|
||||
Indexed Access to Meta-data objects:
|
||||
|
||||
See the document docs/indexing.dox for detailed information.
|
||||
|
||||
Basically provide a common header and use NCindex instances
|
||||
instead of linked lists.
|
||||
|
||||
WARNING: ALL OBJECTS THAT CAN BE INSERTED INTO AN NCindex
|
||||
MUST HAVE AN INSTANCE of NC_OBJ AS THE FIRST FIELD.
|
||||
/**
|
||||
* This struct provides indexed Access to Meta-data objects. See the
|
||||
* document docs/indexing.dox for detailed information.
|
||||
*
|
||||
* Basically it provides a common header and use NCindex instances
|
||||
* instead of linked lists.
|
||||
*
|
||||
* WARNING: ALL OBJECTS THAT CAN BE INSERTED INTO AN NCindex MUST HAVE
|
||||
* AN INSTANCE of NC_OBJ AS THE FIRST FIELD.
|
||||
*/
|
||||
|
||||
typedef struct NC_OBJ {
|
||||
NC_SORT sort;
|
||||
char* name; /* assumed to be null terminated */
|
||||
size_t id;
|
||||
unsigned int hashkey; /* crc32(name) */
|
||||
typedef struct NC_OBJ
|
||||
{
|
||||
NC_SORT sort; /**< Type of object. */
|
||||
char* name; /**< Name, assumed to be null terminated. */
|
||||
size_t id; /**< This objects ID. */
|
||||
unsigned int hashkey; /**< The hash key, crc32(name). */
|
||||
} NC_OBJ;
|
||||
|
||||
/* This is a struct to handle the dim metadata. */
|
||||
/**
|
||||
* This struct holds information about reserved attributes. These
|
||||
* attributes cannot be created or read by the user (through the
|
||||
* netCDF API). */
|
||||
typedef struct NC_reservedatt
|
||||
{
|
||||
const char *name; /**< Name of the reserved attribute. */
|
||||
int flags; /**< Flags that control handling of reserved attribute. */
|
||||
} NC_reservedatt;
|
||||
|
||||
/** This is a struct to handle the dimension metadata. */
|
||||
typedef struct NC_DIM_INFO
|
||||
{
|
||||
NC_OBJ hdr;
|
||||
struct NC_GRP_INFO *container; /* containing group */
|
||||
size_t len;
|
||||
nc_bool_t unlimited; /* True if the dimension is unlimited */
|
||||
nc_bool_t extended; /* True if the dimension needs to be extended */
|
||||
nc_bool_t too_long; /* True if len is too big to fit in local size_t. */
|
||||
void *format_dim_info; /* Pointer to format-specific dim info. */
|
||||
struct NC_VAR_INFO *coord_var; /* The coord var, if it exists. */
|
||||
NC_OBJ hdr; /**< The hdr contains the name and ID. */
|
||||
struct NC_GRP_INFO *container; /**< Pointer to containing group. */
|
||||
size_t len; /**< Length of this dimension. */
|
||||
nc_bool_t unlimited; /**< True if the dimension is unlimited */
|
||||
nc_bool_t extended; /**< True if the dimension needs to be extended. */
|
||||
nc_bool_t too_long; /**< True if len is too big to fit in local size_t. */
|
||||
void *format_dim_info; /**< Pointer to format-specific dim info. */
|
||||
struct NC_VAR_INFO *coord_var; /**< The coord var, if it exists. */
|
||||
} NC_DIM_INFO_T;
|
||||
|
||||
/** This is a struct to handle the attribute metadata. */
|
||||
typedef struct NC_ATT_INFO
|
||||
{
|
||||
NC_OBJ hdr;
|
||||
struct NC_OBJ *container; /* containing group|var */
|
||||
int len;
|
||||
nc_bool_t dirty; /* True if attribute modified */
|
||||
nc_bool_t created; /* True if attribute already created */
|
||||
nc_type nc_typeid; /* netCDF type of attribute's data */
|
||||
void *format_att_info;
|
||||
void *data;
|
||||
nc_vlen_t *vldata; /* only used for vlen */
|
||||
char **stdata; /* only for string type. */
|
||||
NC_OBJ hdr; /**< The hdr contains the name and ID. */
|
||||
struct NC_OBJ *container; /**< Pointer to containing group|var. */
|
||||
int len; /**< Length of attribute data. */
|
||||
nc_bool_t dirty; /**< True if attribute modified. */
|
||||
nc_bool_t created; /**< True if attribute already created. */
|
||||
nc_type nc_typeid; /**< NetCDF type of attribute's data. */
|
||||
void *format_att_info; /**< Pointer to format-specific att info. */
|
||||
void *data; /**< The attribute data. */
|
||||
nc_vlen_t *vldata; /**< VLEN data (only used for vlen types). */
|
||||
char **stdata; /**< String data (only for string type). */
|
||||
} NC_ATT_INFO_T;
|
||||
|
||||
/* This is a struct to handle the var metadata. */
|
||||
/** This is a struct to handle the var metadata. */
|
||||
typedef struct NC_VAR_INFO
|
||||
{
|
||||
NC_OBJ hdr;
|
||||
char *hdf5_name; /* used if different from name */
|
||||
struct NC_GRP_INFO *container; /* containing group */
|
||||
size_t ndims;
|
||||
int *dimids;
|
||||
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 */
|
||||
nc_bool_t fill_val_changed; /* True if variable's fill value changes after it has been created */
|
||||
nc_bool_t attr_dirty; /* True if variable's attributes are dirty and should be rewritten */
|
||||
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 */
|
||||
NC_OBJ hdr; /**< The hdr contains the name and ID. */
|
||||
char *hdf5_name; /**< Used if name in HDF5 must be different from name. */
|
||||
struct NC_GRP_INFO *container; /**< Pointer to containing group. */
|
||||
size_t ndims; /**< Number of dims. */
|
||||
int *dimids; /**< Dim IDs. */
|
||||
NC_DIM_INFO_T **dim; /**< Pointer to 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 */
|
||||
nc_bool_t fill_val_changed; /**< True if variable's fill value changes after it has been created */
|
||||
nc_bool_t attr_dirty; /**< True if variable's attributes are dirty and should be rewritten */
|
||||
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_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<NC_ATT_INFO_T*> */
|
||||
nc_bool_t no_fill; /* True if no fill value is defined for var */
|
||||
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<NC_ATT_INFO_T*> */
|
||||
nc_bool_t no_fill; /**< True if no fill value is defined for var */
|
||||
void *fill_value;
|
||||
size_t *chunksizes;
|
||||
nc_bool_t contiguous; /* True if variable is stored contiguously in HDF5 file */
|
||||
int parallel_access; /* Type of parallel access for I/O on variable (collective or independent) */
|
||||
nc_bool_t dimscale; /* True if var is a dimscale */
|
||||
nc_bool_t *dimscale_attached; /* Array of flags that are true if dimscale is attached for that dim index */
|
||||
nc_bool_t deflate; /* True if var has deflate filter applied */
|
||||
nc_bool_t contiguous; /**< True if variable is stored contiguously in HDF5 file */
|
||||
int parallel_access; /**< Type of parallel access for I/O on variable (collective or independent) */
|
||||
nc_bool_t dimscale; /**< True if var is a dimscale */
|
||||
nc_bool_t *dimscale_attached; /**< Array of flags that are true if dimscale is attached for that dim index */
|
||||
nc_bool_t deflate; /**< True if var has deflate filter applied */
|
||||
int deflate_level;
|
||||
nc_bool_t shuffle; /* True if var has shuffle filter applied */
|
||||
nc_bool_t fletcher32; /* True if var has fletcher32 filter applied */
|
||||
nc_bool_t shuffle; /**< True if var has shuffle filter applied */
|
||||
nc_bool_t fletcher32; /**< True if var has fletcher32 filter applied */
|
||||
size_t chunk_cache_size, chunk_cache_nelems;
|
||||
float chunk_cache_preemption;
|
||||
void *format_var_info; /* Pointer to any binary format info. */
|
||||
/* Stuff for arbitrary filters */
|
||||
unsigned int filterid;
|
||||
size_t nparams;
|
||||
unsigned int *params;
|
||||
void *format_var_info; /**< Pointer to any binary format info. */
|
||||
unsigned int filterid; /**< ID for arbitrary filter. */
|
||||
size_t nparams; /**< nparams for arbitrary filter. */
|
||||
unsigned int *params; /**< Params for arbitrary filter. */
|
||||
} NC_VAR_INFO_T;
|
||||
|
||||
/** This is a struct to handle the field metadata from a user-defined
|
||||
* type. */
|
||||
typedef struct NC_FIELD_INFO
|
||||
{
|
||||
NC_OBJ hdr;
|
||||
nc_type nc_typeid;
|
||||
size_t offset;
|
||||
int ndims;
|
||||
int *dim_size;
|
||||
void *format_field_info; /* Pointer to any binary format info for field. */
|
||||
NC_OBJ hdr; /**< The hdr contains the name and ID. */
|
||||
nc_type nc_typeid; /**< The type of this field. */
|
||||
size_t offset; /**< Offset in bytes of field. */
|
||||
int ndims; /**< Number of dims. */
|
||||
int *dim_size; /**< Dim sizes. */
|
||||
void *format_field_info; /**< Pointer to any binary format info for field. */
|
||||
} NC_FIELD_INFO_T;
|
||||
|
||||
/** This is a struct to handle metadata for a user-defined enum
|
||||
* type. */
|
||||
typedef struct NC_ENUM_MEMBER_INFO
|
||||
{
|
||||
char *name;
|
||||
void *value;
|
||||
char *name; /**< Name of member. */
|
||||
void *value; /**< Value of member. */
|
||||
} NC_ENUM_MEMBER_INFO_T;
|
||||
|
||||
/** This is a struct to handle metadata for a user-defined type. */
|
||||
typedef struct NC_TYPE_INFO
|
||||
{
|
||||
NC_OBJ hdr; /* NetCDF type ID. */
|
||||
struct NC_GRP_INFO *container; /* Containing group */
|
||||
unsigned rc; /* Ref. count of objects using this type */
|
||||
int endianness; /* What endianness for the type? */
|
||||
size_t size; /* Size of the type in memory, in bytes */
|
||||
nc_bool_t committed; /* True when datatype is committed in the file */
|
||||
nc_type nc_type_class; /* NC_VLEN, NC_COMPOUND, NC_OPAQUE,
|
||||
* NC_ENUM, NC_INT, NC_FLOAT, or
|
||||
* NC_STRING. */
|
||||
void *format_type_info; /* HDF5-specific type info. */
|
||||
NC_OBJ hdr; /**< The hdr contains the name and ID. */
|
||||
struct NC_GRP_INFO *container; /**< Containing group */
|
||||
unsigned rc; /**< Ref. count of objects using this type */
|
||||
int endianness; /**< What endianness for the type? */
|
||||
size_t size; /**< Size of the type in memory, in bytes */
|
||||
nc_bool_t committed; /**< True when datatype is committed in the file */
|
||||
nc_type nc_type_class; /**< NC_VLEN, NC_COMPOUND, NC_OPAQUE, NC_ENUM, NC_INT, NC_FLOAT, or NC_STRING. */
|
||||
void *format_type_info; /**< HDF5-specific type info. */
|
||||
|
||||
/* Information for each type or class */
|
||||
/** Information for each type or class */
|
||||
union {
|
||||
struct {
|
||||
NClist* enum_member; /* <! NClist<NC_ENUM_MEMBER_INFO_T*> */
|
||||
nc_type base_nc_typeid;
|
||||
} e; /* Enum */
|
||||
NClist* enum_member; /**< <! NClist<NC_ENUM_MEMBER_INFO_T*> */
|
||||
nc_type base_nc_typeid; /**< Typeid of the base type. */
|
||||
} e; /**< Enum */
|
||||
struct Fields {
|
||||
NClist* field; /* <! NClist<NC_FIELD_INFO_T*> */
|
||||
} c; /* Compound */
|
||||
NClist* field; /**< <! NClist<NC_FIELD_INFO_T*> */
|
||||
} c; /**< Compound */
|
||||
struct {
|
||||
nc_type base_nc_typeid;
|
||||
} v; /* Variable-length */
|
||||
} u; /* Union of structs, for each type/class */
|
||||
nc_type base_nc_typeid; /**< Typeid of the base type. */
|
||||
} v; /**< Variable-length. */
|
||||
} u; /**< Union of structs, for each type/class. */
|
||||
} NC_TYPE_INFO_T;
|
||||
|
||||
/* This holds information for one group. Groups reproduce with
|
||||
/** This holds information for one group. Groups reproduce with
|
||||
* parthenogenesis. */
|
||||
typedef struct NC_GRP_INFO
|
||||
{
|
||||
NC_OBJ hdr;
|
||||
void *format_grp_info;
|
||||
struct NC_FILE_INFO *nc4_info;
|
||||
struct NC_GRP_INFO *parent;
|
||||
int atts_read; /* True if atts have been read for this group. */
|
||||
NCindex* children; /* NCindex<struct NC_GRP_INFO*> */
|
||||
NCindex* dim; /* NCindex<NC_DIM_INFO_T> * */
|
||||
NCindex* att; /* NCindex<NC_ATT_INFO_T> * */
|
||||
NCindex* type; /* NCindex<NC_TYPE_INFO_T> * */
|
||||
NC_OBJ hdr; /**< The hdr contains the name and ID. */
|
||||
void *format_grp_info; /**< Pointer to binary format info for group. */
|
||||
struct NC_FILE_INFO *nc4_info; /**< Pointer containing NC_FILE_INFO_T. */
|
||||
struct NC_GRP_INFO *parent; /**< Pointer tp parent group. */
|
||||
int atts_read; /**< True if atts have been read for this group. */
|
||||
NCindex* children; /**< NCindex<struct NC_GRP_INFO*> */
|
||||
NCindex* dim; /**< NCindex<NC_DIM_INFO_T> * */
|
||||
NCindex* att; /**< NCindex<NC_ATT_INFO_T> * */
|
||||
NCindex* type; /**< NCindex<NC_TYPE_INFO_T> * */
|
||||
/* Note that this is the list of vars with position == varid */
|
||||
NCindex* vars; /* NCindex<NC_VAR_INFO_T> * */
|
||||
NCindex* vars; /**< NCindex<NC_VAR_INFO_T> * */
|
||||
} NC_GRP_INFO_T;
|
||||
|
||||
/* These constants apply to the cmode parameter in the
|
||||
* HDF5_FILE_INFO_T defined below. */
|
||||
#define NC_CREAT 2 /* in create phase, cleared by ncendef */
|
||||
#define NC_INDEF 8 /* in define mode, cleared by ncendef */
|
||||
#define NC_NSYNC 0x10 /* synchronise numrecs on change */
|
||||
#define NC_HSYNC 0x20 /* synchronise whole header on change */
|
||||
#define NC_NDIRTY 0x40 /* numrecs has changed */
|
||||
#define NC_HDIRTY 0x80 /* header info has changed */
|
||||
#define NC_CREAT 2 /**< in create phase, cleared by ncendef */
|
||||
#define NC_INDEF 8 /**< in define mode, cleared by ncendef */
|
||||
#define NC_NSYNC 0x10 /**< synchronise numrecs on change */
|
||||
#define NC_HSYNC 0x20 /**< synchronise whole header on change */
|
||||
#define NC_NDIRTY 0x40 /**< numrecs has changed */
|
||||
#define NC_HDIRTY 0x80 /**< header info has changed */
|
||||
|
||||
/* This is the metadata we need to keep track of for each
|
||||
netcdf-4/HDF5 file. */
|
||||
/** This is the metadata we need to keep track of for each
|
||||
* netcdf-4/HDF5 file. */
|
||||
typedef struct NC_FILE_INFO
|
||||
{
|
||||
NC* controller;
|
||||
NC *controller; /**< Pointer to containing NC. */
|
||||
#ifdef USE_PARALLEL4
|
||||
MPI_Comm comm; /* Copy of MPI Communicator used to open the file */
|
||||
MPI_Info info; /* Copy of MPI Information Object used to open the file */
|
||||
MPI_Comm comm; /**< Copy of MPI Communicator used to open the file. */
|
||||
MPI_Info info; /**< Copy of MPI Information Object used to open the file. */
|
||||
#endif
|
||||
int flags;
|
||||
int cmode;
|
||||
nc_bool_t parallel; /* True if file is open for parallel access */
|
||||
nc_bool_t redef; /* True if redefining an existing file */
|
||||
int fill_mode; /* Fill mode for vars - Unused internally currently */
|
||||
nc_bool_t no_write; /* true if nc_open has mode NC_NOWRITE. */
|
||||
NC_GRP_INFO_T *root_grp;
|
||||
/* Track indices to assign to grps, types, and dims */
|
||||
short next_nc_grpid;
|
||||
int next_typeid;
|
||||
int next_dimid;
|
||||
/* Provide convenience vectors indexed by the object id.
|
||||
This allows for direct conversion of e.g. an nc_type to
|
||||
the corresponding NC_TYPE_INFO_T object.
|
||||
*/
|
||||
NClist* alldims;
|
||||
NClist* alltypes;
|
||||
NClist* allgroups; /* including root group */
|
||||
void *format_file_info;
|
||||
NC4_Provenance provenance;
|
||||
struct NC4_Memio {
|
||||
NC_memio memio; /* What we sent to image_init and what comes back*/
|
||||
int locked; /* do not copy and do not free */
|
||||
int persist; /* Should file be persisted out on close? */
|
||||
int inmemory; /* NC_INMEMORY flag was set */
|
||||
int diskless; /* NC_DISKLESS flag was set => inmemory */
|
||||
int created; /* 1 => create, 0 => open */
|
||||
unsigned int imageflags; /* for H5LTopen_file_image */
|
||||
size_t initialsize;
|
||||
void* udata; /* extra memory allocated in NC4_image_init */
|
||||
int flags; /**< Flags used to open the file. */
|
||||
int cmode; /**< Create mode used to create the file. */
|
||||
nc_bool_t parallel; /**< True if file is open for parallel access */
|
||||
nc_bool_t redef; /**< True if redefining an existing file */
|
||||
int fill_mode; /**< Fill mode for vars - Unused internally currently */
|
||||
nc_bool_t no_write; /**< true if nc_open has mode NC_NOWRITE. */
|
||||
NC_GRP_INFO_T *root_grp; /**< Pointer to root group. */
|
||||
short next_nc_grpid; /**< Next available group ID. */
|
||||
int next_typeid; /**< Next available type ID. */
|
||||
int next_dimid; /**< Next available dim ID. */
|
||||
/* Provide convenience vectors indexed by the object id. This
|
||||
allows for direct conversion of e.g. an nc_type to the
|
||||
corresponding NC_TYPE_INFO_T object. */
|
||||
NClist *alldims; /**< List of all dims. */
|
||||
NClist *alltypes; /**< List of all types. */
|
||||
NClist *allgroups; /**< List of all groups, including root group. */
|
||||
void *format_file_info; /**< Pointer to binary format info for file. */
|
||||
NC4_Provenance provenance; /**< File provenence info. */
|
||||
struct NC4_Memio
|
||||
{
|
||||
NC_memio memio; /**< What we sent to image_init and what comes back. */
|
||||
int locked; /**< Do not copy and do not free. */
|
||||
int persist; /**< Should file be persisted out on close? */
|
||||
int inmemory; /**< NC_INMEMORY flag was set. */
|
||||
int diskless; /**< NC_DISKLESS flag was set => inmemory. */
|
||||
int created; /**< 1 => create, 0 => open. */
|
||||
unsigned int imageflags; /**< for H5LTopen_file_image. */
|
||||
size_t initialsize; /**< Initial size. */
|
||||
void *udata; /**< Extra memory allocated in NC4_image_init. */
|
||||
} mem;
|
||||
} NC_FILE_INFO_T;
|
||||
|
||||
/* Variable Length Datatype struct in memory. Must be identical to
|
||||
/** Variable Length Datatype struct in memory. Must be identical to
|
||||
* HDF5 hvl_t. (This is only used for VL sequences, not VL strings,
|
||||
* which are stored in char *'s) */
|
||||
typedef struct {
|
||||
size_t len; /* Length of VL data (in base type units) */
|
||||
void *p; /* Pointer to VL data */
|
||||
typedef struct
|
||||
{
|
||||
size_t len; /**< Length of VL data (in base type units) */
|
||||
void *p; /**< Pointer to VL data */
|
||||
} nc_hvl_t;
|
||||
|
||||
extern const char* nc4_atomic_name[NC_MAX_ATOMIC_TYPE+1];
|
||||
/** The names of the atomic data types. */
|
||||
extern const char *nc4_atomic_name[NC_MAX_ATOMIC_TYPE + 1];
|
||||
|
||||
/* These functions convert between netcdf and HDF5 types. */
|
||||
int nc4_get_typelen_mem(NC_FILE_INFO_T *h5, nc_type xtype, size_t *len);
|
||||
@ -396,35 +443,7 @@ extern void nc4_hdf5_finalize(void);
|
||||
int log_metadata_nc(NC_FILE_INFO_T *h5);
|
||||
#endif
|
||||
|
||||
/* Define accessors for the dispatchdata */
|
||||
#define NC4_DATA(nc) ((NC_FILE_INFO_T*)(nc)->dispatchdata)
|
||||
#define NC4_DATA_SET(nc,data) ((nc)->dispatchdata = (void*)(data))
|
||||
|
||||
/* Reserved Attributes Info */
|
||||
typedef struct NC_reservedatt {
|
||||
const char* name;
|
||||
int flags;
|
||||
} NC_reservedatt;
|
||||
|
||||
/* Reserved attribute flags: must be powers of 2*/
|
||||
/* Hidden dimscale-related, per-variable attributes; immutable and unreadable thru API */
|
||||
#define DIMSCALEFLAG 1
|
||||
/* Readonly global attributes; readable, but immutable thru the API */
|
||||
#define READONLYFLAG 2
|
||||
/* Subset of readonly flags; readable by name only thru the API */
|
||||
#define NAMEONLYFLAG 4
|
||||
/* Subset of readonly flags; Value is actually in file */
|
||||
#define MATERIALIZEDFLAG 8
|
||||
|
||||
/* Binary searcher for reserved attributes */
|
||||
extern const NC_reservedatt* NC_findreserved(const char* name);
|
||||
|
||||
/* Generic reserved Attributes */
|
||||
#define NC_ATT_REFERENCE_LIST "REFERENCE_LIST"
|
||||
#define NC_ATT_CLASS "CLASS"
|
||||
#define NC_ATT_DIMENSION_LIST "DIMENSION_LIST"
|
||||
#define NC_ATT_NAME "NAME"
|
||||
#define NC_ATT_COORDINATES COORDINATES /*defined above*/
|
||||
#define NC_ATT_FORMAT "_Format"
|
||||
extern const NC_reservedatt *NC_findreserved(const char *name);
|
||||
|
||||
#endif /* _NC4INTERNAL_ */
|
||||
|
@ -68,10 +68,11 @@ free_NC(NC *ncp)
|
||||
/**
|
||||
* Create and initialize a new NC struct. The ncid is assigned later.
|
||||
*
|
||||
* @param dispatcher
|
||||
* @param dispatcher An pointer to the NC_Dispatch table that should
|
||||
* be used by this NC.
|
||||
* @param path The name of the file.
|
||||
* @param mode The open or create mode.
|
||||
* @param model
|
||||
* @param model An NCmodel instance, provided by NC_infermodel().
|
||||
* @param ncpp A pointer that gets a pointer to the newlly allocacted
|
||||
* and initialized NC struct.
|
||||
*
|
||||
|
@ -89,7 +89,7 @@ nc4_check_name(const char *name, char *norm_name)
|
||||
* nc4_nc4f_list_add(), except it takes an ncid instead of an NC *,
|
||||
* and also passes back the dispatchdata pointer.
|
||||
*
|
||||
* @param ncid The ncid of the file (aka ext_ncid).
|
||||
* @param ncid The (already-assigned) ncid of the file (aka ext_ncid).
|
||||
* @param path The file name of the new file.
|
||||
* @param mode The mode flag.
|
||||
* @param dispatchdata Void * that gets pointer to dispatch data,
|
||||
@ -125,10 +125,35 @@ nc4_file_list_add(int ncid, const char *path, int mode, void **dispatchdata)
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/* /\** */
|
||||
/* * @internal Change the ncid of an open file. This is needed for PIO */
|
||||
/* * integration. */
|
||||
/* * */
|
||||
/* * @param ncid The ncid of the file (aka ext_ncid). */
|
||||
/* * @param new_ncid The new ncid to use. */
|
||||
/* * */
|
||||
/* * @return ::NC_NOERR No error. */
|
||||
/* * @return ::NC_EBADID No NC struct with this ext_ncid. */
|
||||
/* * @return ::NC_ENOMEM Out of memory. */
|
||||
/* * @author Ed Hartnett */
|
||||
/* *\/ */
|
||||
/* int */
|
||||
/* nc4_file_change_ncid(int ncid, int new_ncid) */
|
||||
/* { */
|
||||
/* NC *nc; */
|
||||
/* int ret; */
|
||||
|
||||
/* /\* Find NC pointer for this file. *\/ */
|
||||
/* if ((ret = NC_check_id(ncid, &nc))) */
|
||||
/* return ret; */
|
||||
|
||||
/* return NC_NOERR; */
|
||||
/* } */
|
||||
|
||||
/**
|
||||
* @internal Get info about a file on the list of libsrc4 open files. This is
|
||||
* used by dispatch layers that wish to use the libsrc4 metadata
|
||||
* model, but don't know about struct NC.
|
||||
* @internal Get info about a file on the list of libsrc4 open
|
||||
* files. This is used by dispatch layers that wish to use the libsrc4
|
||||
* metadata model, but don't know about struct NC.
|
||||
*
|
||||
* @param ncid The ncid of the file (aka ext_ncid).
|
||||
* @param path A pointer that gets file name (< NC_MAX_NAME). Igored
|
||||
@ -212,7 +237,7 @@ nc4_nc4f_list_add(NC *nc, const char *path, int mode)
|
||||
|
||||
/* There's always at least one open group - the root
|
||||
* group. Allocate space for one group's worth of information. Set
|
||||
* its hdf id, name, and a pointer to it's file structure. */
|
||||
* its grp id, name, and allocate associated empty lists. */
|
||||
if ((retval = nc4_grp_list_add(h5, NULL, NC_GROUP_NAME, &h5->root_grp)))
|
||||
return retval;
|
||||
|
||||
|
@ -90,5 +90,3 @@ IF(TEST_PARALLEL4)
|
||||
build_bin_test(tst_simplerw_coll_r)
|
||||
add_sh_test(nc_test4 run_par_test)
|
||||
ENDIF()
|
||||
|
||||
ADD_EXTRA_DIST(findplugin.in run_par_test.sh.in)
|
||||
|
21
unit_test/CMakeLists.txt
Normal file
21
unit_test/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014,
|
||||
# 2015, 2016, 2017, 2018, 2019
|
||||
# University Corporation for Atmospheric Research/Unidata.
|
||||
|
||||
# See netcdf-c/COPYRIGHT file for more info.
|
||||
|
||||
# This is the cmake build file for unit_test/ directory.
|
||||
# @author Ward Fisher
|
||||
|
||||
# Some unit testing
|
||||
|
||||
SET(UNIT_TESTS tst_nclist)
|
||||
|
||||
IF(ENABLE_NETCDF_4)
|
||||
SET(UNIT_TESTS ${UNIT_TESTS} tst_nc4internal)
|
||||
ENDIF(ENABLE_NETCDF_4)
|
||||
|
||||
FOREACH(CTEST ${UNIT_TESTS})
|
||||
add_bin_test(unit_test ${CTEST})
|
||||
ENDFOREACH()
|
@ -14,8 +14,14 @@ include $(top_srcdir)/lib_flags.am
|
||||
# Find and link to the netcdf-c library.
|
||||
LDADD = ${top_builddir}/liblib/libnetcdf.la
|
||||
|
||||
check_PROGRAMS = tst_nclist
|
||||
TESTS = tst_nclist
|
||||
if USE_NETCDF4
|
||||
NC4_TESTS = tst_nc4internal
|
||||
endif # USE_NETCDF4
|
||||
|
||||
check_PROGRAMS = tst_nclist $(NC4_TESTS)
|
||||
TESTS = tst_nclist $(NC4_TESTS)
|
||||
|
||||
EXTRA_DIST = CMakeLists.txt
|
||||
|
||||
# If valgrind is present, add valgrind targets.
|
||||
@VALGRIND_CHECK_RULES@
|
||||
|
300
unit_test/tst_nc4internal.c
Normal file
300
unit_test/tst_nc4internal.c
Normal file
@ -0,0 +1,300 @@
|
||||
/* This is part of the netCDF package. Copyright 2005-2019 University
|
||||
Corporation for Atmospheric Research/Unidata. See COPYRIGHT file
|
||||
for conditions of use.
|
||||
|
||||
Test list functions in nc4internal.c.
|
||||
|
||||
Ed Hartnett, 8/21/19
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <nc_tests.h>
|
||||
#include "nc.h"
|
||||
#include "nc4internal.h"
|
||||
#include "ncdispatch.h"
|
||||
#include "err_macros.h"
|
||||
|
||||
/* An integer value to use in testing. */
|
||||
#define TEST_VAL_42 42
|
||||
|
||||
#define FILE_NAME "tst_nc4internal.nc"
|
||||
#define VAR_NAME "Hilary_Duff"
|
||||
#define DIM_NAME "Foggy"
|
||||
#define DIM_LEN 5
|
||||
#define TYPE_NAME "Madonna"
|
||||
#define TYPE_SIZE TEST_VAL_42
|
||||
#define FIELD_NAME "Britany_Spears"
|
||||
#define FIELD_OFFSET 9
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
printf("\n*** Testing netcdf nc4internal functions.\n");
|
||||
printf("Testing adding new file to nc4internal file lists with "
|
||||
"nc4_file_list_add()...");
|
||||
{
|
||||
NC *ncp;
|
||||
NCmodel model;
|
||||
char *path;
|
||||
/* The NC3_dispatch_table is defined in nc3dispatch.c and
|
||||
* externed in ncdispatch.h. But it will be 0 because we have
|
||||
* not yet called NC3_initialize(). */
|
||||
const void *dispatcher = NC3_dispatch_table;
|
||||
void *dispatchdata_in;
|
||||
int mode = 0, mode_in;
|
||||
|
||||
/* This won't work because there is no NC in the NC list which
|
||||
* has an ncid of TEST_VAL_42. */
|
||||
if (nc4_file_list_add(TEST_VAL_42, FILE_NAME, 0, NULL) != NC_EBADID) ERR;
|
||||
|
||||
/* Create the NC* instance and insert its dispatcher and
|
||||
* model. */
|
||||
if (new_NC(dispatcher, FILE_NAME, mode, &model, &ncp)) ERR;
|
||||
|
||||
/* Add to array of open files nc_filelist and define
|
||||
* ext_ncid by left-shifting the index 16 bits. */
|
||||
add_to_NCList(ncp);
|
||||
|
||||
/* Create the NC_FILE_INFO_T instance associated empty lists
|
||||
* to hold dims, types, groups, and the root group. */
|
||||
if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, mode, NULL)) ERR;
|
||||
|
||||
/* Find the file in the list. */
|
||||
if (!(path = malloc(NC_MAX_NAME + 1))) ERR;
|
||||
if (nc4_file_list_get(ncp->ext_ncid, &path, &mode_in, &dispatchdata_in)) ERR;
|
||||
if (strcmp(path, FILE_NAME)) ERR;
|
||||
free(path);
|
||||
if (mode_in != mode) ERR;
|
||||
|
||||
/* This won't work. */
|
||||
if (nc4_file_list_del(TEST_VAL_42) != NC_EBADID) ERR;
|
||||
|
||||
/* Delete the NC_FILE_INFO_T and related storage. */
|
||||
if (nc4_file_list_del(ncp->ext_ncid)) ERR;
|
||||
|
||||
/* Delete the ncp from the list. (In fact, just null out its
|
||||
* entry in the array of file slots.) */
|
||||
del_from_NCList(ncp); /* Will free empty list. */
|
||||
|
||||
/* Now free the NC struct. */
|
||||
free_NC(ncp);
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
printf("Testing adding new file to nc4internal file lists with "
|
||||
"nc4_nc4f_list_add()...");
|
||||
{
|
||||
NC *ncp, *ncp_in, *ncp_in2;
|
||||
NCmodel model;
|
||||
char *path;
|
||||
void *dispatchdata_in;
|
||||
int mode = 0, mode_in;
|
||||
NC_GRP_INFO_T *grp, *grp2;
|
||||
NC_FILE_INFO_T *h5, *h52;
|
||||
|
||||
/* Create the NC* instance and insert its dispatcher and
|
||||
* model. */
|
||||
if (new_NC(NC3_dispatch_table, FILE_NAME, mode, &model, &ncp)) ERR;
|
||||
|
||||
/* Add to array of open files nc_filelist and define
|
||||
* ext_ncid by left-shifting the index 16 bits. */
|
||||
add_to_NCList(ncp);
|
||||
|
||||
/* Create the NC_FILE_INFO_T instance associated empty lists
|
||||
* to hold dims, types, groups, and the root group. */
|
||||
if (nc4_nc4f_list_add(ncp, FILE_NAME, mode)) ERR;
|
||||
|
||||
/* Find the file in the list. */
|
||||
if (!(path = malloc(NC_MAX_NAME + 1))) ERR;
|
||||
if (nc4_file_list_get(ncp->ext_ncid, &path, &mode_in, &dispatchdata_in)) ERR;
|
||||
if (strcmp(path, FILE_NAME)) ERR;
|
||||
free(path);
|
||||
if (mode_in != mode) ERR;
|
||||
|
||||
/* Find it again. */
|
||||
if (nc4_find_nc_grp_h5(ncp->ext_ncid, &ncp_in, &grp, &h5)) ERR;
|
||||
if (ncp_in->ext_ncid != ncp->ext_ncid) ERR;
|
||||
if (grp->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
|
||||
if (h5->controller->ext_ncid != ncp->ext_ncid) ERR;
|
||||
|
||||
/* Any of the pointer parameters may be NULL. */
|
||||
if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, NULL, NULL)) ERR;
|
||||
if (nc4_find_nc_grp_h5(ncp->ext_ncid, &ncp_in2, NULL, NULL)) ERR;
|
||||
if (ncp_in2->ext_ncid != ncp->ext_ncid) ERR;
|
||||
if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp2, NULL)) ERR;
|
||||
if (grp2->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
|
||||
if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, NULL, &h52)) ERR;
|
||||
if (h52->controller->ext_ncid != ncp->ext_ncid) ERR;
|
||||
|
||||
/* There are additional functions which use the NULL
|
||||
* parameters of nc4_find_nc_grp_h5(). */
|
||||
grp2 = NULL;
|
||||
h52 = NULL;
|
||||
if (nc4_find_grp_h5(ncp->ext_ncid, NULL, NULL)) ERR;
|
||||
if (nc4_find_grp_h5(ncp->ext_ncid, &grp2, NULL)) ERR;
|
||||
if (grp2->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
|
||||
if (nc4_find_grp_h5(ncp->ext_ncid, NULL, &h52)) ERR;
|
||||
if (h52->controller->ext_ncid != ncp->ext_ncid) ERR;
|
||||
grp2 = NULL;
|
||||
if (nc4_find_nc4_grp(ncp->ext_ncid, NULL)) ERR;
|
||||
if (nc4_find_nc4_grp(ncp->ext_ncid, &grp2)) ERR;
|
||||
if (grp2->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
|
||||
|
||||
/* Delete the NC_FILE_INFO_T and related storage. */
|
||||
if (nc4_file_list_del(ncp->ext_ncid)) ERR;
|
||||
|
||||
/* Delete the ncp from the list. (In fact, just null out its
|
||||
* entry in the array of file slots.) */
|
||||
del_from_NCList(ncp); /* Will free empty list. */
|
||||
|
||||
/* Now free the NC struct. */
|
||||
free_NC(ncp);
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
printf("Testing adding new var to nc4internal file...");
|
||||
{
|
||||
NC *ncp, *ncp_in;
|
||||
NCmodel model;
|
||||
NC_GRP_INFO_T *grp;
|
||||
NC_VAR_INFO_T *var, *var_in;
|
||||
NC_FILE_INFO_T *h5;
|
||||
|
||||
/* Create the NC* instance and insert its dispatcher and
|
||||
* model. */
|
||||
if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR;
|
||||
|
||||
/* Add to array of open files nc_filelist and define
|
||||
* ext_ncid by left-shifting the index 16 bits. */
|
||||
add_to_NCList(ncp);
|
||||
|
||||
/* Create the NC_FILE_INFO_T instance associated empty lists
|
||||
* to hold dims, types, groups, and the root group. */
|
||||
if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR;
|
||||
|
||||
/* Find the file in the list. */
|
||||
if (nc4_find_nc_grp_h5(ncp->ext_ncid, &ncp_in, &grp, &h5)) ERR;
|
||||
if (ncp_in->ext_ncid != ncp->ext_ncid) ERR;
|
||||
|
||||
/* Add a var to the varlist. */
|
||||
if (nc4_var_list_add(grp, VAR_NAME, 0, &var)) ERR;
|
||||
|
||||
/* Find the var. */
|
||||
if (nc4_find_var(grp, VAR_NAME, &var_in)) ERR;
|
||||
if (strcmp(var_in->hdr.name, var->hdr.name)) ERR;
|
||||
|
||||
/* Find it again. */
|
||||
h5 = NULL;
|
||||
grp = NULL;
|
||||
var_in = NULL;
|
||||
if (nc4_find_grp_h5_var(ncp->ext_ncid, 0, &h5, &grp, &var_in)) ERR;
|
||||
if (h5->controller->ext_ncid != ncp->ext_ncid) ERR;
|
||||
if (grp->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
|
||||
if (strcmp(var_in->hdr.name, var->hdr.name)) ERR;
|
||||
|
||||
/* Delete the NC_FILE_INFO_T and related storage, including
|
||||
* all vars, dims, types, etc. */
|
||||
if (nc4_file_list_del(ncp->ext_ncid)) ERR;
|
||||
|
||||
/* Delete the ncp from the list. (In fact, just null out its
|
||||
* entry in the array of file slots.) */
|
||||
del_from_NCList(ncp); /* Will free empty list. */
|
||||
|
||||
/* Now free the NC struct. */
|
||||
free_NC(ncp);
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
printf("Testing adding new dim to nc4internal file...");
|
||||
{
|
||||
NC *ncp;
|
||||
NCmodel model;
|
||||
NC_GRP_INFO_T *grp, *dim_grp;
|
||||
NC_DIM_INFO_T *dim, *dim_in;
|
||||
|
||||
/* Create the NC, add it to nc_filelist array, add and init
|
||||
* NC_FILE_INFO_T. */
|
||||
if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR;
|
||||
add_to_NCList(ncp);
|
||||
if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR;
|
||||
if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp, NULL)) ERR;
|
||||
|
||||
/* Add a dim. */
|
||||
if (nc4_dim_list_add(grp, DIM_NAME, DIM_LEN, 0, &dim)) ERR;
|
||||
|
||||
/* Find the dim. */
|
||||
if (nc4_find_dim(grp, 0, &dim_in, &dim_grp)) ERR;
|
||||
if (strcmp(dim_in->hdr.name, dim->hdr.name)) ERR;
|
||||
if (strcmp(dim_grp->hdr.name, grp->hdr.name)) ERR;
|
||||
dim_in = NULL;
|
||||
if (nc4_find_dim(grp, 0, &dim_in, NULL)) ERR;
|
||||
if (strcmp(dim_in->hdr.name, dim->hdr.name)) ERR;
|
||||
|
||||
/* Release resources. */
|
||||
if (nc4_file_list_del(ncp->ext_ncid)) ERR;
|
||||
del_from_NCList(ncp);
|
||||
free_NC(ncp);
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
printf("Testing adding new type to nc4internal file...");
|
||||
{
|
||||
NC *ncp;
|
||||
NCmodel model;
|
||||
NC_GRP_INFO_T *grp;
|
||||
NC_TYPE_INFO_T *type, *type_in;
|
||||
NC_FILE_INFO_T *h5;
|
||||
|
||||
/* Create the NC, add it to nc_filelist array, add and init
|
||||
* NC_FILE_INFO_T. */
|
||||
if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR;
|
||||
add_to_NCList(ncp);
|
||||
if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR;
|
||||
if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp, &h5)) ERR;
|
||||
|
||||
/* Add a type. */
|
||||
if (nc4_type_list_add(grp, TYPE_SIZE, TYPE_NAME, &type)) ERR;
|
||||
|
||||
/* Add a field to the type. */
|
||||
/* if (nc4_field_list_add(type, FIELD_NAME, FIELD_OFFSET, NC_INT, 0, */
|
||||
/* NULL)) ERR; */
|
||||
|
||||
/* Find it. */
|
||||
if (nc4_find_type(h5, type->hdr.id, &type_in)) ERR;
|
||||
if (strcmp(type_in->hdr.name, type->hdr.name)) ERR;
|
||||
|
||||
/* Release resources. */
|
||||
if (nc4_file_list_del(ncp->ext_ncid)) ERR;
|
||||
del_from_NCList(ncp);
|
||||
free_NC(ncp);
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
/* printf("Testing changing ncid..."); */
|
||||
/* { */
|
||||
/* NC *ncp, *ncp2; */
|
||||
/* int mode = 0; */
|
||||
/* NCmodel model; */
|
||||
/* int ret; */
|
||||
|
||||
/* /\* Create the NC* instance and insert its dispatcher and model. *\/ */
|
||||
/* if ((ret = new_NC(NULL, FILE_NAME, mode, &model, &ncp))) ERR; */
|
||||
|
||||
/* /\* Add to list of known open files and define ext_ncid. *\/ */
|
||||
/* add_to_NCList(ncp); */
|
||||
|
||||
/* /\* Find it in the list. *\/ */
|
||||
/* if (!(ncp2 = find_in_NCList(ncp->ext_ncid))) ERR; */
|
||||
/* if (!(ncp2 = find_in_NCList_by_name(FILE_NAME))) ERR; */
|
||||
/* if ((ret = iterate_NCList(1, &ncp2))) ERR; */
|
||||
/* if (count_NCList() != 1) ERR; */
|
||||
|
||||
/* /\* Change the ncid. *\/ */
|
||||
/* if (nc4_file_change_ncid(ncp->ext_ncid, TEST_VAL_42)) ERR; */
|
||||
|
||||
/* /\* Delete it. *\/ */
|
||||
/* del_from_NCList(ncp); /\* Will free empty list. *\/ */
|
||||
/* free_NC(ncp); */
|
||||
|
||||
/* /\* Ensure it is no longer in list. *\/ */
|
||||
/* /\* if (find_in_NCList(ncp->ext_ncid)) ERR; *\/ */
|
||||
|
||||
/* } */
|
||||
/* SUMMARIZE_ERR; */
|
||||
FINAL_RESULTS;
|
||||
}
|
@ -16,6 +16,8 @@
|
||||
/* An integer value to use in testing. */
|
||||
#define TEST_VAL_42 42
|
||||
|
||||
#define FILE_NAME "tst_nclist.nc"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -36,16 +38,20 @@ main(int argc, char **argv)
|
||||
NC *ncp, *ncp2;
|
||||
int mode = 0;
|
||||
NCmodel model;
|
||||
char path[] = {"file.nc"};
|
||||
int ret;
|
||||
|
||||
/* Create the NC* instance and insert its dispatcher and model. */
|
||||
if ((ret = new_NC(NULL, path, mode, &model, &ncp))) ERR;
|
||||
if ((ret = new_NC(NULL, FILE_NAME, mode, &model, &ncp))) ERR;
|
||||
|
||||
/* Nothing to find yet. */
|
||||
if (find_in_NCList(TEST_VAL_42)) ERR;
|
||||
|
||||
/* Add to list of known open files and define ext_ncid. */
|
||||
/* Add to list of known open files and define ext_ncid. To get
|
||||
* the ncid, we find the first open index > 1 in the
|
||||
* nc_filelist array, which has a size of 65536. Then we
|
||||
* left-shift that index 16 bits to put it in the first
|
||||
* 2-bytes of the 4-byte ncid. (The other two bytes are
|
||||
* reserved for grpid of netCDF-4 groups.) */
|
||||
add_to_NCList(ncp);
|
||||
|
||||
/* These won't work! */
|
||||
@ -55,7 +61,7 @@ main(int argc, char **argv)
|
||||
|
||||
/* Find it in the list. */
|
||||
if (!(ncp2 = find_in_NCList(ncp->ext_ncid))) ERR;
|
||||
if (!(ncp2 = find_in_NCList_by_name(path))) ERR;
|
||||
if (!(ncp2 = find_in_NCList_by_name(FILE_NAME))) ERR;
|
||||
if ((ret = iterate_NCList(1, &ncp2))) ERR;
|
||||
if (count_NCList() != 1) ERR;
|
||||
|
||||
@ -66,6 +72,8 @@ main(int argc, char **argv)
|
||||
ncid = ncp->ext_ncid;
|
||||
del_from_NCList(ncp); /* Will free empty list. */
|
||||
free_NC(ncp);
|
||||
|
||||
/* Ensure it is no longer in list. */
|
||||
if (find_in_NCList(ncid)) ERR;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
@ -76,7 +84,6 @@ main(int argc, char **argv)
|
||||
NC *ncp;
|
||||
int mode = 0;
|
||||
NCmodel model;
|
||||
char path[] = {"file.nc"};
|
||||
int max_num_nc = 65535;
|
||||
int i;
|
||||
int ret;
|
||||
@ -84,7 +91,7 @@ main(int argc, char **argv)
|
||||
/* Fill the NC list. */
|
||||
for (i = 0; i < max_num_nc; i++)
|
||||
{
|
||||
if ((ret = new_NC(NULL, path, mode, &model, &ncp))) ERR;
|
||||
if ((ret = new_NC(NULL, FILE_NAME, mode, &model, &ncp))) ERR;
|
||||
if (add_to_NCList(ncp)) ERR;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user