mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-03-07 17:08:02 +08:00
Add provenance info for netcdf-4 files.
This consists of a persistent attribute named _NCProperties plus two computed attributes _IsNetcdf4 and _SuperblockVersion. See the 'Provenance Attributes' section of docs/attribute_conventions.md for details.
This commit is contained in:
parent
e1a75d5257
commit
2e55a233eb
CMakeLists.txtcfcf.cmakeconfig.h.cmake.inconfigure.ac
docs
include
libdispatch
liblib
libsrc4
nc_test
nc_test4
ncdump
CMakeLists.txtMake0Makefile.amcdl.hncdump.cncdump.href_tst_ncf213.cdlref_tst_special_atts.cdltst_fileinfo.ctst_fileinfo.shtst_lengths.shtst_netcdf4.shtst_netcdf4_4.shutils.cutils.h
ncgen
Makefile.amdata.hgenc.cgenlib.hincludes.hmain.cncgen.hncgen.lncgen.yncgenl.cncgeny.cncgeny.hrun_tests.shutil.cutil.h
nctest
@ -191,7 +191,6 @@ OPTION(NC_FIND_SHARED_LIBS "Find dynamically-built versions of dependent librari
|
||||
##
|
||||
OPTION(ENABLE_SHARED_LIBRARY_VERSION "Encode the library SO version in the file name of the generated library file." ON)
|
||||
|
||||
|
||||
# Set some default linux gcc & apple compiler options for
|
||||
# debug builds.
|
||||
IF(CMAKE_COMPILER_IS_GNUCC OR APPLE)
|
||||
@ -752,6 +751,12 @@ IF(NOT WIN32)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
OPTION(ENABLE_PROPERTIES_ATTRIBUTE "Enable properties attribute." ON)
|
||||
IF(ENABLE_PROPERTIES_ATTRIBUTE)
|
||||
SET(ENABLE_PROPATTR ON CACHE BOOL "")
|
||||
ENDIF()
|
||||
|
||||
|
||||
# Option to Enable DAP long tests, remote tests.
|
||||
OPTION(ENABLE_DAP_LONG_TESTS "Enable DAP long tests." OFF)
|
||||
OPTION(ENABLE_DAP_REMOTE_TESTS "Enable DAP remote tests." ON)
|
||||
@ -1064,6 +1069,11 @@ MARK_AS_ADVANCED(ENABLE_INTERNAL_DOCS VALGRIND_TESTS ENABLE_COVERAGE_TESTS )
|
||||
MARK_AS_ADVANCED(ENABLE_DAP_REMOTE_TESTS ENABLE_DAP_LONG_TESTS USE_REMOTE_CDASH)
|
||||
MARK_AS_ADVANCED(ENABLE_DOXYGEN_BUILD_RELEASE_DOCS DOXYGEN_ENABLE_TASKS ENABLE_DOXYGEN_SERVER_SIDE_SEARCH)
|
||||
MARK_AS_ADVANCED(ENABLE_SHARED_LIBRARY_VERSION)
|
||||
|
||||
# This option is temporary and should always be on
|
||||
OPTION(ENABLE_FILEINFO "Enable FILEINFO." ON)
|
||||
MARK_AS_ADVANCED(ENABLE_FILEINFO)
|
||||
|
||||
################################
|
||||
# Option checks
|
||||
################################
|
||||
|
10
cf
10
cf
@ -24,7 +24,7 @@ fi
|
||||
|
||||
CFLAGS=""
|
||||
#CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter -Wconversion ${CFLAGS}"
|
||||
CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter ${CFLAGS}"
|
||||
CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter -Wno-char-subscripts -Wno-pointer-sign -Wno-format ${CFLAGS}"
|
||||
#CFLAGS="-Wall ${CFLAGS}"
|
||||
#CFLAGS="-Wconversion"
|
||||
|
||||
@ -116,21 +116,23 @@ FLAGS="$FLAGS --disable-examples"
|
||||
#FLAGS="$FLAGS --disable-dap-remote-tests"
|
||||
FLAGS="$FLAGS --enable-dap-auth-tests"
|
||||
#FLAGS="$FLAGS --enable-doxygen"
|
||||
FLAGS="$FLAGS --enable-logging"
|
||||
#FLAGS="$FLAGS --enable-logging"
|
||||
#FLAGS="$FLAGS --disable-diskless"
|
||||
#FLAGS="$FLAGS --enable-mmap"
|
||||
#FLAGS="$FLAGS --with-udunits"
|
||||
#FLAGS="$FLAGS --with-libcf"
|
||||
#valgrind => not shared
|
||||
#FLAGS="$FLAGS --enable-valgrind-tests"
|
||||
FLAGS="$FLAGS --enable-jna"
|
||||
#FLAGS="$FLAGS --enable-jna"
|
||||
#FLAGS="$FLAGS --disable-properties-attribute"
|
||||
#FLAGS="$FLAGS --disable-silent-rules"
|
||||
|
||||
if test "x$PAR4" != x1 ; then
|
||||
FLAGS="$FLAGS --disable-parallel4"
|
||||
fi
|
||||
|
||||
if test "x${DB}" = x1 ; then
|
||||
FLAGS="$FLAGS --disable-shared"
|
||||
FLAGS="$FLAGS --disable-shared --enable-static"
|
||||
else
|
||||
FLAGS="$FLAGS --enable-shared"
|
||||
fi
|
||||
|
2
cf.cmake
2
cf.cmake
@ -42,7 +42,7 @@ ZLIB="-DZLIB_LIBRARY=${ZP}/$ZLIB -DZLIB_INCLUDE_DIR=${ZP}/include -DZLIB_INCLUDE
|
||||
HDF5="-DHDF5_LIB=${HP}/$H5LIB -DHDF5_HL_LIB=${HP}/$H5LIB_HL -DHDF5_INCLUDE_DIR=${HP}/include"
|
||||
CURL="-DCURL_LIBRARY=${CP}/$CURLLIB -DCURL_INCLUDE_DIR=${CP}/include -DCURL_INCLUDE_DIRS=${CP}/include"
|
||||
|
||||
FLAGS="$FLAGS -DCMAKE_C_FLAGS='-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter'"x2
|
||||
#FLAGS="$FLAGS -DCMAKE_C_FLAGS='-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter'"x2
|
||||
|
||||
#FLAGS="$FLAGS -DENABLE_DAP=false"
|
||||
#FLAGS="$FLAGS -DENABLE_NETCDF_4=false"
|
||||
|
@ -87,6 +87,7 @@ are set when opening a binary file on Windows. */
|
||||
#cmakedefine ENABLE_DAP 1
|
||||
#cmakedefine ENABLE_DAP_GROUPS 1
|
||||
#cmakedefine ENABLE_DAP_REMOTE_TESTS 1
|
||||
#cmakedefine ENABLE_FILEINFO 1
|
||||
#cmakedefine EXTRA_TESTS
|
||||
#cmakedefine USE_NETCDF4 1
|
||||
#cmakedefine USE_LIBDL 1
|
||||
@ -102,6 +103,7 @@ are set when opening a binary file on Windows. */
|
||||
#cmakedefine USE_PARALLEL4 1
|
||||
#cmakedefine USE_PNETCDF 1
|
||||
#cmakedefine USE_MMAP 1
|
||||
#cmakedefine ENABLE_FILEINFO 1
|
||||
#cmakedefine TEST_PARALLEL ${TEST_PARALLEL}
|
||||
#cmakedefine BUILD_RPC 1
|
||||
#cmakedefine USE_DISKLESS 1
|
||||
|
17
configure.ac
17
configure.ac
@ -68,7 +68,7 @@ AC_CONFIG_LINKS([nc_test4/ref_hdf5_compat2.nc:nc_test4/ref_hdf5_compat2.nc])
|
||||
AC_CONFIG_LINKS([nc_test4/ref_hdf5_compat3.nc:nc_test4/ref_hdf5_compat3.nc])
|
||||
|
||||
# This call is required by automake.
|
||||
AM_INIT_AUTOMAKE([foreign dist-zip subdir-objects])
|
||||
AM_INIT_AUTOMAKE([foreign dist-zip subdir-objects serial-tests])
|
||||
|
||||
# Check for the existence of this file before proceeding.
|
||||
AC_CONFIG_SRCDIR([include/netcdf.h])
|
||||
@ -200,6 +200,21 @@ enable_netcdf_4=no
|
||||
fi
|
||||
AC_MSG_RESULT([$enable_netcdf_4])
|
||||
|
||||
####
|
||||
# Is Netcdf4 file info capture enabled; includes properties attribute
|
||||
# We do not actually provide a direct flag for disabling this
|
||||
if test "x$enable_netcdf_4" = xyes ; then
|
||||
enable_fileinfo=yes
|
||||
else
|
||||
enable_fileinfo=no
|
||||
fi
|
||||
AC_MSG_CHECKING([If file info capture is enabled])
|
||||
AC_MSG_RESULT([$enable_fileinfo])
|
||||
if test "x$enable_fileinfo" = xyes ; then
|
||||
AC_DEFINE([ENABLE_FILEINFO], [1], [file info])
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_FILEINFO, [test x$enable_fileinfo = xyes])
|
||||
|
||||
# Does the user require dynamic loading?
|
||||
# This is only for those hdf5 installs that support it.
|
||||
AC_MSG_CHECKING([do we require hdf5 dynamic-loading support])
|
||||
|
@ -126,3 +126,42 @@ It is strongly recommended that applicable conventions be followed unless there
|
||||
<p>
|
||||
|
||||
> Typical conventions web sites will include references to documents in some form agreed upon by the community that supports the conventions and examples of netCDF file structures that follow the conventions.
|
||||
|
||||
# Provenance Attributes
|
||||
|
||||
These attributes can occur in netCDF enhanced (netcdf-4) files beginning
|
||||
with version 4.4.1. They all are associated with the root group as
|
||||
global attributes. They are hidden in the sense that they can only be
|
||||
accessed thru the netcdf-C api calls via the name. They have no
|
||||
attribute number and will not be counted in the number of global
|
||||
attributes in the root group. The simplest way to view these attributes
|
||||
is to use the -s flag to the ncdump command.
|
||||
|
||||
`_NCProperties`
|
||||
|
||||
> This attribute is persistent in the file, but hidden. It is inserted in the file at creation time and is never modified after that point. It specifies the following.
|
||||
> - The version for the netcdf library used at creation time.
|
||||
> - The version for the HDF5 library used at creation time.
|
||||
|
||||
> Its format is: `name=value|name=value ...`<br>
|
||||
> Occurrences of '|' in the name or value are disallowed.
|
||||
|
||||
> The current set of known names is as follows.
|
||||
> - version=... The current format version for the _NCProperties file, currently 1.
|
||||
> - netcdflibversion=... The version of the netcdf library used to create the file. The value is, for example, 4.4.1-rc1-development or 4.4.1.
|
||||
> - hdf5libversion=... The version of the HDF5 library used to create the file. The value is, for example, 1.8.16 or 1.10.0.
|
||||
|
||||
`_SuperblockVersion`
|
||||
|
||||
> This attribute is ephemeral in that it is computed by looking at the file's HDF5 superblock.
|
||||
> It has this form: `_SuperBlockVersion = 0|1|2|3|...`
|
||||
|
||||
`_IsNetcdf4`
|
||||
|
||||
> This attribute is ephemeral in that it is computed by walking the metadata of the file looking for attributes specific to netCDF-4 files.
|
||||
|
||||
> The _IsNetcdf4 attribute has the form: `_IsNetcdf4 = 0|1`
|
||||
> where 1 means the file has various tags indicating it was produced thru the netcdf-4 API.
|
||||
|
||||
> This attribute is computed by using the HDF5 API to walk the file to look for attributes specific to netcdf-4. False negatives are possible for a small subset of netcdf-4 files, especially those not containing dimensions. False positives are only possible by deliberate modifications to an existing HDF5 file thru the HDF5 API. For files with the _NCProperties attribute, this attribute is redundant. For files created prior to the introduction of the _NCProperties attribute, this may be a useful indicator of the provenance of the file.
|
||||
|
||||
|
@ -653,7 +653,7 @@ stripped from the name for the netCDF API.
|
||||
Attributes in HDF5 and netCDF-4 correspond very closely. Each
|
||||
attribute in an HDF5 file is represented as an attribute in the
|
||||
netCDF-4 file, with the exception of the attributes below, which are
|
||||
ignored by the netCDF-4 API.
|
||||
hidden by the netCDF-4 API.
|
||||
- _Netcdf4Coordinates An integer array containing the dimension IDs of
|
||||
a variable which is a multi-dimensional coordinate variable.
|
||||
- _nc3_strict When this (scalar, H5T_NATIVE_INT) attribute exists in
|
||||
@ -670,6 +670,9 @@ ignored by the netCDF-4 API.
|
||||
- _Netcdf4Dimid Holds a scalar H5T_NATIVE_INT that is the (zero-based)
|
||||
dimension ID for this dimension, needed when dimensions and
|
||||
coordinate variables are defined in different orders.
|
||||
- _NCProperties Holds provenance information about a file at the time
|
||||
it was created. It specifies the versions of the netCDF and HDF5
|
||||
libraries used to create the file.
|
||||
|
||||
\subsection user_defined_spec User-Defined Data Types
|
||||
|
||||
|
@ -2233,17 +2233,20 @@ one of 'classic'. '64-bit offset', 'netCDF-4', or 'netCDF-4 classic
|
||||
model'.
|
||||
|
||||
@par -s
|
||||
Specifies that \e special virtual attributes should be output for the
|
||||
file format variant and for variable properties such as
|
||||
Specifies that \e special virtual and hidden attributes should be output
|
||||
for the file format variant and for variable properties such as
|
||||
compression, chunking, and other properties specific to the format
|
||||
implementation that are primarily related to performance rather
|
||||
than the logical schema of the data. All the special virtual
|
||||
attributes begin with '_' followed by an upper-case
|
||||
letter. Currently they include the global attribute '_Format' and
|
||||
letter. Currently they include the global attributes '_Format',
|
||||
'_NCProperties', '_IsNetcdf4', '_SuperblockVersion' and
|
||||
the variable attributes '_ChunkSizes', '_DeflateLevel',
|
||||
'_Endianness', '_Fletcher32', '_NoFill', '_Shuffle', and '_Storage'.
|
||||
The \b ncgen utility recognizes these attributes and
|
||||
supports them appropriately.
|
||||
supports them appropriately. For '_NCProperties',
|
||||
'_IsNetcdf4', and '_SuperblockVersion', the term 'appropriately'
|
||||
means that they are ignored.
|
||||
|
||||
@par -t
|
||||
Controls display of time data, if stored in a variable that uses a
|
||||
|
@ -87,12 +87,14 @@ extern int nc_set_default_format(int format, int *old_formatp);
|
||||
/* This function gets a current default create flag */
|
||||
extern int nc_get_default_format(void);
|
||||
|
||||
|
||||
extern int add_to_NCList(NC*);
|
||||
extern void del_from_NCList(NC*);/* does not free object */
|
||||
extern NC* find_in_NCList(int ext_ncid);
|
||||
extern NC* find_in_NCList_by_name(const char*);
|
||||
extern void free_NCList(void);/* reclaim whole list */
|
||||
extern int count_NCList(void); /* return # of entries in NClist */
|
||||
extern int iterate_NCList(int i,NC**); /* Walk from 0 ...; ERANGE return => stop */
|
||||
|
||||
/* Defined in nc.c */
|
||||
extern void free_NC(NC*);
|
||||
|
@ -9,21 +9,21 @@
|
||||
#ifndef _NC4INTERNAL_
|
||||
#define _NC4INTERNAL_
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <hdf5.h>
|
||||
#include <ncdimscale.h>
|
||||
#include <nc_logging.h>
|
||||
#include "ncdimscale.h"
|
||||
#include "nc_logging.h"
|
||||
|
||||
#ifdef USE_PARALLEL
|
||||
#include <netcdf_par.h>
|
||||
#include "netcdf_par.h"
|
||||
#endif /* USE_PARALLEL */
|
||||
#include <netcdf.h>
|
||||
#include <netcdf_f.h>
|
||||
#include "netcdf.h"
|
||||
#include "netcdf_f.h"
|
||||
|
||||
/* Always needed */
|
||||
#include "nc.h"
|
||||
@ -100,6 +100,11 @@ typedef enum {VAR, DIM, ATT} NC_OBJ_T;
|
||||
/* Boolean type, to make the code easier to read */
|
||||
typedef enum {NC_FALSE = 0, NC_TRUE = 1} nc_bool_t;
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
/*Forward*/
|
||||
struct NCFILEINFO;
|
||||
#endif
|
||||
|
||||
/* Generic doubly-linked list node */
|
||||
typedef struct NC_LIST_NODE
|
||||
{
|
||||
@ -286,6 +291,7 @@ typedef struct NC_GRP_INFO
|
||||
#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. */
|
||||
typedef struct NC_HDF5_FILE_INFO
|
||||
@ -314,6 +320,9 @@ typedef struct NC_HDF5_FILE_INFO
|
||||
nc_bool_t hdf4; /* True for HDF4 file */
|
||||
int sdid;
|
||||
#endif /* USE_HDF4 */
|
||||
#ifdef ENABLE_FILEINFO
|
||||
struct NCFILEINFO* fileinfo;
|
||||
#endif
|
||||
} NC_HDF5_FILE_INFO_T;
|
||||
|
||||
|
||||
@ -407,8 +416,8 @@ int nc4_normalize_name(const char *name, char *norm_name);
|
||||
int nc4_check_dup_name(NC_GRP_INFO_T *grp, char *norm_name);
|
||||
|
||||
/* HDF5 initialization */
|
||||
static int nc4_hdf5_initialized;
|
||||
void nc4_hdf5_initialize(void);
|
||||
extern int nc4_hdf5_initialized;
|
||||
extern void nc4_hdf5_initialize(void);
|
||||
|
||||
/* This is only included if --enable-logging is used for configure; it
|
||||
prints info about the metadata to stderr. */
|
||||
@ -420,4 +429,64 @@ int log_metadata_nc(NC *nc);
|
||||
#define NC4_DATA(nc) ((NC_HDF5_FILE_INFO_T*)(nc)->dispatchdata)
|
||||
#define NC4_DATA_SET(nc,data) ((nc)->dispatchdata = (void*)(data))
|
||||
|
||||
/* Reserved Attributes */
|
||||
extern const char* NC_RESERVED_VARATT_LIST[];
|
||||
extern const char* NC_RESERVED_ATT_LIST[];
|
||||
extern const char* NC_RESERVED_SPECIAL_LIST[];
|
||||
#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"
|
||||
|
||||
/**************************************************/
|
||||
/**
|
||||
For netcdf4 files, capture state information about the following:
|
||||
1. Global: netcdf library version
|
||||
2. Global: hdf5 library version
|
||||
3. Per file: superblock version
|
||||
4. Per File: was it created by netcdf-4?
|
||||
5. Per file: _NCProperties attribute
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
|
||||
#define NCPROPS "_NCProperties"
|
||||
#define NCPROPS_VERSION (1)
|
||||
#define NCPROPSSEP '|'
|
||||
#define NCPROPS_LENGTH (8192)
|
||||
|
||||
/* Currently used properties */
|
||||
#define NCPVERSION "version" /* Of the properties format */
|
||||
#define NCPHDF5LIBVERSION "hdf5libversion"
|
||||
#define NCPNCLIBVERSION "netcdflibversion"
|
||||
|
||||
/* Other hidden attributes */
|
||||
#define ISNETCDF4ATT "_IsNetcdf4"
|
||||
#define SUPERBLOCKATT "_SuperblockVersion"
|
||||
|
||||
struct NCFILEINFO {
|
||||
int superblockversion;
|
||||
/* Following is filled from NCPROPS attribute or from global version */
|
||||
struct NCPROPINFO {
|
||||
int version; /* 0 => not defined */
|
||||
char hdf5ver[NC_MAX_NAME+1];
|
||||
char netcdfver[NC_MAX_NAME+1];
|
||||
char text[NCPROPS_LENGTH+1]; /* Value of the NCPROPS attribute */
|
||||
} propattr;
|
||||
};
|
||||
|
||||
extern struct NCPROPINFO globalpropinfo;
|
||||
|
||||
extern int NC4_fileinfo_init(void); /*libsrc4/ncinfo.c*/
|
||||
extern int NC4_get_fileinfo(struct NC_HDF5_FILE_INFO* info, struct NCPROPINFO*); /*libsrc4/ncinfo.c*/
|
||||
extern int NC4_put_propattr(struct NC_HDF5_FILE_INFO* info); /*libsrc4/ncinfo.c*/
|
||||
|
||||
/* ENABLE_FILEINFO => ENABLE_NETCDF4 */
|
||||
extern int NC4_hdf5get_libversion(unsigned*,unsigned*,unsigned*);/*libsrc4/nc4hdf.c*/
|
||||
extern int NC4_hdf5get_superblock(struct NC_HDF5_FILE_INFO*, int*);/*libsrc4/nc4hdf.c*/
|
||||
extern int NC4_isnetcdf4(struct NC_HDF5_FILE_INFO*); /*libsrc4/nc4hdf.c*/
|
||||
#endif /*ENABLE_FILEINFO*/
|
||||
|
||||
#endif /* _NETCDF4_ */
|
||||
|
@ -161,7 +161,8 @@ nc_del_att(int ncid, int varid, const char *name)
|
||||
int stat = NC_check_id(ncid, &ncp);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
TRACE(nc_del_att);
|
||||
return ncp->dispatch->del_att(ncid, varid, name);
|
||||
stat = ncp->dispatch->del_att(ncid, varid, name);
|
||||
return stat;
|
||||
}
|
||||
/*! \} */ /* End of named group ...*/
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#define ID_SHIFT (16)
|
||||
#define NCFILELISTLENGTH 0x10000
|
||||
|
||||
/* Version one just allocates the max space (sizeof(NC*)*2^16)*/
|
||||
static NC** nc_filelist = NULL;
|
||||
|
||||
@ -111,4 +112,13 @@ find_in_NCList_by_name(const char* path)
|
||||
return f;
|
||||
}
|
||||
|
||||
int
|
||||
iterate_NCList(int index, NC** ncp)
|
||||
{
|
||||
/* Walk from 0 ...; 0 return => stop */
|
||||
if(index < 0 || index >= NCFILELISTLENGTH)
|
||||
return NC_ERANGE;
|
||||
if(ncp) *ncp = nc_filelist[index];
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#endif
|
||||
|
||||
#include "ncdispatch.h"
|
||||
#include "nc4internal.h"
|
||||
|
||||
extern int NC3_initialize(void);
|
||||
extern int NC3_finalize(void);
|
||||
@ -54,25 +55,26 @@ nc_initialize()
|
||||
NC_finalized = 0;
|
||||
|
||||
/* Do general initialization */
|
||||
if((stat = NCDISPATCH_initialize())) return stat;
|
||||
if((stat = NCDISPATCH_initialize())) goto done;
|
||||
|
||||
/* Initialize each active protocol */
|
||||
|
||||
if((stat = NC3_initialize())) return stat;
|
||||
|
||||
if((stat = NC3_initialize())) goto done;
|
||||
#ifdef USE_DAP
|
||||
if((stat = NCD2_initialize())) return stat;
|
||||
if((stat = NCD2_initialize())) goto done;
|
||||
#endif
|
||||
|
||||
#ifdef USE_PNETCDF
|
||||
if((stat = NCP_initialize())) return stat;
|
||||
if((stat = NCP_initialize())) goto done;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NETCDF4
|
||||
if((stat = NC4_initialize())) return stat;
|
||||
if((stat = NC4_initialize())) goto done;
|
||||
#endif /* USE_NETCDF4 */
|
||||
|
||||
return NC_NOERR;
|
||||
#ifdef ENABLE_FILEINFO
|
||||
stat = NC4_fileinfo_init();
|
||||
#endif
|
||||
|
||||
done:
|
||||
return stat;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,5 +116,3 @@ nc_finalize(void)
|
||||
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Process these files with m4.
|
||||
|
||||
SET(libsrc4_SOURCES nc4dispatch.c nc4attr.c nc4dim.c nc4file.c nc4grp.c nc4type.c nc4var.c ncfunc.c nc4internal.c nc4hdf.c)
|
||||
SET(libsrc4_SOURCES nc4dispatch.c nc4attr.c nc4dim.c nc4file.c nc4grp.c nc4type.c nc4var.c ncfunc.c nc4internal.c nc4hdf.c nc4info.c)
|
||||
|
||||
IF(LOGGING)
|
||||
SET(libsrc4_SOURCES ${libsrc4_SOURCES} error4.c)
|
||||
|
@ -16,6 +16,9 @@ endif
|
||||
noinst_LTLIBRARIES = libnetcdf4.la
|
||||
libnetcdf4_la_SOURCES = nc4dispatch.c nc4dispatch.h nc4attr.c nc4dim.c \
|
||||
nc4file.c nc4grp.c nc4hdf.c nc4internal.c nc4type.c nc4var.c ncfunc.c error4.c
|
||||
if ENABLE_FILEINFO
|
||||
libnetcdf4_la_SOURCES += nc4info.c
|
||||
endif
|
||||
|
||||
EXTRA_DIST=CMakeLists.txt
|
||||
|
||||
|
@ -21,6 +21,10 @@ conditions.
|
||||
#include <pnetcdf.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
static int nc4_get_att_special(NC_HDF5_FILE_INFO_T*, const char*, nc_type, int, void*, size_t*, int*);
|
||||
#endif
|
||||
|
||||
int nc4typelen(nc_type type);
|
||||
|
||||
/* Get or put attribute metadata from our linked list of file
|
||||
@ -43,10 +47,11 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
|
||||
char norm_name[NC_MAX_NAME + 1];
|
||||
int i;
|
||||
int retval = NC_NOERR;
|
||||
const char** sp;
|
||||
|
||||
if (attnum)
|
||||
if (attnum) {
|
||||
my_attnum = *attnum;
|
||||
assert(nc && NC4_DATA(nc));
|
||||
}
|
||||
|
||||
LOG((3, "%s: ncid 0x%x varid %d name %s attnum %d mem_type %d",
|
||||
__func__, ncid, varid, name, my_attnum, mem_type));
|
||||
@ -60,6 +65,17 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
|
||||
if ((retval = nc4_normalize_name(name, norm_name)))
|
||||
BAIL(retval);
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
if(nc->ext_ncid == ncid && varid == NC_GLOBAL) {
|
||||
const char** sp;
|
||||
for(sp = NC_RESERVED_SPECIAL_LIST;*sp;sp++) {
|
||||
if(strcmp(name,*sp)==0) {
|
||||
return nc4_get_att_special(h5, norm_name, mem_type, is_long, data, lenp, attnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Find the attribute, if it exists. If we don't find it, we are
|
||||
major failures. */
|
||||
if ((retval = nc4_find_grp_att(grp, varid, norm_name, my_attnum, &att)))
|
||||
@ -84,8 +100,9 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
|
||||
*lenp = att->len;
|
||||
if (xtype)
|
||||
*xtype = att->nc_typeid;
|
||||
if (attnum)
|
||||
if (attnum) {
|
||||
*attnum = att->attnum;
|
||||
}
|
||||
|
||||
/* Zero len attributes are easy to read! */
|
||||
if (!att->len)
|
||||
@ -232,6 +249,17 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
|
||||
if ((retval = nc4_check_name(name, norm_name)))
|
||||
return retval;
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
if(nc->ext_ncid == ncid && varid == NC_GLOBAL) {
|
||||
const char** sp;
|
||||
for(sp = NC_RESERVED_SPECIAL_LIST;*sp;sp++) {
|
||||
if(strcmp(name,*sp)==0) {
|
||||
return NC_ENOTATT; /* Not settable */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Find att, if it exists. */
|
||||
if (varid == NC_GLOBAL)
|
||||
attlist = &grp->att;
|
||||
@ -246,6 +274,7 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
|
||||
if (!var)
|
||||
return NC_ENOTVAR;
|
||||
}
|
||||
|
||||
for (att = *attlist; att; att = att->l.next)
|
||||
if (!strcmp(att->name, norm_name))
|
||||
break;
|
||||
@ -860,6 +889,22 @@ nc4_put_att_tc(int ncid, int varid, const char *name, nc_type file_type,
|
||||
h5 = NC4_DATA(nc);
|
||||
assert(h5);
|
||||
|
||||
if(nc->ext_ncid == ncid && varid == NC_GLOBAL) {
|
||||
const char** reserved = NC_RESERVED_ATT_LIST;
|
||||
for(;*reserved;reserved++) {
|
||||
if(strcmp(name,*reserved)==0)
|
||||
return NC_ENAMEINUSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(varid != NC_GLOBAL) {
|
||||
const char** reserved = NC_RESERVED_VARATT_LIST;
|
||||
for(;*reserved;reserved++) {
|
||||
if(strcmp(name,*reserved)==0)
|
||||
return NC_ENAMEINUSE;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /*def USE_PNETCDF*/
|
||||
/* Take care of files created/opened with parallel-netcdf library. */
|
||||
if (h5->pnetcdf_file)
|
||||
@ -903,6 +948,44 @@ nc4_put_att_tc(int ncid, int varid, const char *name, nc_type file_type,
|
||||
mem_type_is_long, op);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
static int
|
||||
nc4_get_att_special(NC_HDF5_FILE_INFO_T *h5, const char* name, nc_type mem_type, int islong, void* data, size_t* lenp, int* idp)
|
||||
{
|
||||
/* Always make the attr id be -1 */
|
||||
if(idp) *idp = -1;
|
||||
|
||||
if(strcmp(name,NCPROPS)==0) {
|
||||
if(h5->fileinfo->propattr.version == 0)
|
||||
return NC_ENOTATT;
|
||||
if(lenp) *lenp = strlen(h5->fileinfo->propattr.text);
|
||||
if(data) strcpy((char*)data,h5->fileinfo->propattr.text);
|
||||
} else if(strcmp(name,ISNETCDF4ATT)==0
|
||||
|| strcmp(name,SUPERBLOCKATT)==0) {
|
||||
unsigned long long iv = 0;
|
||||
if(strcmp(name,SUPERBLOCKATT)==0)
|
||||
iv = (unsigned long long)h5->fileinfo->superblockversion;
|
||||
else /* strcmp(name,ISNETCDF4ATT)==0 */
|
||||
iv = NC4_isnetcdf4(h5);
|
||||
if(lenp) *lenp = 1;
|
||||
if(data)
|
||||
switch (mem_type) {
|
||||
case NC_BYTE: *((char*)data) = (char)iv; break;
|
||||
case NC_SHORT: *((short*)data) = (short)iv; break;
|
||||
case NC_INT: *((int*)data) = (int)iv; break;
|
||||
case NC_UBYTE: *((unsigned char*)data) = (unsigned char)iv; break;
|
||||
case NC_USHORT: *((unsigned short*)data) = (unsigned short)iv; break;
|
||||
case NC_UINT: *((unsigned int*)data) = (unsigned int)iv; break;
|
||||
case NC_INT64: *((long long*)data) = (long long)iv; break;
|
||||
case NC_UINT64: *((unsigned long long*)data) = (unsigned long long)iv; break;
|
||||
default:
|
||||
return NC_ERANGE;
|
||||
}
|
||||
}
|
||||
return NC_NOERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read an attribute of any type, with type conversion. This may be
|
||||
* called by any of the nc_get_att_* functions. */
|
||||
int
|
||||
@ -953,8 +1036,7 @@ nc4_get_att_tc(int ncid, int varid, const char *name, nc_type mem_type,
|
||||
}
|
||||
}
|
||||
#endif /* USE_PNETCDF */
|
||||
|
||||
return nc4_get_att(ncid, nc, varid, name, NULL, mem_type,
|
||||
return nc4_get_att(ncid, nc, varid, name, NULL, mem_type,
|
||||
NULL, NULL, mem_type_is_long, ip);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ COPYRIGHT file for copying and redistribution conditions.
|
||||
#include "config.h"
|
||||
#include <errno.h> /* netcdf functions sometimes return system errors */
|
||||
|
||||
|
||||
#include "nc.h"
|
||||
#include "nc4internal.h"
|
||||
#include "nc4dispatch.h"
|
||||
@ -28,6 +27,11 @@ COPYRIGHT file for copying and redistribution conditions.
|
||||
#include <hdf5_hl.h>
|
||||
#endif
|
||||
|
||||
/* When we have open objects at file close, should
|
||||
we log them or print to stdout. Default is to log
|
||||
*/
|
||||
#define LOGOPEN 1
|
||||
|
||||
/* This is to track opened HDF5 objects to make sure they are
|
||||
* closed. */
|
||||
#ifdef EXTRA_TESTS
|
||||
@ -38,18 +42,13 @@ extern int num_spaces;
|
||||
#define MIN_DEFLATE_LEVEL 0
|
||||
#define MAX_DEFLATE_LEVEL 9
|
||||
|
||||
/* These are the special attributes added by the HDF5 dimension scale
|
||||
* API. They will be ignored by netCDF-4. */
|
||||
#define REFERENCE_LIST "REFERENCE_LIST"
|
||||
#define CLASS "CLASS"
|
||||
#define DIMENSION_LIST "DIMENSION_LIST"
|
||||
#define NAME "NAME"
|
||||
|
||||
/* Define the illegal mode flags */
|
||||
static const int ILLEGAL_OPEN_FLAGS = (NC_MMAP|NC_64BIT_OFFSET);
|
||||
|
||||
static const int ILLEGAL_CREATE_FLAGS = (NC_NOWRITE|NC_MMAP|NC_INMEMORY|NC_64BIT_OFFSET|NC_CDF5);
|
||||
|
||||
extern void reportopenobjects(int log, hid_t);
|
||||
|
||||
/*! Struct to track information about objects in a group, for nc4_rec_read_metadata()
|
||||
|
||||
\internal
|
||||
@ -80,6 +79,46 @@ static int NC4_enddef(int ncid);
|
||||
static int nc4_rec_read_metadata(NC_GRP_INFO_T *grp);
|
||||
static int close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort);
|
||||
|
||||
/* Define the names of attributes to ignore
|
||||
* added by the HDF5 dimension scale; these
|
||||
* attached to variables.
|
||||
* They cannot be modified thru the netcdf-4 API.
|
||||
*/
|
||||
const char* NC_RESERVED_VARATT_LIST[] = {
|
||||
NC_ATT_REFERENCE_LIST,
|
||||
NC_ATT_CLASS,
|
||||
NC_ATT_DIMENSION_LIST,
|
||||
NC_ATT_NAME,
|
||||
NC_ATT_COORDINATES,
|
||||
NC_DIMID_ATT_NAME,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Define the names of attributes to ignore
|
||||
* because they are "hidden" global attributes.
|
||||
* They can be read, but not modified thru the netcdf-4 API.
|
||||
*/
|
||||
const char* NC_RESERVED_ATT_LIST[] = {
|
||||
NC_ATT_FORMAT,
|
||||
NC3_STRICT_ATT_NAME,
|
||||
#ifdef ENABLE_FILEINFO
|
||||
NCPROPS,
|
||||
ISNETCDF4ATT,
|
||||
SUPERBLOCKATT,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
/* Define the subset of the reserved list that is readable by name only */
|
||||
const char* NC_RESERVED_SPECIAL_LIST[] = {
|
||||
ISNETCDF4ATT,
|
||||
SUPERBLOCKATT,
|
||||
NCPROPS,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
/* These are the default chunk cache sizes for HDF5 files created or
|
||||
* opened with netCDF-4. */
|
||||
size_t nc4_chunk_cache_size = CHUNK_CACHE_SIZE;
|
||||
@ -314,7 +353,7 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
|
||||
return NC_NOERR;
|
||||
#endif
|
||||
|
||||
/* Need this access plist to control how HDF5 handles open onjects
|
||||
/* Need this access plist to control how HDF5 handles open objects
|
||||
* on file close. (Setting H5F_CLOSE_SEMI will cause H5Fclose to
|
||||
* fail if there are any open objects in the file. */
|
||||
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
||||
@ -424,8 +463,7 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
|
||||
BAIL(NC_EFILEMETA);
|
||||
|
||||
/* Release the property lists. */
|
||||
if (H5Pclose(fapl_id) < 0 ||
|
||||
H5Pclose(fcpl_id) < 0)
|
||||
if (H5Pclose(fapl_id) < 0 || H5Pclose(fcpl_id) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
#ifdef EXTRA_TESTS
|
||||
num_plists--;
|
||||
@ -435,6 +473,11 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
|
||||
/* Define mode gets turned on automatically on create. */
|
||||
nc4_info->flags |= NC_INDEF;
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
NC4_get_fileinfo(nc4_info,&globalpropinfo);
|
||||
NC4_put_propattr(nc4_info);
|
||||
#endif
|
||||
|
||||
return NC_NOERR;
|
||||
|
||||
exit: /*failure exit*/
|
||||
@ -474,6 +517,7 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
|
||||
MPI_Comm comm = MPI_COMM_WORLD;
|
||||
MPI_Info info = MPI_INFO_NULL;
|
||||
int res;
|
||||
NC* nc;
|
||||
|
||||
assert(nc_file && path);
|
||||
|
||||
@ -1490,6 +1534,7 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
|
||||
hid_t access_pid = 0;
|
||||
int incr_id_rc = 0; /* Whether the dataset ID's ref count has been incremented */
|
||||
int natts, a, d;
|
||||
const char** reserved;
|
||||
|
||||
NC_ATT_INFO_T *att;
|
||||
hid_t attid = 0;
|
||||
@ -1758,13 +1803,10 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
|
||||
LOG((4, "%s:: a %d att_name %s", __func__, a, att_name));
|
||||
|
||||
/* Should we ignore this attribute? */
|
||||
if (strcmp(att_name, REFERENCE_LIST) &&
|
||||
strcmp(att_name, CLASS) &&
|
||||
strcmp(att_name, DIMENSION_LIST) &&
|
||||
strcmp(att_name, NAME) &&
|
||||
strcmp(att_name, COORDINATES) &&
|
||||
strcmp(att_name, NC_DIMID_ATT_NAME))
|
||||
{
|
||||
for(reserved=NC_RESERVED_VARATT_LIST;*reserved;reserved++) {
|
||||
if (strcmp(att_name, *reserved)==0) break;
|
||||
}
|
||||
if(*reserved == NULL) {
|
||||
/* Add to the end of the list of atts for this var. */
|
||||
if ((retval = nc4_att_list_add(&var->att, &att)))
|
||||
BAIL(retval);
|
||||
@ -1825,36 +1867,43 @@ exit:
|
||||
static int
|
||||
read_grp_atts(NC_GRP_INFO_T *grp)
|
||||
{
|
||||
hid_t attid = 0;
|
||||
hid_t attid = -1;
|
||||
hsize_t num_obj, i;
|
||||
NC_ATT_INFO_T *att;
|
||||
NC_TYPE_INFO_T *type;
|
||||
char obj_name[NC_MAX_HDF5_NAME + 1];
|
||||
int max_len;
|
||||
int retval = NC_NOERR;
|
||||
int hidden = 0;
|
||||
|
||||
num_obj = H5Aget_num_attrs(grp->hdf_grpid);
|
||||
for (i = 0; i < num_obj; i++)
|
||||
{
|
||||
/* Close an attribute from previous loop iteration */
|
||||
/* (Should be from 'continue' statement, below) */
|
||||
if (attid && H5Aclose(attid) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
|
||||
if ((attid = H5Aopen_idx(grp->hdf_grpid, (unsigned int)i)) < 0)
|
||||
BAIL(NC_EATTMETA);
|
||||
if (H5Aget_name(attid, NC_MAX_NAME + 1, obj_name) < 0)
|
||||
BAIL(NC_EATTMETA);
|
||||
LOG((3, "reading attribute of _netCDF group, named %s", obj_name));
|
||||
|
||||
/* See if this a hidden, global attribute */
|
||||
if(grp->nc4_info->root_grp == grp) {
|
||||
const char** reserved = NC_RESERVED_ATT_LIST;
|
||||
hidden = 0;
|
||||
for(;*reserved;reserved++) {
|
||||
if(strcmp(*reserved,obj_name)==0) {
|
||||
hidden = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This may be an attribute telling us that strict netcdf-3
|
||||
* rules are in effect. If so, we will make note of the fact,
|
||||
* but not add this attribute to the metadata. It's not a user
|
||||
* attribute, but an internal netcdf-4 one. */
|
||||
if (!strcmp(obj_name, NC3_STRICT_ATT_NAME))
|
||||
grp->nc4_info->cmode |= NC_CLASSIC_MODEL;
|
||||
else
|
||||
{
|
||||
if(strcmp(obj_name, NC3_STRICT_ATT_NAME)==0)
|
||||
grp->nc4_info->cmode |= NC_CLASSIC_MODEL;
|
||||
else if(!hidden) {
|
||||
/* Add an att struct at the end of the list, and then go to it. */
|
||||
if ((retval = nc4_att_list_add(&grp->att, &att)))
|
||||
BAIL(retval);
|
||||
@ -1866,26 +1915,28 @@ read_grp_atts(NC_GRP_INFO_T *grp)
|
||||
strncpy(att->name, obj_name, max_len);
|
||||
att->name[max_len] = 0;
|
||||
att->attnum = grp->natts++;
|
||||
if ((retval = read_hdf5_att(grp, attid, att)))
|
||||
{
|
||||
if (NC_EBADTYPID == retval)
|
||||
{
|
||||
if ((retval = nc4_att_list_del(&grp->att, att)))
|
||||
retval = read_hdf5_att(grp, attid, att);
|
||||
if(retval == NC_EBADTYPID) {
|
||||
if((retval = nc4_att_list_del(&grp->att, att)))
|
||||
BAIL(retval);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
} else if(retval) {
|
||||
BAIL(retval);
|
||||
}
|
||||
att->created = NC_TRUE;
|
||||
if ((retval = nc4_find_type(grp->nc4_info, att->nc_typeid, &type)))
|
||||
BAIL(retval);
|
||||
} else {
|
||||
att->created = NC_TRUE;
|
||||
if ((retval = nc4_find_type(grp->nc4_info, att->nc_typeid, &type)))
|
||||
BAIL(retval);
|
||||
}
|
||||
}
|
||||
/* Unconditionally close the open attribute */
|
||||
H5Aclose(attid);
|
||||
attid = -1;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (attid > 0 && H5Aclose(attid) < 0)
|
||||
BAIL2(NC_EHDFERR);
|
||||
exit:
|
||||
if (attid > 0) {
|
||||
if(H5Aclose(attid) < 0)
|
||||
BAIL2(NC_EHDFERR);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -2229,7 +2280,6 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
|
||||
BAIL(NC_EHDFERR);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_PARALLEL4
|
||||
/* If this is a parallel file create, set up the file creation
|
||||
property list. */
|
||||
@ -2323,6 +2373,10 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
|
||||
num_plists--;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
NC4_get_fileinfo(nc4_info,NULL);
|
||||
#endif
|
||||
|
||||
return NC_NOERR;
|
||||
|
||||
exit:
|
||||
@ -2834,7 +2888,6 @@ NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
|
||||
#endif /* USE_HDF4 */
|
||||
else
|
||||
assert(0); /* should never happen */
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -3087,6 +3140,11 @@ close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort)
|
||||
MPI_Info_free(&h5->info);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
if(h5->fileinfo) free(h5->fileinfo);
|
||||
#endif
|
||||
|
||||
if (H5Fclose(h5->hdfid) < 0)
|
||||
{
|
||||
int nobjs;
|
||||
@ -3097,23 +3155,29 @@ close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort)
|
||||
BAIL_QUIET(NC_EHDFERR);
|
||||
} else if(nobjs > 0) {
|
||||
#ifdef LOGGING
|
||||
char msg[1024];
|
||||
int logit = 1;
|
||||
/* If the close doesn't work, probably there are still some HDF5
|
||||
* objects open, which means there's a bug in the library. So
|
||||
* print out some info on to help the poor programmer figure it
|
||||
* out. */
|
||||
LOG((0, "There are %d HDF5 objects open!", nobjs));
|
||||
snprintf(msg,sizeof(msg),"There are %d HDF5 objects open!", nobjs);
|
||||
#ifdef LOGOPEN
|
||||
LOG((0, msg));
|
||||
#else
|
||||
fprintf(stdout,msg);
|
||||
logit = 0;
|
||||
#endif
|
||||
reportopenobjects(logit,h5->hdfid);
|
||||
#endif
|
||||
BAIL_QUIET(NC_EHDFERR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
/* Free the nc4_info struct; above code should have reclaimed
|
||||
everything else */
|
||||
if(h5 != NULL)
|
||||
free(h5);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
235
libsrc4/nc4hdf.c
235
libsrc4/nc4hdf.c
@ -25,6 +25,8 @@
|
||||
|
||||
#define NC3_STRICT_ATT_NAME "_nc3_strict"
|
||||
|
||||
#define NC_HDF5_MAX_NAME 1024
|
||||
|
||||
/* This is to track opened HDF5 objects to make sure they are
|
||||
* closed. */
|
||||
#ifdef EXTRA_TESTS
|
||||
@ -1901,10 +1903,10 @@ write_nc3_strict_att(hid_t hdf_grpid)
|
||||
BAIL(NC_EHDFERR);
|
||||
if (H5Aget_name(attid, NC_MAX_HDF5_NAME, att_name) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
if (!strcmp(att_name, NC3_STRICT_ATT_NAME))
|
||||
{
|
||||
if (H5Aclose(attid) < 0)
|
||||
if (H5Aclose(attid) < 0)
|
||||
return NC_EFILEMETA;
|
||||
if (strcmp(att_name, NC3_STRICT_ATT_NAME)==0)
|
||||
{
|
||||
return NC_NOERR;
|
||||
}
|
||||
}
|
||||
@ -2488,14 +2490,12 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order)
|
||||
int coord_varid = -1;
|
||||
|
||||
int retval;
|
||||
|
||||
assert(grp && grp->name && grp->hdf_grpid);
|
||||
LOG((3, "%s: grp->name %s, bad_coord_order %d", __func__, grp->name, bad_coord_order));
|
||||
|
||||
/* Write global attributes for this group. */
|
||||
if ((retval = write_attlist(grp->att, NC_GLOBAL, grp)))
|
||||
return retval;
|
||||
|
||||
/* Set the pointers to the beginning of the list of dims & vars in this
|
||||
* group. */
|
||||
dim = grp->dim;
|
||||
@ -3848,3 +3848,228 @@ nc4_get_typeclass(const NC_HDF5_FILE_INFO_T *h5, nc_type xtype, int *type_class)
|
||||
exit:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
NC4_test_netcdf4(void)
|
||||
{
|
||||
return NC_NOERR;
|
||||
}
|
||||
void
|
||||
reportobject(int log, hid_t id, unsigned int type)
|
||||
{
|
||||
# define MAXNAME 1024
|
||||
char name[MAXNAME];
|
||||
ssize_t len;
|
||||
const char* typename = NULL;
|
||||
|
||||
len = H5Iget_name(id, name, MAXNAME);
|
||||
if(len < 0) return;
|
||||
name[len] = '\0';
|
||||
|
||||
switch (type) {
|
||||
case H5F_OBJ_FILE: typename = "File"; break;
|
||||
case H5F_OBJ_DATASET: typename = "Dataset"; break;
|
||||
case H5F_OBJ_GROUP: typename = "Group"; break;
|
||||
case H5F_OBJ_DATATYPE: typename = "Datatype"; break;
|
||||
case H5F_OBJ_ATTR:
|
||||
typename = "Attribute";
|
||||
len = H5Aget_name(id, MAXNAME, name);
|
||||
if(len < 0) len = 0;
|
||||
name[len] = '\0';
|
||||
break;
|
||||
default: typename = "<unknown>"; break;
|
||||
}
|
||||
if(log) {
|
||||
#ifdef LOGGING
|
||||
LOG((0,"Type = %s(%8u) name='%s'",typename,id,name));
|
||||
#endif
|
||||
} else {
|
||||
fprintf(stderr,"Type = %s(%8u) name='%s'",typename,id,name);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int OTYPES[5] = {H5F_OBJ_FILE, H5F_OBJ_DATASET, H5F_OBJ_GROUP, H5F_OBJ_DATATYPE, H5F_OBJ_ATTR};
|
||||
|
||||
static void
|
||||
reportopenobjectsT(int log, hid_t fid, int ntypes, unsigned int* otypes)
|
||||
{
|
||||
int t,i;
|
||||
ssize_t ocount;
|
||||
size_t maxobjs = -1;
|
||||
hid_t* idlist = NULL;
|
||||
|
||||
if(log) {
|
||||
#ifdef LOGGING
|
||||
LOG((0,"\nReport: open objects on %d\n",fid));
|
||||
#endif
|
||||
} else {
|
||||
fprintf(stdout,"\nReport: open objects on %d\n",fid);
|
||||
}
|
||||
maxobjs = H5Fget_obj_count(fid,H5F_OBJ_ALL);
|
||||
if(idlist != NULL) free(idlist);
|
||||
idlist = (hid_t*)malloc(sizeof(hid_t)*maxobjs);
|
||||
for(t=0;t<ntypes;t++) {
|
||||
unsigned int ot = otypes[t];
|
||||
if(ot < 0) break;
|
||||
ocount = H5Fget_obj_ids(fid,ot,maxobjs,idlist);
|
||||
for(i=0;i<ocount;i++) {
|
||||
hid_t o = idlist[i];
|
||||
reportobject(log,o,ot);
|
||||
}
|
||||
}
|
||||
if(idlist != NULL) free(idlist);
|
||||
}
|
||||
|
||||
void
|
||||
reportopenobjects(int log, hid_t fid)
|
||||
{
|
||||
reportopenobjectsT(log, fid,5,OTYPES);
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_FILEINFO
|
||||
int
|
||||
NC4_hdf5get_libversion(unsigned* major,unsigned* minor,unsigned* release)
|
||||
{
|
||||
if(H5get_libversion(major,minor,release) < 0)
|
||||
return NC_EHDFERR;
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
int
|
||||
NC4_hdf5get_superblock(struct NC_HDF5_FILE_INFO* h5, int* idp)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
unsigned super;
|
||||
hid_t plist = -1;
|
||||
if((plist = H5Fget_create_plist(h5->hdfid)) < 0)
|
||||
{stat = NC_EHDFERR; goto done;}
|
||||
if(H5Pget_version(plist, &super, NULL, NULL, NULL) < 0)
|
||||
{stat = NC_EHDFERR; goto done;}
|
||||
if(idp) *idp = (int)super;
|
||||
done:
|
||||
if(plist >= 0) H5Pclose(plist);
|
||||
return stat;
|
||||
}
|
||||
|
||||
/* We define a file as being from netcdf-4 if any of the following
|
||||
are true:
|
||||
1. NCPROPS attribute exists in root group
|
||||
2. NC3_STRICT_ATT_NAME exists in root group
|
||||
3. any of NC_ATT_REFERENCE_LIST, NC_ATT_CLASS,
|
||||
NC_ATT_DIMENSION_LIST, NC_ATT_NAME,
|
||||
NC_ATT_COORDINATES, NC_DIMID_ATT_NAME
|
||||
exist anywhere in the file; note that this
|
||||
requires walking the file.
|
||||
WARNINGS:
|
||||
1. False negatives are possible for a small subset of netcdf-4
|
||||
created files.
|
||||
2. Deliberate falsification in the file can be used to cause
|
||||
a false positive.
|
||||
*/
|
||||
|
||||
static int NC4_get_strict_att(NC_HDF5_FILE_INFO_T*);
|
||||
static int NC4_walk(hid_t, int*);
|
||||
|
||||
int
|
||||
NC4_isnetcdf4(struct NC_HDF5_FILE_INFO* h5)
|
||||
{
|
||||
int stat;
|
||||
int isnc4 = 0;
|
||||
int count;
|
||||
|
||||
#if 0
|
||||
if(h5->fileinfo->propattr.version > 0) {
|
||||
isnc4 = 1;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
/* Look for NC3_STRICT_ATT_NAME */
|
||||
isnc4 = NC4_get_strict_att(h5);
|
||||
if(isnc4 > 0)
|
||||
goto done;
|
||||
/* attribute did not exist */
|
||||
/* => last resort: walk the HDF5 file looking for markers */
|
||||
count = 0;
|
||||
stat = NC4_walk(h5->root_grp->hdf_grpid, &count);
|
||||
if(stat != NC_NOERR)
|
||||
isnc4 = 0;
|
||||
else /* Threshold is at least two matches */
|
||||
isnc4 = (count >= 2);
|
||||
|
||||
done:
|
||||
return isnc4;
|
||||
}
|
||||
|
||||
static int
|
||||
NC4_get_strict_att(NC_HDF5_FILE_INFO_T* h5)
|
||||
{
|
||||
int ncstat = NC_NOERR;
|
||||
size_t size;
|
||||
char text[NCPROPS_LENGTH+1];
|
||||
hid_t grp = -1;
|
||||
hid_t attid = -1;
|
||||
herr_t herr = 0;
|
||||
|
||||
/* Get root group */
|
||||
grp = h5->root_grp->hdf_grpid; /* get root group */
|
||||
/* Try to extract the NC3_STRICT_ATT_NAME attribute */
|
||||
attid = H5Aopen_name(grp, NC3_STRICT_ATT_NAME);
|
||||
H5Aclose(attid);
|
||||
return attid;
|
||||
}
|
||||
|
||||
static int
|
||||
NC4_walk(hid_t gid, int* countp)
|
||||
{
|
||||
int ncstat = NC_NOERR;
|
||||
int i,j,na;
|
||||
ssize_t len;
|
||||
hsize_t nobj;
|
||||
herr_t err;
|
||||
int otype;
|
||||
hid_t grpid, dsid;
|
||||
char name[NC_HDF5_MAX_NAME];
|
||||
|
||||
/* walk group members of interest */
|
||||
err = H5Gget_num_objs(gid, &nobj);
|
||||
for(i = 0; i < nobj; i++) {
|
||||
/* Get name & kind of object in the group */
|
||||
len = H5Gget_objname_by_idx(gid,(hsize_t)i,name,(size_t)NC_HDF5_MAX_NAME);
|
||||
otype = H5Gget_objtype_by_idx(gid,(size_t)i);
|
||||
switch(otype) {
|
||||
case H5G_GROUP:
|
||||
grpid = H5Gopen(gid,name);
|
||||
NC4_walk(grpid,countp);
|
||||
H5Gclose(grpid);
|
||||
break;
|
||||
case H5G_DATASET: /* variables */
|
||||
/* Check for phony_dim */
|
||||
if(strcmp(name,"phony_dim")==0)
|
||||
*countp = *countp + 1;
|
||||
dsid = H5Dopen(gid,name);
|
||||
na = H5Aget_num_attrs(dsid);
|
||||
for(j = 0; j < na; j++) {
|
||||
hid_t aid = H5Aopen_idx(dsid,(unsigned int) j);
|
||||
if(aid >= 0) {
|
||||
const char** p;
|
||||
ssize_t len = H5Aget_name(aid, NC_HDF5_MAX_NAME, name);
|
||||
/* Is this a netcdf-4 marker attribute */
|
||||
for(p=NC_RESERVED_VARATT_LIST;*p;p++) {
|
||||
if(strcmp(name,*p) == 0) {
|
||||
*countp = *countp + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
H5Aclose(aid);
|
||||
}
|
||||
H5Dclose(dsid);
|
||||
break;
|
||||
default:/* ignore */
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ncstat;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
216
libsrc4/nc4info.c
Normal file
216
libsrc4/nc4info.c
Normal file
@ -0,0 +1,216 @@
|
||||
/*********************************************************************
|
||||
* Copyright 2010, UCAR/Unidata
|
||||
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
||||
* ********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <hdf5.h>
|
||||
#include "netcdf.h"
|
||||
#include "nc4internal.h"
|
||||
|
||||
#define IGNORE 0
|
||||
|
||||
#define HDF5_MAX_NAME 1024
|
||||
|
||||
#define NCHECK(expr) {if((expr)!=NC_NOERR) {goto done;}}
|
||||
#define HCHECK(expr) {if((expr)<0) {ncstat = NC_EHDFERR; goto done;}}
|
||||
|
||||
/* Global */
|
||||
struct NCPROPINFO globalpropinfo;
|
||||
|
||||
struct NCdata {
|
||||
};
|
||||
|
||||
int
|
||||
NC4_fileinfo_init(void)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
unsigned major,minor,release;
|
||||
int super;
|
||||
size_t total = 0;
|
||||
|
||||
/* Build nc properties */
|
||||
memset((void*)&globalpropinfo,0,sizeof(globalpropinfo));
|
||||
globalpropinfo.version = NCPROPS_VERSION;
|
||||
globalpropinfo.netcdfver[0] = '\0';
|
||||
globalpropinfo.hdf5ver[0] = '\0';
|
||||
|
||||
stat = NC4_hdf5get_libversion(&major,&minor,&release);
|
||||
if(stat) goto done;
|
||||
snprintf(globalpropinfo.hdf5ver,sizeof(globalpropinfo.hdf5ver),
|
||||
"%1u.%1u.%1u",major,minor,release);
|
||||
strncpy(globalpropinfo.netcdfver,PACKAGE_VERSION,sizeof(globalpropinfo.netcdfver));
|
||||
/* Now build actual attribute text */
|
||||
total = 0;
|
||||
total += strlen(NCPVERSION);
|
||||
total += strlen("=00000000|");
|
||||
total += strlen(NCPNCLIBVERSION);
|
||||
total += strlen(globalpropinfo.netcdfver);
|
||||
total += strlen("=|");
|
||||
total += strlen(NCPHDF5LIBVERSION);
|
||||
total += strlen(globalpropinfo.hdf5ver);
|
||||
total += strlen("="); /* Last pair has no trailing '|' */
|
||||
if(total >= sizeof(globalpropinfo.text)) {
|
||||
fprintf(stderr,"%s size is too small\n",NCPROPS);
|
||||
goto done;
|
||||
}
|
||||
globalpropinfo.text[0] = '\0';
|
||||
snprintf(globalpropinfo.text,sizeof(globalpropinfo.text),
|
||||
"%s=%d|%s=%s|%s=%s",
|
||||
NCPVERSION,globalpropinfo.version,
|
||||
NCPNCLIBVERSION,globalpropinfo.netcdfver,
|
||||
NCPHDF5LIBVERSION,globalpropinfo.hdf5ver);
|
||||
done:
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int
|
||||
NC4_properties_parse(struct NCPROPINFO* ncprops)
|
||||
{
|
||||
size_t len;
|
||||
char propdata[NCPROPS_LENGTH]; /* match nc.h struct NCProperties */
|
||||
char* p;
|
||||
|
||||
ncprops->version = 0;
|
||||
ncprops->hdf5ver[0] = '\0';
|
||||
ncprops->netcdfver[0] = '\0';
|
||||
|
||||
strncpy(propdata,ncprops->text,sizeof(propdata)-1);
|
||||
propdata[sizeof(propdata)-1] = '\0';
|
||||
len = strlen(propdata);
|
||||
if(len == 0) return NC_NOERR;
|
||||
|
||||
/* Walk and fill in ncinfo */
|
||||
p = propdata;
|
||||
while(*p) {
|
||||
char* name = p;
|
||||
char* value = NULL;
|
||||
char* q = strchr(p,'=');
|
||||
if(q == NULL)
|
||||
return NC_EINVAL;
|
||||
*q++ = '\0';
|
||||
value = p = q;
|
||||
q = strchr(p,NCPROPSSEP);
|
||||
if(q == NULL) q = (p+strlen(p)); else* q++ = '\0';
|
||||
p = q;
|
||||
if(name != NULL && value != NULL) {
|
||||
if(strcmp(name,NCPVERSION) == 0) {
|
||||
int v = atoi(value);
|
||||
if(v < 0) v = 0;
|
||||
ncprops->version = v;
|
||||
} else if(strcmp(name,NCPNCLIBVERSION) == 0)
|
||||
strncpy(ncprops->netcdfver,value,sizeof(ncprops->netcdfver)-1);
|
||||
else if(strcmp(name,NCPHDF5LIBVERSION) == 0)
|
||||
strncpy(ncprops->hdf5ver,value,sizeof(ncprops->hdf5ver)-1);
|
||||
/* else ignore */
|
||||
}
|
||||
}
|
||||
/* Guarantee null term */
|
||||
ncprops->netcdfver[sizeof(ncprops->netcdfver)-1] = '\0';
|
||||
ncprops->hdf5ver[sizeof(ncprops->hdf5ver)-1] = '\0';
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
static int
|
||||
NC4_get_propattr(NC_HDF5_FILE_INFO_T* h5)
|
||||
{
|
||||
int ncstat = NC_NOERR;
|
||||
size_t size;
|
||||
H5T_class_t t_class;
|
||||
char text[NCPROPS_LENGTH+1];
|
||||
hid_t grp = -1;
|
||||
hid_t attid = -1;
|
||||
hid_t aspace = -1;
|
||||
hid_t atype = -1;
|
||||
hid_t ntype = -1;
|
||||
herr_t herr = 0;
|
||||
|
||||
/* Get root group */
|
||||
grp = h5->root_grp->hdf_grpid; /* get root group */
|
||||
/* Try to extract the NCPROPS attribute */
|
||||
attid = H5Aopen_name(grp, NCPROPS);
|
||||
if(attid >= 0) {
|
||||
herr = -1;
|
||||
aspace = H5Aget_space(attid); /* dimensions of attribute data */
|
||||
atype = H5Aget_type(attid);
|
||||
/* Verify that atype and size */
|
||||
t_class = H5Tget_class(atype);
|
||||
if(t_class != H5T_STRING) {ncstat = NC_EATTMETA; goto done;}
|
||||
size = H5Tget_size(atype);
|
||||
if(size != NCPROPS_LENGTH) {ncstat = NC_EATTMETA; goto done;}
|
||||
HCHECK((ntype = H5Tget_native_type(atype, H5T_DIR_ASCEND)));
|
||||
HCHECK((H5Aread(attid, ntype, text)));
|
||||
/* Try to parse text */
|
||||
strncpy(h5->fileinfo->propattr.text,text,NCPROPS_LENGTH);
|
||||
h5->fileinfo->propattr.text[NCPROPS_LENGTH-1] = '\0';
|
||||
ncstat = NC4_properties_parse(&h5->fileinfo->propattr);
|
||||
herr = 0;
|
||||
}
|
||||
done:
|
||||
if(attid >= 0) HCHECK((H5Aclose(attid)));
|
||||
if(aspace >= 0) HCHECK((H5Sclose(aspace)));
|
||||
if(ntype >= 0) HCHECK((H5Tclose(ntype)));
|
||||
if(atype >= 0) HCHECK((H5Tclose(atype)));
|
||||
return ncstat;
|
||||
}
|
||||
|
||||
int
|
||||
NC4_put_propattr(NC_HDF5_FILE_INFO_T* h5)
|
||||
{
|
||||
int ncstat = NC_NOERR;
|
||||
char text[NCPROPS_LENGTH+1];
|
||||
H5T_class_t t_class;
|
||||
size_t size;
|
||||
hid_t grp = -1;
|
||||
hid_t exists = -1;
|
||||
hid_t attid = -1;
|
||||
hid_t aspace = -1;
|
||||
hid_t atype = -1;
|
||||
herr_t herr = 0;
|
||||
|
||||
/* Get root group */
|
||||
grp = h5->root_grp->hdf_grpid; /* get root group */
|
||||
/* See if the NCPROPS attribute exists */
|
||||
exists = H5Aopen_name(grp, NCPROPS);
|
||||
if(exists < 0) {/* Does not exist */
|
||||
herr = -1;
|
||||
/* Create a datatype to refer to. */
|
||||
HCHECK((atype = H5Tcopy(H5T_C_S1)));
|
||||
HCHECK((H5Tset_cset(atype, H5T_CSET_UTF8)));
|
||||
HCHECK((H5Tset_size(atype, NCPROPS_LENGTH)));
|
||||
HCHECK((aspace = H5Screate(H5S_SCALAR)));
|
||||
HCHECK((attid = H5Acreate(grp, NCPROPS, atype, aspace, H5P_DEFAULT)));
|
||||
HCHECK((H5Awrite(attid, atype, h5->fileinfo->propattr.text)));
|
||||
herr = 0;
|
||||
}
|
||||
done:
|
||||
if(exists >= 0) HCHECK((H5Aclose(exists)));
|
||||
if(attid >= 0) HCHECK((H5Aclose(attid)));
|
||||
if(aspace >= 0) HCHECK((H5Sclose(aspace)));
|
||||
if(atype >= 0) HCHECK((H5Tclose(atype)));
|
||||
return ncstat;
|
||||
}
|
||||
|
||||
int
|
||||
NC4_get_fileinfo(NC_HDF5_FILE_INFO_T* h5, struct NCPROPINFO* init)
|
||||
{
|
||||
int ncstat = NC_NOERR;
|
||||
|
||||
/* Allocate the fileinfo in h5 */
|
||||
h5->fileinfo = (struct NCFILEINFO*)calloc(1,sizeof(struct NCFILEINFO));
|
||||
if(h5->fileinfo == NULL)
|
||||
{ncstat = NC_ENOMEM; goto done;}
|
||||
|
||||
/* Get superblock version */
|
||||
NCHECK((ncstat = NC4_hdf5get_superblock(h5,&h5->fileinfo->superblockversion)));
|
||||
/* Get properties attribute if not already defined */
|
||||
if(init == NULL) {
|
||||
NCHECK((ncstat = NC4_get_propattr(h5)));
|
||||
} else { /*init != NULL*/
|
||||
h5->fileinfo->propattr = *init; /* Initialize */
|
||||
}
|
||||
done:
|
||||
return ncstat;
|
||||
}
|
@ -45,7 +45,7 @@ int nc_log_level = -1;
|
||||
|
||||
#endif /* LOGGING */
|
||||
|
||||
static int nc4_hdf5_initialized = 0;
|
||||
int nc4_hdf5_initialized = 0;
|
||||
|
||||
/*
|
||||
Provide a function to do any necessary initialization
|
||||
@ -544,12 +544,13 @@ nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum,
|
||||
|
||||
/* Now find the attribute by name or number. If a name is provided,
|
||||
* ignore the attnum. */
|
||||
for (*att = attlist; *att; *att = (*att)->l.next) {
|
||||
if (name && (*att)->name && !strcmp((*att)->name, name))
|
||||
return NC_NOERR;
|
||||
if (!name && (*att)->attnum == attnum)
|
||||
return NC_NOERR;
|
||||
}
|
||||
if(attlist)
|
||||
for (*att = attlist; *att; *att = (*att)->l.next) {
|
||||
if (name && (*att)->name && !strcmp((*att)->name, name))
|
||||
return NC_NOERR;
|
||||
if (!name && (*att)->attnum == attnum)
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/* If we get here, we couldn't find the attribute. */
|
||||
return NC_ENOTATT;
|
||||
|
@ -1474,10 +1474,7 @@ nc4_get_hdf4_vara(NC *nc, int ncid, int varid, const size_t *startp,
|
||||
NC_VAR_INFO_T *var;
|
||||
int32 start32[NC_MAX_VAR_DIMS], edge32[NC_MAX_VAR_DIMS];
|
||||
int retval, d;
|
||||
#if 0
|
||||
NC_GRP_INFO_T *g;
|
||||
NC_DIM_INFO_T *dim;
|
||||
#endif
|
||||
|
||||
/* Find our metadata for this file, group, and var. */
|
||||
assert(nc);
|
||||
if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var)))
|
||||
|
@ -1,34 +1,33 @@
|
||||
# Test c output
|
||||
T=t
|
||||
T=tst_small
|
||||
#CMD=valgrind --leak-check=full
|
||||
CMD=gdb --args
|
||||
|
||||
#CMD=gdb --args
|
||||
#PAR=1
|
||||
|
||||
CFLAGS=-Wall -Wno-unused-variable -Wno-unused-function -g -O0 -I.. -I../include
|
||||
|
||||
ifdef PAR
|
||||
CC=mpicc
|
||||
|
||||
CFLAGS=-g -O0 -I.. -I../include
|
||||
#CC=/usr/local/bin/mpicc
|
||||
LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lcurl -lpnetcdf -lmpich -lm
|
||||
else
|
||||
CC=gcc
|
||||
#LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -lm -lcurl
|
||||
|
||||
LDFLAGS=-L/usr/local/lib -lhdf5_hl -lhdf5 -lz ../liblib/.libs/libnetcdf.a -ldl -lm -lcurl
|
||||
|
||||
CC=/usr/local/bin/mpicc
|
||||
LDFLAGS=-L/usr/local/lib -lhdf5_hl -lhdf5 -lz ../liblib/.libs/libnetcdf.a -ldl -lcurl -lpnetcdf -lmpich -lm
|
||||
LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lm -lcurl
|
||||
endif
|
||||
|
||||
# cd .. ; ${MAKE} all
|
||||
|
||||
LLP=/usr/local/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
all::
|
||||
echo ${LD_RUN_PATH}
|
||||
all:: cmp
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CC} -o t ${CFLAGS} ${T}.c ${LDFLAGS}; \
|
||||
${CMD} ./t
|
||||
|
||||
cmp::
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CC} -o t ${CFLAGS} ${T}.c ${SRC} ${LDFLAGS}; \
|
||||
|
||||
cpp::
|
||||
${CC} -E ${CFLAGS} ${T}.c > ${T}.txt
|
||||
|
||||
all::
|
||||
echo ${LD_RUN_PATH}
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
gcc -o t ${CFLAGS} ${T}.c ${LDFLAGS}; \
|
||||
${CMD} ./t
|
||||
|
@ -1,31 +1,33 @@
|
||||
# Test c output
|
||||
T=tst_mode
|
||||
T=tst_chunk_hdf4
|
||||
#CMD=valgrind --leak-check=full
|
||||
CMD=gdb --args
|
||||
|
||||
PAR=1
|
||||
#PAR=1
|
||||
|
||||
CFLAGS=-g -O0 -I.. -I../include
|
||||
CFLAGS=-Wall -Wno-unused-variable -Wno-unused-function -g -O0 -I.. -I../include
|
||||
|
||||
ifdef PAR
|
||||
CC=mpicc
|
||||
#CC=/usr/local/bin/mpicc
|
||||
LDFLAGS=-L/usr/local/lib -lhdf5_hl -lhdf5 -lz ../liblib/.libs/libnetcdf.a -ldl -lcurl -lpnetcdf -lmpich -lm
|
||||
LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lcurl -lpnetcdf -lmpich -lm
|
||||
else
|
||||
CC=gcc
|
||||
#LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -lm -lcurl
|
||||
LDFLAGS=-L/usr/local/lib -lhdf5_hl -lhdf5 -lz ../liblib/.libs/libnetcdf.a -ldl -lm -lcurl
|
||||
LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lm -lcurl
|
||||
endif
|
||||
|
||||
# cd .. ; ${MAKE} all
|
||||
|
||||
LLP=/usr/local/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
all::
|
||||
echo ${LD_RUN_PATH}
|
||||
all:: cmp
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CC} -o t ${CFLAGS} ${T}.c ${LDFLAGS}; \
|
||||
${CMD} ./t
|
||||
|
||||
cmp::
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CC} -o t ${CFLAGS} ${T}.c ${SRC} ${LDFLAGS}; \
|
||||
|
||||
cpp::
|
||||
${CC} -E ${CFLAGS} ${T}.c > ${T}.txt
|
||||
|
@ -23,12 +23,15 @@ echo "* Testing Empty Ragged Arrays (VLEN)"
|
||||
echo "Generating test netcdf files."
|
||||
./tst_empty_vlen_unlim
|
||||
|
||||
echo "Validating Files with ncdump."
|
||||
echo "======================================"
|
||||
../ncdump/ncdump -s tst_empty_vlen_unlim.nc
|
||||
echo "---------------------------------------"
|
||||
../ncdump/ncdump -s tst_empty_vlen_lim.nc
|
||||
echo "======================================"
|
||||
# Since no comparison is made, I am not sure
|
||||
# if this is useful.
|
||||
#echo "Validating Files with ncdump."
|
||||
#echo "======================================"
|
||||
#../ncdump/ncdump -s tst_empty_vlen_unlim.nc
|
||||
#echo "---------------------------------------"
|
||||
#../ncdump/ncdump -s tst_empty_vlen_lim.nc
|
||||
#echo "======================================"
|
||||
|
||||
|
||||
echo "* Tests Passed."
|
||||
exit 0
|
||||
|
@ -59,6 +59,12 @@ IF(ENABLE_TESTS)
|
||||
TARGET_LINK_LIBRARIES(bom netcdf)
|
||||
TARGET_LINK_LIBRARIES(tst_dimsizes netcdf)
|
||||
|
||||
IF(ENABLE_PROPERTIES_ATTRIBUTE)
|
||||
ADD_EXECUTABLE(tst_fileinfo tst_fileinfo.c)
|
||||
TARGET_LINK_LIBRARIES(tst_fileinfo netcdf)
|
||||
add_sh_test(ncdump tst_fileinfo)
|
||||
ENDIF()
|
||||
|
||||
IF(MSVC)
|
||||
SET_TARGET_PROPERTIES(rewrite-scalar PROPERTIES RUNTIME_OUTPUT_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
@ -80,6 +86,8 @@ IF(MSVC)
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
SET_TARGET_PROPERTIES(tst_dimsizes PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
SET_TARGET_PROPERTIES(tst_fileinfo PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
ENDIF()
|
||||
|
||||
# Base tests
|
||||
@ -96,7 +104,6 @@ ENDIF()
|
||||
add_sh_test(ncdump tst_lengths)
|
||||
add_sh_test(ncdump tst_calendars)
|
||||
add_bin_test(ncdump tst_utf8)
|
||||
|
||||
add_sh_test(ncdump run_utf8_tests)
|
||||
IF(USE_NETCDF4)
|
||||
add_sh_test(ncdump run_utf8_nc4_tests)
|
||||
|
37
ncdump/Make0
37
ncdump/Make0
@ -1,24 +1,33 @@
|
||||
# Test c output
|
||||
T=tst_dimsizes
|
||||
T=tst_fileinfo
|
||||
#CMD=valgrind --leak-check=full
|
||||
#CMD=gdb --args
|
||||
CMD=gdb --args
|
||||
|
||||
#MPI=1
|
||||
LLP="LD_LIBRARY_PATH=/usr/local/lib"
|
||||
#PAR=1
|
||||
|
||||
ifndef MPI
|
||||
CC=gcc
|
||||
CFLAGS=-g -O0 -I.. -I../include
|
||||
LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -lm -lcurl
|
||||
CFLAGS=-Wall -g -O0 -I.. -I../include
|
||||
|
||||
ifdef PAR
|
||||
CC=mpicc
|
||||
#CC=/usr/local/bin/mpicc
|
||||
LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lcurl -lpnetcdf -lmpich -lm
|
||||
else
|
||||
CC=/usr/local/bin/mpicc
|
||||
LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz ../liblib/.libs/libnetcdf.a -ldl -lcurl -lpnetcdf -lmpich -lm
|
||||
CC=gcc
|
||||
#LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -lm -lcurl
|
||||
LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lm -lcurl
|
||||
endif
|
||||
|
||||
all::
|
||||
export ${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CC} -o $T.exe ${CFLAGS} ${T}.c ${LDFLAGS}; \
|
||||
${CMD} ./$T.exe
|
||||
# cd .. ; ${MAKE} all
|
||||
|
||||
LLP=/usr/local/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
all:: cmp
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CMD} ./t
|
||||
|
||||
cmp::
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CC} -o t ${CFLAGS} ${T}.c ${SRC} ${LDFLAGS}; \
|
||||
|
||||
cpp::
|
||||
${CC} -E ${CFLAGS} ${T}.c > ${T}.txt
|
||||
|
@ -29,11 +29,17 @@ if BUILD_TESTSETS
|
||||
#if !BUILD_DLL
|
||||
# These tests are run for both netCDF-4 and non-netCDF-4 builds.
|
||||
check_PROGRAMS = rewrite-scalar ctest ctest64 ncdump tst_utf8 bom tst_dimsizes
|
||||
|
||||
TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh ctest ctest64 tst_output.sh \
|
||||
tst_lengths.sh tst_calendars.sh tst_utf8 run_utf8_tests.sh \
|
||||
tst_nccopy3.sh tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh \
|
||||
tst_dimsizes.sh
|
||||
|
||||
if ENABLE_FILEINFO
|
||||
check_PROGRAMS += tst_fileinfo
|
||||
TESTS += tst_fileinfo.sh
|
||||
endif
|
||||
|
||||
if LARGE_FILE_TESTS
|
||||
TESTS += tst_iter.sh
|
||||
endif
|
||||
@ -114,7 +120,8 @@ tst_nc_test_netcdf4_4_0.cdl tst_mud4.nc tst_mud4.cdl tst_mud4-bc.cdl \
|
||||
tst_ncf213.cdl tst_ncf213.nc tst_h_scalar.cdl tst_h_scalar.nc \
|
||||
tst_mud4_chars.cdl tst_mud4_chars.nc \
|
||||
inttags.nc inttags4.nc tst_inttags.cdl tst_inttags4.cdl \
|
||||
tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc
|
||||
tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc \
|
||||
nc4_fileinfo.nc hdf5_fileinfo.hdf
|
||||
|
||||
# These files all have to be included with the distribution.
|
||||
EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \
|
||||
@ -142,7 +149,7 @@ run_utf8_nc4_tests.sh \
|
||||
tst_formatx3.sh tst_formatx4.sh ref_tst_utf8_4.cdl \
|
||||
tst_inttags.sh tst_inttags4.sh \
|
||||
CMakeLists.txt XGetopt.c tst_bom.sh tst_inmemory_nc3.sh \
|
||||
tst_dimsizes.sh tst_inmemory_nc4.sh
|
||||
tst_dimsizes.sh tst_inmemory_nc4.sh tst_fileinfo.sh
|
||||
|
||||
# CDL files and Expected results
|
||||
SUBDIRS=cdl expected
|
||||
|
@ -17,5 +17,6 @@
|
||||
#define NC_ATT_SHUFFLE "_Shuffle"
|
||||
#define NC_ATT_STORAGE "_Storage"
|
||||
#define NC_ATT_NOFILL "_NoFill"
|
||||
#define NC_ATT_NETCDF4 "_NetCDF4"
|
||||
|
||||
#endif /*_CDL_H_ */
|
||||
|
@ -37,8 +37,8 @@ typedef int ssize_t;
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif /* HAVE_LOCALE_H */
|
||||
#include <netcdf.h>
|
||||
#include <netcdf_mem.h>
|
||||
#include "netcdf.h"
|
||||
#include "netcdf_mem.h"
|
||||
#include "utils.h"
|
||||
#include "nccomps.h"
|
||||
#include "nctime0.h" /* new iso time and calendar stuff */
|
||||
@ -48,6 +48,7 @@ typedef int ssize_t;
|
||||
#include "indent.h"
|
||||
#include "isnan.h"
|
||||
#include "cdl.h"
|
||||
#include "nc4internal.h" /* to get name of the special properties file */
|
||||
|
||||
#define XML_VERSION "1.0"
|
||||
|
||||
@ -116,6 +117,7 @@ usage(void)
|
||||
[-g grp1[,...]] Data and metadata for group(s) <grp1>,... only\n\
|
||||
[-w] With client-side caching of variables for DAP URLs\n\
|
||||
[-x] Output XML (NcML) instead of CDL\n\
|
||||
[-Xp] Unconditionally suppress output of the properties attribute\n\
|
||||
file Name of netCDF file (or URL if DAP access enabled)\n"
|
||||
|
||||
(void) fprintf(stderr,
|
||||
@ -757,6 +759,10 @@ pr_att(
|
||||
ncatt_t att; /* attribute */
|
||||
|
||||
NC_CHECK( nc_inq_attname(ncid, varid, ia, att.name) );
|
||||
if (ncid == getrootid(ncid)
|
||||
&& varid == NC_GLOBAL
|
||||
&& strcmp(att.name,NCPROPS)==0)
|
||||
return; /* will be printed elsewere */
|
||||
NC_CHECK( nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );
|
||||
att.tinfo = get_typeinfo(att.type);
|
||||
|
||||
@ -952,7 +958,6 @@ pr_att_global_format(
|
||||
printf (" ;\n");
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_NETCDF4
|
||||
/*
|
||||
* Print special reserved variable attributes, such as _Chunking,
|
||||
@ -1054,6 +1059,7 @@ pr_att_specials(
|
||||
printf(" = \"true\" ;\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: handle _Nbit when inquire function is available */
|
||||
|
||||
/* TODO: handle _ScaleOffset when inquire is available */
|
||||
@ -1062,6 +1068,54 @@ pr_att_specials(
|
||||
}
|
||||
#endif /* USE_NETCDF4 */
|
||||
|
||||
#ifdef ENABLE_FILEINFO /*=>NETCDF4*/
|
||||
static void
|
||||
pr_att_hidden(
|
||||
int ncid,
|
||||
int kind
|
||||
)
|
||||
{
|
||||
int stat;
|
||||
size_t len;
|
||||
char propdata[NCPROPS_LENGTH];
|
||||
|
||||
/* No special variable attributes for classic or 64-bit offset data */
|
||||
if(kind == 1 || kind == 2)
|
||||
return;
|
||||
/* Print out Selected hidden attributes */
|
||||
/* NCPROPS */
|
||||
stat = nc_inq_att(ncid,NC_GLOBAL,NCPROPS,NULL,&len);
|
||||
if(stat == NC_NOERR && len < sizeof(propdata)) {
|
||||
stat = nc_get_att_text(ncid,NC_GLOBAL,NCPROPS,propdata);
|
||||
if(stat == NC_NOERR) {
|
||||
pr_att_name(ncid, "", NCPROPS);
|
||||
/* make sure its null terminated */
|
||||
propdata[NCPROPS_LENGTH-1] = '\0';
|
||||
printf(" = \"%s\" ;\n",propdata);
|
||||
}
|
||||
}
|
||||
/* _SuperblockVersion */
|
||||
stat = nc_inq_att(ncid,NC_GLOBAL,SUPERBLOCKATT,NULL,&len);
|
||||
if(stat == NC_NOERR && len == 1) {
|
||||
int sbversion;
|
||||
stat = nc_get_att_int(ncid,NC_GLOBAL,SUPERBLOCKATT,&sbversion);
|
||||
if(stat == NC_NOERR) {
|
||||
pr_att_name(ncid, "", SUPERBLOCKATT);
|
||||
printf(" = %d ;\n",sbversion);
|
||||
}
|
||||
}
|
||||
/* _IsNetcdf4 */
|
||||
stat = nc_inq_att(ncid,NC_GLOBAL,ISNETCDF4ATT,NULL,&len);
|
||||
if(stat == NC_NOERR && len == 1) {
|
||||
int isnc4;
|
||||
stat = nc_get_att_int(ncid,NC_GLOBAL,ISNETCDF4ATT,&isnc4);
|
||||
if(stat == NC_NOERR) {
|
||||
pr_att_name(ncid, "", ISNETCDF4ATT);
|
||||
printf(" = %d ;\n",isnc4?1:0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_FILEINFO */
|
||||
|
||||
/*
|
||||
* Print a variable attribute for NcML
|
||||
@ -1078,6 +1132,13 @@ pr_attx(
|
||||
int attvalslen = 0;
|
||||
|
||||
NC_CHECK( nc_inq_attname(ncid, varid, ia, att.name) );
|
||||
if (ncid == getrootid(ncid)
|
||||
&& varid == NC_GLOBAL
|
||||
&& strcmp(att.name,NCPROPS)==0
|
||||
&& (!formatting_specs.special_atts
|
||||
|| !formatting_specs.xopt_props)
|
||||
)
|
||||
return;
|
||||
NC_CHECK( nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );
|
||||
|
||||
/* Put attribute values into a single string, with blanks in between */
|
||||
@ -1325,8 +1386,11 @@ print_ud_type(int ncid, nc_type typeid) {
|
||||
printf(" ;\n");
|
||||
}
|
||||
indent_out();
|
||||
/* printf("}; // %s\n", type_name); */
|
||||
#if 0
|
||||
printf("}; // %s\n", type_name);
|
||||
#else
|
||||
printf("}; // ");
|
||||
#endif
|
||||
print_type_name(ncid, typeid);
|
||||
printf("\n");
|
||||
}
|
||||
@ -1666,7 +1730,6 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
#endif /* USE_NETCDF4 */
|
||||
}
|
||||
|
||||
/* get global attributes */
|
||||
if (ngatts > 0 || formatting_specs.special_atts) {
|
||||
printf ("\n");
|
||||
indent_out();
|
||||
@ -1680,9 +1743,12 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
}
|
||||
if (is_root && formatting_specs.special_atts) { /* output special attribute
|
||||
* for format variant */
|
||||
pr_att_hidden(ncid, kind);
|
||||
pr_att_global_format(ncid, kind);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
/* output variable data, unless "-h" option specified header only
|
||||
* or this group is not in list of groups specified by "-g"
|
||||
* option */
|
||||
@ -2019,6 +2085,7 @@ main(int argc, char *argv[])
|
||||
bool_t xml_out = false; /* if true, output NcML instead of CDL */
|
||||
bool_t kind_out = false; /* if true, just output kind of netCDF file */
|
||||
bool_t kind_out_extended = false; /* output inq_format vs inq_format_extended */
|
||||
int Xp_flag = 0; /* indicate that -Xp flag was set */
|
||||
|
||||
#if defined(WIN32) || defined(msdos) || defined(WIN64)
|
||||
putenv("PRINTF_EXPONENT_DIGITS=2"); /* Enforce unix/linux style exponent formatting. */
|
||||
@ -2132,6 +2199,9 @@ main(int argc, char *argv[])
|
||||
case 'm':
|
||||
formatting_specs.xopt_inmemory = 1;
|
||||
break;
|
||||
case 'p': /* suppress the properties attribute */
|
||||
Xp_flag = 1; /* record that this flag was set */
|
||||
break;
|
||||
default:
|
||||
error("invalid value for -X option: %s", optarg);
|
||||
break;
|
||||
@ -2142,6 +2212,16 @@ main(int argc, char *argv[])
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Decide xopt_props */
|
||||
if(formatting_specs.special_atts && Xp_flag == 1)
|
||||
formatting_specs.xopt_props = 0;
|
||||
else if(formatting_specs.special_atts && Xp_flag == 0)
|
||||
formatting_specs.xopt_props = 1;
|
||||
else if(!formatting_specs.special_atts)
|
||||
formatting_specs.xopt_props = 0;
|
||||
else
|
||||
formatting_specs.xopt_props = 0;
|
||||
|
||||
set_max_len(max_len);
|
||||
|
||||
argc -= optind;
|
||||
|
@ -43,7 +43,7 @@ typedef struct { /* specification for how to format dump */
|
||||
* for optimization characteristics:
|
||||
* _Compression, _Chunking,
|
||||
* _Endianness, _Format, _Checksum,
|
||||
* _NoFill */
|
||||
* _NoFill, _NetCDF4 */
|
||||
|
||||
Nclang data_lang; /* Specifies index conventions used in data
|
||||
* comments, either LANG_C (C, 0-based,
|
||||
@ -78,6 +78,7 @@ typedef struct { /* specification for how to format dump */
|
||||
int nc_mode; /* mode as reported by inq_format_extended */
|
||||
|
||||
int xopt_inmemory; /* Use in-memory option; testing only */
|
||||
int xopt_props ; /* 1=>Unconditionally Suppress properties attribute */
|
||||
} fspec_t;
|
||||
|
||||
#endif /*_NCDUMP_H_ */
|
||||
|
@ -44,5 +44,8 @@ variables:
|
||||
var5:_NoFill = "true" ;
|
||||
|
||||
// global attributes:
|
||||
:_NCProperties = "version=1|netcdflibversion=0.0.0|hdf5libversion=0.0.0" ;
|
||||
:_SuperblockVersion = 0 ;
|
||||
:_IsNetcdf4 = 1 ;
|
||||
:_Format = "netCDF-4" ;
|
||||
}
|
||||
|
@ -45,6 +45,9 @@ variables:
|
||||
var5:_NoFill = "true" ;
|
||||
|
||||
// global attributes:
|
||||
:_NCProperties = "version=1|netcdflibversion=0.0.0|hdf5libversion=0.0.0" ;
|
||||
:_SuperblockVersion = 0 ;
|
||||
:_IsNetcdf4 = 1 ;
|
||||
:_Format = "netCDF-4" ;
|
||||
data:
|
||||
}
|
||||
|
157
ncdump/tst_fileinfo.c
Normal file
157
ncdump/tst_fileinfo.c
Normal file
@ -0,0 +1,157 @@
|
||||
/* This is part of the netCDF package. Copyright 2008 University
|
||||
Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
|
||||
conditions of use. See www.unidata.ucar.edu for more info.
|
||||
*/
|
||||
|
||||
/*
|
||||
Test _NCProperties and other special attributes
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include "unistd.h"
|
||||
#endif
|
||||
|
||||
#include <hdf5.h>
|
||||
#include "nc_tests.h"
|
||||
#include "netcdf.h"
|
||||
#include "nc4internal.h"
|
||||
|
||||
#define NC4FILE "nc4_fileinfo.nc"
|
||||
#define HDFFILE "hdf5_fileinfo.hdf"
|
||||
#define INT_ATT_NAME "int_attr"
|
||||
#define INT_VAR_NAME "int_var"
|
||||
#define GROUPNAME "subgroup"
|
||||
#define DIMNAME "time"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
printf("\n*** Testing 'Fileinfo attributes.\n");
|
||||
|
||||
{
|
||||
hid_t fileid;
|
||||
hid_t fcplid;
|
||||
hid_t scalar_spaceid;
|
||||
|
||||
printf("*** creating test file using HDF5 directly %s...", HDFFILE);
|
||||
|
||||
/* Create scalar dataspace */
|
||||
if((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR;
|
||||
|
||||
/* Set creation ordering for file, so we can revise its contents later */
|
||||
if((fcplid = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
|
||||
if(H5Pset_link_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;
|
||||
if(H5Pset_attr_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;
|
||||
|
||||
/* Create new file, using default properties */
|
||||
if((fileid = H5Fcreate(HDFFILE, H5F_ACC_TRUNC, fcplid, H5P_DEFAULT)) < 0) ERR;
|
||||
/* Close file creation property list */
|
||||
if(H5Pclose(fcplid) < 0) ERR;
|
||||
|
||||
/* Add attributes to root group */
|
||||
{
|
||||
hid_t scalar_spaceid = -1;
|
||||
hid_t attid = -1;
|
||||
|
||||
/* Create scalar dataspace */
|
||||
if((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR;
|
||||
|
||||
/* Create attribute with native integer datatype on object */
|
||||
if((attid = H5Acreate2(fileid, INT_ATT_NAME, H5T_NATIVE_INT, scalar_spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
|
||||
if(H5Aclose(attid) < 0) ERR;
|
||||
|
||||
/* Clean up objects created */
|
||||
if(H5Sclose(scalar_spaceid) < 0) ERR;
|
||||
}
|
||||
|
||||
/* Close rest */
|
||||
if(H5Sclose(scalar_spaceid) < 0) ERR;
|
||||
if(H5Fclose(fileid) < 0) ERR;
|
||||
}
|
||||
|
||||
{
|
||||
int root, grpid, varid, stat, natts;
|
||||
int data = 17;
|
||||
const char* sdata = "text";
|
||||
char ncprops[8192];
|
||||
size_t len;
|
||||
int dimid;
|
||||
|
||||
printf("*** creating netcdf-4 test file using netCDF %s...", NC4FILE);
|
||||
|
||||
if(nc_create(NC4FILE,NC_WRITE|NC_CLOBBER|NC_NETCDF4,&root)!=0) ERR;
|
||||
/* Create global attribute */
|
||||
if(nc_put_att_int(root,NC_GLOBAL,INT_ATT_NAME,NC_INT,1,&data)!=0) ERR;
|
||||
/* Create global variable */
|
||||
if(nc_def_var(root,INT_VAR_NAME,NC_INT,0,NULL,&varid)!=0) ERR;
|
||||
/* Create attribute on var */
|
||||
if(nc_put_att_int(root,varid,INT_ATT_NAME,NC_INT,1,&data)!=0) ERR;
|
||||
/* Create global subgroup */
|
||||
if(nc_def_grp(root,GROUPNAME,&grpid)!=0) ERR;
|
||||
/* Create global attribute in the group */
|
||||
if(nc_put_att_int(grpid,NC_GLOBAL,INT_ATT_NAME,NC_INT,1,&data)!=0) ERR;
|
||||
/* Create _NCProperties as var attr and as subgroup attribute */
|
||||
if(nc_put_att_text(grpid,NC_GLOBAL,NCPROPS,strlen(sdata),sdata)!=0) ERR;
|
||||
if(nc_put_att_text(root,varid,NCPROPS,strlen(sdata),sdata)!=0) ERR;
|
||||
/* Create var + dimension to cause e.g. dimscales to appear */
|
||||
if(nc_def_dim(root,DIMNAME,(size_t)4,&dimid)!=0) ERR;
|
||||
if(nc_def_var(root,DIMNAME,NC_INT,1,&dimid,&varid)!=0) ERR; /* same name */
|
||||
/* Close, then re-open */
|
||||
if(nc_close(root)) ERR;
|
||||
if(nc_open(NC4FILE,NC_WRITE|NC_NETCDF4,&root)!=0) ERR;
|
||||
|
||||
/* Is all invisible attributes actually invisible vis-a-vis nc_inq? */
|
||||
if(nc_inq(root,NULL,NULL,&natts,NULL)!=0) ERR;
|
||||
if(natts != 1) ERR;
|
||||
|
||||
/* Now, fiddle with the NCPROPS attribute */
|
||||
|
||||
/* Get its value */
|
||||
if(nc_inq_att(root,NC_GLOBAL,NCPROPS,NULL,&len)!=0) ERR;
|
||||
if(nc_get_att_text(root,NC_GLOBAL,NCPROPS,ncprops)!=0) ERR;
|
||||
|
||||
/*Overwrite _NCProperties root attribute; should fail */
|
||||
stat = nc_put_att_text(root,NC_GLOBAL,NCPROPS,strlen(sdata),sdata);
|
||||
if(stat == NC_NOERR) ERR;
|
||||
|
||||
/* Delete; should fail */
|
||||
stat = nc_del_att(root,NC_GLOBAL,NCPROPS);
|
||||
if(stat != NC_ENOTATT) ERR;
|
||||
|
||||
/* Ditto _SuperblockVersion */
|
||||
|
||||
/* Get its value */
|
||||
if(nc_inq_att(root,NC_GLOBAL,SUPERBLOCKATT,NULL,&len)!=0) ERR;
|
||||
if(len != 1) ERR;
|
||||
if(nc_get_att_int(root,NC_GLOBAL,SUPERBLOCKATT,&data)!=0) ERR;
|
||||
|
||||
/*Overwrite; should fail */
|
||||
stat = nc_put_att_int(root,NC_GLOBAL,NCPROPS,NC_INT,1,&data);
|
||||
if(stat == NC_NOERR) ERR;
|
||||
|
||||
/* Delete; should fail */
|
||||
stat = nc_del_att(root,NC_GLOBAL,SUPERBLOCKATT);
|
||||
if(stat == NC_NOERR) ERR;
|
||||
|
||||
/* Ditto _IsNetcdf4 */
|
||||
|
||||
/* Get its value */
|
||||
if(nc_inq_att(root,NC_GLOBAL,ISNETCDF4ATT,NULL,&len)!=0) ERR;
|
||||
if(len != 1) ERR;
|
||||
if(nc_get_att_int(root,NC_GLOBAL,ISNETCDF4ATT,&data)!=0) ERR;
|
||||
|
||||
/*Overwrite; should fail */
|
||||
stat = nc_put_att_int(root,NC_GLOBAL,ISNETCDF4ATT,NC_INT,1,&data);
|
||||
if(stat == NC_NOERR) ERR;
|
||||
|
||||
/* Delete; should fail */
|
||||
stat = nc_del_att(root,NC_GLOBAL,ISNETCDF4ATT);
|
||||
if(stat == NC_NOERR) ERR;
|
||||
|
||||
if(nc_close(root)!=0) ERR;
|
||||
}
|
||||
|
||||
SUMMARIZE_ERR;
|
||||
FINAL_RESULTS;
|
||||
}
|
59
ncdump/tst_fileinfo.sh
Executable file
59
ncdump/tst_fileinfo.sh
Executable file
@ -0,0 +1,59 @@
|
||||
#!/bin/sh
|
||||
if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
|
||||
set -e
|
||||
echo ""
|
||||
|
||||
if test "x$builddir" = "x"; then builddir=`pwd`; fi
|
||||
if test "x$srcdir" = "x"; then srcdir=`dirname $0`; fi
|
||||
|
||||
# Make buildir absolute
|
||||
cd $builddir
|
||||
builddir=`pwd`
|
||||
|
||||
# Make srcdir be absolute
|
||||
cd $srcdir
|
||||
srcdir=`pwd`
|
||||
|
||||
cd $builddir
|
||||
|
||||
export verbose
|
||||
export srcdir
|
||||
export builddir
|
||||
|
||||
EXIT=0
|
||||
|
||||
NCF=$srcdir/nc4_fileinfo.nc
|
||||
HDF=$srcdir/hdf5_fileinfo.hdf
|
||||
NF=ref_tst_compounds4.nc
|
||||
|
||||
# Do a false negative test
|
||||
rm -f ./tmp
|
||||
if $builddir/ncdump -s $builddir/$NF | fgrep '_IsNetcdf4 = 0' > ./tmp ; then
|
||||
echo "Pass: False negative for file: $NF"
|
||||
else
|
||||
echo "FAIL: False negative for file: $NF"
|
||||
fi
|
||||
rm -f ./tmp
|
||||
|
||||
if ./tst_fileinfo > /dev/null ; then
|
||||
# look at the _IsNetcdf4 flag
|
||||
N_IS=`${builddir}/ncdump -s $NCF | fgrep '_IsNetcdf4' | tr -d ' ;'`
|
||||
N_IS=`echo $N_IS | cut -d= -f2`
|
||||
H_IS=`${builddir}/ncdump -s $HDF | fgrep '_IsNetcdf4' | tr -d ' ;'`
|
||||
H_IS=`echo $H_IS | cut -d= -f2`
|
||||
if test "x$N_IS" = 'x0' ;then
|
||||
echo "FAIL: $NCF is marked as not netcdf-4"
|
||||
fi
|
||||
if test "x$H_IS" = 'x1' ;then
|
||||
echo "FAIL: $HDF is marked as netcdf-4"
|
||||
fi
|
||||
else
|
||||
echo "FAIL: tst_fileinfo"
|
||||
EXIT=1
|
||||
fi
|
||||
|
||||
rm -f $NCF
|
||||
rm -f $HDF
|
||||
|
||||
exit $EXIT
|
||||
|
@ -1,5 +1,21 @@
|
||||
#!/bin/sh
|
||||
if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
|
||||
|
||||
if test "x$srcdir" = x ; then
|
||||
srcdir=`pwd`
|
||||
fi
|
||||
|
||||
# It is unreasonable to test actual lengths of files
|
||||
# (even netcdf-3 files).
|
||||
#However, the files created in this script are used in later ones
|
||||
|
||||
../ncgen/ncgen -b ${srcdir}/small.cdl
|
||||
../ncgen/ncgen -b ${srcdir}/small2.cdl
|
||||
|
||||
exit
|
||||
|
||||
|
||||
|
||||
# This shell script tests lengths of small netcdf files and tests
|
||||
# that rewriting a numeric value doesn't change file length
|
||||
# $Id: tst_lengths.sh,v 1.10 2008/08/07 00:07:52 ed Exp $
|
||||
@ -34,9 +50,6 @@ if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
|
||||
# echo "netcdf small {variables: byte t; data: t = 1;}" > small.cdl
|
||||
set -e
|
||||
|
||||
if test "x$srcdir" = x ; then
|
||||
srcdir=`pwd`
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "*** testing length of classic file"
|
||||
|
@ -82,7 +82,12 @@ if test -f ./tst_unicode -o -f ./tst_unicode.exe ; then
|
||||
#diff -b tst_unicode.cdl $srcdir/ref_tst_unicode.cdl
|
||||
fi
|
||||
./tst_special_atts
|
||||
./ncdump -c -s tst_special_atts.nc | sed 's/e+0/e+/g' > tst_special_atts.cdl
|
||||
./ncdump -c -s tst_special_atts.nc \
|
||||
| sed 's/e+0/e+/g' \
|
||||
| sed -e 's/netcdflibversion=.*[|]/netcdflibversion=0.0.0|/' \
|
||||
| sed -e 's/hdf5libversion=.*"/hdf5libversion=0.0.0"/' \
|
||||
| sed -e 's|_SuperblockVersion = [0-9]|_SuperblockVersion = 0|' \
|
||||
| cat > tst_special_atts.cdl
|
||||
echo "*** comparing tst_special_atts.cdl with ref_tst_special_atts.cdl..."
|
||||
diff -b tst_special_atts.cdl $srcdir/ref_tst_special_atts.cdl
|
||||
|
||||
|
@ -84,7 +84,11 @@ else # Non-MINGW Platforms
|
||||
# Exercise Jira NCF-213 bug fix
|
||||
# rm -f tst_ncf213.cdl tst_ncf213.nc
|
||||
../ncgen/ncgen -b -o tst_ncf213.nc $srcdir/ref_tst_ncf213.cdl
|
||||
./ncdump -s -h tst_ncf213.nc >tst_ncf213.cdl
|
||||
./ncdump -s -h tst_ncf213.nc \
|
||||
| sed -e 's/netcdflibversion=.*[|]/netcdflibversion=0.0.0|/' \
|
||||
| sed -e 's/hdf5libversion=.*"/hdf5libversion=0.0.0"/' \
|
||||
| sed -e 's|_SuperblockVersion = [0-9]|_SuperblockVersion = 0|' \
|
||||
| cat >tst_ncf213.cdl
|
||||
# Now compare
|
||||
ok=1;
|
||||
if diff -b $srcdir/ref_tst_ncf213.cdl tst_ncf213.cdl ; then ok=1; else ok=0; fi
|
||||
|
@ -745,3 +745,18 @@ nc_inq_grps_full(int rootid, int *numgrps, int *grpids)
|
||||
nc_free_giter(giter);
|
||||
return stat;
|
||||
}
|
||||
|
||||
int
|
||||
getrootid(int grpid)
|
||||
{
|
||||
int current = grpid;
|
||||
int parent = current;
|
||||
/* see if root id */
|
||||
for(;;) {
|
||||
int stat = nc_inq_grp_parent(current,&parent);
|
||||
if(stat) break;
|
||||
current = parent;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
|
@ -150,6 +150,7 @@ extern int nc_next_giter(ncgiter_t *iterp, int *grpid);
|
||||
* Release memory allocated for group iterator.
|
||||
*/
|
||||
extern void nc_free_giter(ncgiter_t *iterp);
|
||||
extern int getrootid(int grpid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ CLEANFILES = c0.nc c0_64.nc c0_4.nc c0_4c.nc ref_camrun.c \
|
||||
# autoconf will forcibly delete files of the name *.tab.*
|
||||
|
||||
makeparser::
|
||||
flex -L -Pncg -8 ncgen.l
|
||||
flex -Pncg -8 ncgen.l
|
||||
rm -f ncgenl.c
|
||||
sed -e s/lex.ncg.c/ncgenl.c/g <lex.ncg.c >ncgenl.c
|
||||
bison -pncg -t -d ncgen.y
|
||||
|
@ -177,9 +177,6 @@ void gen_charattr(Datalist*, Bytebuffer*);
|
||||
void gen_charvlen(Datalist*, Bytebuffer*);
|
||||
void gen_chararray(struct Dimset*, int, Datalist*, Bytebuffer*, Datalist* fillsrc);
|
||||
|
||||
/* Mnemonic */
|
||||
#define UNKNOWN ((size_t)0)
|
||||
|
||||
typedef enum ListClass {
|
||||
LISTDATA, LISTATTR, LISTVLEN, LISTCOMPOUND, LISTFIELDARRAY
|
||||
} ListClass;
|
||||
|
@ -414,7 +414,7 @@ genc_defineglobalspecials(void)
|
||||
if(usingclassic) return;
|
||||
if(!/*Main.*/format_attribute) return;
|
||||
/* Watch out, this is a global Attribute */
|
||||
format = kind_string(/*Main.*/format_flag);
|
||||
format = kind_string(globalspecials._Format);
|
||||
bbprintf0(stmt,"%sstat = nc_put_att_text(ncid, NC_GLOBAL, \"_Format\", 1, \"%s\");\n",
|
||||
indented(1),
|
||||
format);
|
||||
|
@ -152,7 +152,6 @@ extern void jflush(void);
|
||||
|
||||
/* from: main.c */
|
||||
extern int k_flag; /* -k value from command line*/
|
||||
extern int format_flag; /* _Format attribute value (same range as -k flag) */
|
||||
extern int format_attribute; /* 1 if format came from _FORMAT attribute */
|
||||
extern int enhanced_flag; /* 1 => netcdf-4 constructs appear in the parse */
|
||||
extern int cdf5_flag; /* 1 => cdf-5 unsigned types in the parse */
|
||||
@ -160,6 +159,7 @@ extern int specials_flag; /* 1 => special attributes are present */
|
||||
extern int usingclassic; /* 1 => k_flag == 1|2|5 */
|
||||
extern int k_flag;
|
||||
extern int ncloglevel;
|
||||
extern GlobalSpecialData globalspecials;
|
||||
|
||||
/* Global data */
|
||||
|
||||
@ -199,6 +199,6 @@ extern void* emalloc (size_t);
|
||||
extern void* ecalloc (size_t);
|
||||
extern void* erealloc(void*,size_t);
|
||||
|
||||
extern char* specialname(int flag);
|
||||
extern const char* specialname(int tag);
|
||||
|
||||
#endif /*!NC_GENLIB_H*/
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include "genlib.h"
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
#include "nc.h"
|
||||
#include "nc4internal.h"
|
||||
|
||||
extern int specialconstants;
|
||||
|
||||
|
@ -38,7 +38,6 @@ int header_only;
|
||||
|
||||
/* flags for tracking what output format to use */
|
||||
int k_flag; /* > 0 => -k was specified on command line*/
|
||||
int format_flag; /* _Format attribute value (same range as -k flag) */
|
||||
int format_attribute; /* 1=>format came from format attribute */
|
||||
int enhanced_flag; /* 1 => netcdf-4 */
|
||||
int cdf5_flag; /* 1 => cdf5 | maybe netcdf-4 */
|
||||
@ -48,6 +47,8 @@ int cmode_modifier;
|
||||
int diskless;
|
||||
int ncloglevel;
|
||||
|
||||
GlobalSpecialData globalspecials;
|
||||
|
||||
char* binary_ext = ".nc";
|
||||
|
||||
size_t nciterbuffersize;
|
||||
@ -231,7 +232,6 @@ main(
|
||||
nciterbuffersize = 0;
|
||||
|
||||
k_flag = 0;
|
||||
format_flag = 0;
|
||||
format_attribute = 0;
|
||||
enhanced_flag = 0;
|
||||
cdf5_flag = 0;
|
||||
@ -242,6 +242,7 @@ main(
|
||||
#else
|
||||
ncloglevel = -1;
|
||||
#endif
|
||||
memset(&globalspecials,0,sizeof(GlobalSpecialData));
|
||||
|
||||
#if _CRAYMPP && 0
|
||||
/* initialize CRAY MPP parallel-I/O library */
|
||||
@ -512,7 +513,7 @@ main(
|
||||
}
|
||||
|
||||
if(k_flag == 0)
|
||||
k_flag = format_flag;
|
||||
k_flag = globalspecials._Format;
|
||||
|
||||
if(cdf5_flag && !enhanced_flag && k_flag == 0)
|
||||
k_flag = 5;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright 1993, UCAR/Unidata
|
||||
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
||||
* $Header: /upc/share/CVS/netcdf-3/ncgen/ncgen.h,v 1.18 2010/06/01 15:34:53 ed Exp $
|
||||
*********************************************************************/
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <float.h>
|
||||
@ -71,7 +71,7 @@ typedef nc_type nc_subclass;
|
||||
|
||||
/*
|
||||
Define data structure
|
||||
to hold special attribute values
|
||||
xto hold special attribute values
|
||||
for a given variable.
|
||||
Global values are kept as
|
||||
various C global variables
|
||||
@ -79,6 +79,7 @@ various C global variables
|
||||
|
||||
/* Define a bit set for indicating which*/
|
||||
/* specials were explicitly specified*/
|
||||
/* See also: ncgen.y.tag2name */
|
||||
#define _STORAGE_FLAG 0x001
|
||||
#define _CHUNKSIZES_FLAG 0x002
|
||||
#define _FLETCHER32_FLAG 0x004
|
||||
@ -87,7 +88,16 @@ various C global variables
|
||||
#define _ENDIAN_FLAG 0x020
|
||||
#define _NOFILL_FLAG 0x040
|
||||
#define _FILLVALUE_FLAG 0x080
|
||||
#define _FORMAT_FLAG 0x100
|
||||
#define _NCPROPS_FLAG 0x100
|
||||
#define _ISNETCDF4_FLAG 0x200
|
||||
#define _SUPERBLOCK_FLAG 0x400
|
||||
#define _FORMAT_FLAG 0x800
|
||||
|
||||
extern struct Specialtoken {
|
||||
char* name;
|
||||
int token;
|
||||
int tag;
|
||||
} specials[];
|
||||
|
||||
/* Define an enumeration of supported languages */
|
||||
typedef enum Language {
|
||||
@ -120,6 +130,13 @@ typedef struct Specialdata {
|
||||
int _Fill ; /* 0 => false, 1 => true WATCHOUT: this is inverse of NOFILL*/
|
||||
} Specialdata;
|
||||
|
||||
typedef struct GlobalSpecialdata {
|
||||
int _Format ; /* kflag */
|
||||
const char* _NCProperties ;
|
||||
int _IsNetcdf4 ; /* 0 => false, 1 => true */
|
||||
int _Superblock ; /* HDF5 file superblock version */
|
||||
} GlobalSpecialData;
|
||||
|
||||
/* Track a set of dimensions*/
|
||||
/* (Note: the netcdf type system is deficient here)*/
|
||||
typedef struct Dimset {
|
||||
@ -143,7 +160,7 @@ typedef struct Typeinfo {
|
||||
nc_type typecode;
|
||||
unsigned long offset; /* fields in struct*/
|
||||
unsigned long alignment;/* fields in struct*/
|
||||
NCConstant econst; /* for enum values*/
|
||||
NCConstant econst; /* for enum values*/
|
||||
Dimset dimset; /* for NC_VAR/NC_FIELD/NC_ATT*/
|
||||
size_t size; /* for opaque, compound, etc.*/
|
||||
size_t nelems; /* size in terms of # of datalist constants
|
||||
|
@ -115,19 +115,19 @@ static int tagmatch(nc_type nct, int tag);
|
||||
static int nct2lexeme(nc_type nct);
|
||||
static int collecttag(char* text, char** stagp);
|
||||
|
||||
static struct Specialtoken {
|
||||
char* name;
|
||||
int token;
|
||||
} specials[] = {
|
||||
{"_FillValue",_FILLVALUE},
|
||||
{"_Format",_FORMAT},
|
||||
{"_Storage",_STORAGE},
|
||||
{"_ChunkSizes",_CHUNKSIZES},
|
||||
{"_Fletcher32",_FLETCHER32},
|
||||
{"_DeflateLevel",_DEFLATELEVEL},
|
||||
{"_Shuffle",_SHUFFLE},
|
||||
{"_Endianness",_ENDIANNESS},
|
||||
{"_NoFill",_NOFILL},
|
||||
struct Specialtoken specials[] = {
|
||||
{"_FillValue",_FILLVALUE,_FILLVALUE_FLAG},
|
||||
{"_Format",_FORMAT,_FORMAT_FLAG},
|
||||
{"_Storage",_STORAGE,_STORAGE_FLAG},
|
||||
{"_ChunkSizes",_CHUNKSIZES,_CHUNKSIZES_FLAG},
|
||||
{"_Fletcher32",_FLETCHER32,_FLETCHER32_FLAG},
|
||||
{"_DeflateLevel",_DEFLATELEVEL,_DEFLATE_FLAG},
|
||||
{"_Shuffle",_SHUFFLE,_SHUFFLE_FLAG},
|
||||
{"_Endianness",_ENDIANNESS,_ENDIAN_FLAG},
|
||||
{"_NoFill",_NOFILL,_NOFILL_FLAG},
|
||||
{"_NCProperties",_NCPROPS,_NCPROPS_FLAG},
|
||||
{"_IsNetcdf4",_ISNETCDF4,_ISNETCDF4_FLAG},
|
||||
{"_SuperblockVersion",_SUPERBLOCK,_SUPERBLOCK_FLAG},
|
||||
{NULL,0} /* null terminate */
|
||||
};
|
||||
|
||||
@ -206,7 +206,7 @@ NUMBER [+-]?[0-9][0-9]*[Uu]?([BbSs]|[Ll]|[Ll][Ll])?
|
||||
DBLNUMBER [+-]?[0-9]*\.[0-9]*{exp}?[LlDd]?|[+-]?[0-9]*{exp}[LlDd]?
|
||||
FLTNUMBER [+-]?[0-9]*\.[0-9]*{exp}?[Ff]|[+-]?[0-9]*{exp}[Ff]
|
||||
|
||||
SPECIAL "_FillValue"|"_Format"|"_Storage"|"_ChunkSizes"|"_Fletcher32"|"_DeflateLevel"|"_Shuffle"|"_Endianness"|"_NoFill"
|
||||
SPECIAL "_FillValue"|"_Format"|"_Storage"|"_ChunkSizes"|"_Fletcher32"|"_DeflateLevel"|"_Shuffle"|"_Endianness"|"_NoFill"|"_NCProperties"|"_IsNetcdf4"|"_SuperblockVersion"
|
||||
|
||||
USASCII [\x01-\x7F]
|
||||
|
||||
|
@ -69,6 +69,8 @@ char* primtypenames[PRIMNO] = {
|
||||
"string"
|
||||
};
|
||||
|
||||
static int GLOBAL_SPECIAL = _NCPROPS_FLAG | _ISNETCDF4_FLAG | _SUPERBLOCK_FLAG | _FORMAT_FLAG ;
|
||||
|
||||
/*Defined in ncgen.l*/
|
||||
extern int lineno; /* line number for error messages */
|
||||
extern Bytebuffer* lextext; /* name or string with escapes removed */
|
||||
@ -112,6 +114,7 @@ static Symbol* makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int
|
||||
static int containsfills(Datalist* list);
|
||||
static void datalistextend(Datalist* dl, NCConstant* con);
|
||||
static void vercheck(int ncid);
|
||||
static long long extractint(NCConstant con);
|
||||
|
||||
int yylex(void);
|
||||
|
||||
@ -185,6 +188,9 @@ NCConstant constant;
|
||||
_ENDIANNESS
|
||||
_NOFILL
|
||||
_FLETCHER32
|
||||
_NCPROPS
|
||||
_ISNETCDF4
|
||||
_SUPERBLOCK
|
||||
DATASETID
|
||||
|
||||
%type <sym> ident typename primtype dimd varspec
|
||||
@ -438,9 +444,9 @@ dimdeclist: dimdecl
|
||||
;
|
||||
|
||||
dimdecl:
|
||||
dimd '=' UINT64_CONST
|
||||
dimd '=' constint
|
||||
{
|
||||
$1->dim.declsize = (size_t)uint64_val;
|
||||
$1->dim.declsize = (size_t)extractint($3);
|
||||
#ifdef GENDEBUG1
|
||||
fprintf(stderr,"dimension: %s = %llu\n",$1->name,(unsigned long long)$1->dim.declsize);
|
||||
#endif
|
||||
@ -690,6 +696,12 @@ attrdecllist: /*empty*/ {} | attrdecl ';' attrdecllist {} ;
|
||||
attrdecl:
|
||||
':' ident '=' datalist
|
||||
{ $$=makeattribute($2,NULL,NULL,$4,ATTRGLOBAL);}
|
||||
| ':' _NCPROPS '=' conststring
|
||||
{$$ = makespecial(_NCPROPS_FLAG,NULL,NULL,(void*)&$4,ATTRGLOBAL);}
|
||||
| ':' _ISNETCDF4 '=' constbool
|
||||
{$$ = makespecial(_ISNETCDF4_FLAG,NULL,NULL,(void*)&$4,ATTRGLOBAL);}
|
||||
| ':' _SUPERBLOCK '=' constint
|
||||
{$$ = makespecial(_SUPERBLOCK_FLAG,NULL,NULL,(void*)&$4,ATTRGLOBAL);}
|
||||
| typeref type_var_ref ':' ident '=' datalist
|
||||
{Symbol* tsym = $1; Symbol* vsym = $2; Symbol* asym = $4;
|
||||
if(vsym->objectclass == NC_VAR) {
|
||||
@ -1099,24 +1111,6 @@ basetypefor(nc_type nctype)
|
||||
return primsymbols[nctype];
|
||||
}
|
||||
|
||||
char*
|
||||
specialname(int flag)
|
||||
{
|
||||
switch (flag) {
|
||||
case _FILLVALUE_FLAG: return "_FillValue";
|
||||
case _FORMAT_FLAG: return "_Format";
|
||||
case _STORAGE_FLAG: return "_Storage";
|
||||
case _CHUNKSIZES_FLAG: return "_ChunkSizes";
|
||||
case _FLETCHER32_FLAG: return "_Fletcher32";
|
||||
case _DEFLATE_FLAG: return "_DeflateLevel";
|
||||
case _SHUFFLE_FLAG: return "_Shuffle";
|
||||
case _ENDIAN_FLAG: return "_Endianness";
|
||||
case _NOFILL_FLAG: return "_NoFill";
|
||||
default: break;
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
static int
|
||||
truefalse(NCConstant* con, int tag)
|
||||
{
|
||||
@ -1153,7 +1147,7 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
|
||||
char* sdata = NULL;
|
||||
int idata = -1;
|
||||
|
||||
if(tag == _FORMAT_FLAG) {
|
||||
if((GLOBAL_SPECIAL & tag) != 0) {
|
||||
if(vsym != NULL) {
|
||||
derror("_Format: must be global attribute");
|
||||
vsym = NULL;
|
||||
@ -1180,6 +1174,7 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
|
||||
switch (tag) {
|
||||
case _FLETCHER32_FLAG:
|
||||
case _SHUFFLE_FLAG:
|
||||
case _ISNETCDF4_FLAG:
|
||||
case _NOFILL_FLAG:
|
||||
iconst.nctype = (con->nctype == NC_STRING?NC_STRING:NC_INT);
|
||||
convert1(con,&iconst);
|
||||
@ -1187,6 +1182,7 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
|
||||
break;
|
||||
case _FORMAT_FLAG:
|
||||
case _STORAGE_FLAG:
|
||||
case _NCPROPS_FLAG:
|
||||
case _ENDIAN_FLAG:
|
||||
iconst.nctype = NC_STRING;
|
||||
convert1(con,&iconst);
|
||||
@ -1195,6 +1191,7 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
|
||||
else
|
||||
derror("%s: illegal value",specialname(tag));
|
||||
break;
|
||||
case _SUPERBLOCK_FLAG:
|
||||
case _DEFLATE_FLAG:
|
||||
iconst.nctype = NC_INT;
|
||||
convert1(con,&iconst);
|
||||
@ -1214,12 +1211,12 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
|
||||
/* Watch out: this is a global attribute */
|
||||
struct Kvalues* kvalue;
|
||||
int found = 0;
|
||||
|
||||
/* Use the table in main.c */
|
||||
for(kvalue = legalkinds; kvalue->name; kvalue++) {
|
||||
if(sdata) {
|
||||
if(strcmp(sdata, kvalue->name) == 0) {
|
||||
/*Main.*/format_flag = kvalue->k_flag;
|
||||
globalspecials._Format = kvalue->k_flag;
|
||||
/*Main.*/format_attribute = 1;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
@ -1227,13 +1224,17 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
|
||||
}
|
||||
if(!found)
|
||||
derror("_Format: illegal value: %s",sdata);
|
||||
/*Main.*/format_attribute = 1;
|
||||
} else if((GLOBAL_SPECIAL & tag) != 0) {
|
||||
if(tag == _ISNETCDF4_FLAG)
|
||||
globalspecials._IsNetcdf4 = tf;
|
||||
else if(tag == _SUPERBLOCK_FLAG)
|
||||
globalspecials._Superblock = idata;
|
||||
else if(tag == _NCPROPS_FLAG)
|
||||
globalspecials._NCProperties = strdup(sdata);
|
||||
} else {
|
||||
Specialdata* special;
|
||||
|
||||
/* Set up special info */
|
||||
special = &vsym->var.special;
|
||||
|
||||
if(tag == _FILLVALUE_FLAG) {
|
||||
special->_Fillvalue = list;
|
||||
/* fillvalue must be a single value*/
|
||||
@ -1293,7 +1294,7 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
|
||||
special->_Fill = (1 - tf); /* negate */
|
||||
special->flags |= _NOFILL_FLAG;
|
||||
break;
|
||||
case _CHUNKSIZES_FLAG: {
|
||||
case _CHUNKSIZES_FLAG: {
|
||||
int i;
|
||||
special->nchunks = list->length;
|
||||
special->_ChunkSizes = (size_t*)emalloc(sizeof(size_t)*special->nchunks);
|
||||
@ -1327,17 +1328,21 @@ makeattribute(Symbol* asym,
|
||||
{
|
||||
asym->objectclass = NC_ATT;
|
||||
asym->data = data;
|
||||
addtogroup(asym);
|
||||
switch (kind) {
|
||||
case ATTRVAR:
|
||||
asym->att.var = vsym;
|
||||
asym->typ.basetype = tsym;
|
||||
listpush(attdefs,(void*)asym);
|
||||
addtogroup(asym);
|
||||
break;
|
||||
case ATTRGLOBAL:
|
||||
asym->att.var = NULL; /* NULL => NC_GLOBAL*/
|
||||
asym->typ.basetype = tsym;
|
||||
listpush(gattdefs,(void*)asym);
|
||||
// If we are adding NCPROPS to root group, then don't.
|
||||
if(strcmp(NCPROPS,asym->name)!=0 || !currentgroup()->grp.is_root) {
|
||||
addtogroup(asym);
|
||||
listpush(gattdefs,(void*)asym);
|
||||
}
|
||||
break;
|
||||
default: PANIC1("unexpected attribute type: %d",kind);
|
||||
}
|
||||
@ -1348,6 +1353,24 @@ makeattribute(Symbol* asym,
|
||||
return asym;
|
||||
}
|
||||
|
||||
static long long
|
||||
extractint(NCConstant con)
|
||||
{
|
||||
switch (con.nctype) {
|
||||
case NC_BYTE: return (long long)(con.value.int8v);
|
||||
case NC_SHORT: return (long long)(con.value.int16v);
|
||||
case NC_INT: return (long long)(con.value.int32v);
|
||||
case NC_UBYTE: return (long long)(con.value.uint8v);
|
||||
case NC_USHORT: return (long long)(con.value.uint16v);
|
||||
case NC_UINT: return (long long)(con.value.uint32v);
|
||||
case NC_INT64: return (long long)(con.value.int64v);
|
||||
default:
|
||||
derror("Not a signed integer type: %d",con.nctype);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
containsfills(Datalist* list)
|
||||
{
|
||||
@ -1387,6 +1410,17 @@ vercheck(int tid)
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
specialname(int tag)
|
||||
{
|
||||
struct Specialtoken* spp = specials;
|
||||
for(;spp->name;spp++) {
|
||||
if(spp->tag == tag)
|
||||
return spp->name;
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
/*
|
||||
Since the arguments are all simple constants,
|
||||
we can evaluate the function immediately
|
||||
|
1289
ncgen/ncgenl.c
1289
ncgen/ncgenl.c
File diff suppressed because it is too large
Load Diff
3014
ncgen/ncgeny.c
3014
ncgen/ncgeny.c
File diff suppressed because it is too large
Load Diff
210
ncgen/ncgeny.h
210
ncgen/ncgeny.h
@ -1,14 +1,13 @@
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ -16,9 +15,7 @@
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
@ -33,133 +30,100 @@
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YY_NCG_NCGEN_TAB_H_INCLUDED
|
||||
# define YY_NCG_NCGEN_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 1
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int ncgdebug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
NC_UNLIMITED_K = 258,
|
||||
CHAR_K = 259,
|
||||
BYTE_K = 260,
|
||||
SHORT_K = 261,
|
||||
INT_K = 262,
|
||||
FLOAT_K = 263,
|
||||
DOUBLE_K = 264,
|
||||
UBYTE_K = 265,
|
||||
USHORT_K = 266,
|
||||
UINT_K = 267,
|
||||
INT64_K = 268,
|
||||
UINT64_K = 269,
|
||||
IDENT = 270,
|
||||
TERMSTRING = 271,
|
||||
CHAR_CONST = 272,
|
||||
BYTE_CONST = 273,
|
||||
SHORT_CONST = 274,
|
||||
INT_CONST = 275,
|
||||
INT64_CONST = 276,
|
||||
UBYTE_CONST = 277,
|
||||
USHORT_CONST = 278,
|
||||
UINT_CONST = 279,
|
||||
UINT64_CONST = 280,
|
||||
FLOAT_CONST = 281,
|
||||
DOUBLE_CONST = 282,
|
||||
DIMENSIONS = 283,
|
||||
VARIABLES = 284,
|
||||
NETCDF = 285,
|
||||
DATA = 286,
|
||||
TYPES = 287,
|
||||
COMPOUND = 288,
|
||||
ENUM = 289,
|
||||
OPAQUE = 290,
|
||||
OPAQUESTRING = 291,
|
||||
GROUP = 292,
|
||||
PATH = 293,
|
||||
FILLMARKER = 294,
|
||||
NIL = 295,
|
||||
_FILLVALUE = 296,
|
||||
_FORMAT = 297,
|
||||
_STORAGE = 298,
|
||||
_CHUNKSIZES = 299,
|
||||
_DEFLATELEVEL = 300,
|
||||
_SHUFFLE = 301,
|
||||
_ENDIANNESS = 302,
|
||||
_NOFILL = 303,
|
||||
_FLETCHER32 = 304,
|
||||
DATASETID = 305
|
||||
};
|
||||
enum yytokentype
|
||||
{
|
||||
NC_UNLIMITED_K = 258,
|
||||
CHAR_K = 259,
|
||||
BYTE_K = 260,
|
||||
SHORT_K = 261,
|
||||
INT_K = 262,
|
||||
FLOAT_K = 263,
|
||||
DOUBLE_K = 264,
|
||||
UBYTE_K = 265,
|
||||
USHORT_K = 266,
|
||||
UINT_K = 267,
|
||||
INT64_K = 268,
|
||||
UINT64_K = 269,
|
||||
IDENT = 270,
|
||||
TERMSTRING = 271,
|
||||
CHAR_CONST = 272,
|
||||
BYTE_CONST = 273,
|
||||
SHORT_CONST = 274,
|
||||
INT_CONST = 275,
|
||||
INT64_CONST = 276,
|
||||
UBYTE_CONST = 277,
|
||||
USHORT_CONST = 278,
|
||||
UINT_CONST = 279,
|
||||
UINT64_CONST = 280,
|
||||
FLOAT_CONST = 281,
|
||||
DOUBLE_CONST = 282,
|
||||
DIMENSIONS = 283,
|
||||
VARIABLES = 284,
|
||||
NETCDF = 285,
|
||||
DATA = 286,
|
||||
TYPES = 287,
|
||||
COMPOUND = 288,
|
||||
ENUM = 289,
|
||||
OPAQUE = 290,
|
||||
OPAQUESTRING = 291,
|
||||
GROUP = 292,
|
||||
PATH = 293,
|
||||
FILLMARKER = 294,
|
||||
NIL = 295,
|
||||
_FILLVALUE = 296,
|
||||
_FORMAT = 297,
|
||||
_STORAGE = 298,
|
||||
_CHUNKSIZES = 299,
|
||||
_DEFLATELEVEL = 300,
|
||||
_SHUFFLE = 301,
|
||||
_ENDIANNESS = 302,
|
||||
_NOFILL = 303,
|
||||
_FLETCHER32 = 304,
|
||||
_NCPROPS = 305,
|
||||
_ISNETCDF4 = 306,
|
||||
_SUPERBLOCK = 307,
|
||||
DATASETID = 308
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define NC_UNLIMITED_K 258
|
||||
#define CHAR_K 259
|
||||
#define BYTE_K 260
|
||||
#define SHORT_K 261
|
||||
#define INT_K 262
|
||||
#define FLOAT_K 263
|
||||
#define DOUBLE_K 264
|
||||
#define UBYTE_K 265
|
||||
#define USHORT_K 266
|
||||
#define UINT_K 267
|
||||
#define INT64_K 268
|
||||
#define UINT64_K 269
|
||||
#define IDENT 270
|
||||
#define TERMSTRING 271
|
||||
#define CHAR_CONST 272
|
||||
#define BYTE_CONST 273
|
||||
#define SHORT_CONST 274
|
||||
#define INT_CONST 275
|
||||
#define INT64_CONST 276
|
||||
#define UBYTE_CONST 277
|
||||
#define USHORT_CONST 278
|
||||
#define UINT_CONST 279
|
||||
#define UINT64_CONST 280
|
||||
#define FLOAT_CONST 281
|
||||
#define DOUBLE_CONST 282
|
||||
#define DIMENSIONS 283
|
||||
#define VARIABLES 284
|
||||
#define NETCDF 285
|
||||
#define DATA 286
|
||||
#define TYPES 287
|
||||
#define COMPOUND 288
|
||||
#define ENUM 289
|
||||
#define OPAQUE 290
|
||||
#define OPAQUESTRING 291
|
||||
#define GROUP 292
|
||||
#define PATH 293
|
||||
#define FILLMARKER 294
|
||||
#define NIL 295
|
||||
#define _FILLVALUE 296
|
||||
#define _FORMAT 297
|
||||
#define _STORAGE 298
|
||||
#define _CHUNKSIZES 299
|
||||
#define _DEFLATELEVEL 300
|
||||
#define _SHUFFLE 301
|
||||
#define _ENDIANNESS 302
|
||||
#define _NOFILL 303
|
||||
#define _FLETCHER32 304
|
||||
#define DATASETID 305
|
||||
|
||||
|
||||
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
#line 131 "ncgen.y"
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 134 "ncgen.y" /* yacc.c:1909 */
|
||||
|
||||
Symbol* sym;
|
||||
unsigned long size; /* allow for zero size to indicate e.g. UNLIMITED*/
|
||||
long mark; /* track indices into the sequence*/
|
||||
int nctype; /* for tracking attribute list type*/
|
||||
Datalist* datalist;
|
||||
NCConstant constant;
|
||||
}
|
||||
/* Line 1529 of yacc.c. */
|
||||
#line 158 "ncgen.tab.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
||||
#line 117 "ncgeny.h" /* yacc.c:1909 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
extern YYSTYPE ncglval;
|
||||
|
||||
int ncgparse (void);
|
||||
|
||||
#endif /* !YY_NCG_NCGEN_TAB_H_INCLUDED */
|
||||
|
@ -2,14 +2,17 @@
|
||||
# This shell script runs the ncgen tests.
|
||||
# $Id: run_tests.sh,v 1.10 2010/04/04 22:06:03 dmh Exp $
|
||||
|
||||
set -x
|
||||
if test "x$srcdir" = x ; then
|
||||
srcdir="."
|
||||
srcdir=`pwd`
|
||||
fi
|
||||
|
||||
echo "*** Testing ncgen."
|
||||
set -e
|
||||
|
||||
echo "*** creating classic file c0.nc from c0.cdl..."
|
||||
ls -l "$srcdir/c0.cdl"
|
||||
ls -l ./ncgen*
|
||||
./ncgen -b -o c0.nc $srcdir/c0.cdl
|
||||
if [ ! -f c0.nc ]; then
|
||||
echo "Failure."
|
||||
|
14
ncgen/util.c
14
ncgen/util.c
@ -695,3 +695,17 @@ kind_string(int kind)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
getrootid(int grpid)
|
||||
{
|
||||
int current = grpid;
|
||||
int parent = current;
|
||||
/* see if root id */
|
||||
for(;;) {
|
||||
int stat = nc_inq_grp_parent(current,&parent);
|
||||
if(stat) break;
|
||||
current = parent;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ extern int getpadding(int offset, int alignment);
|
||||
extern void check_err(const int stat, const int line, const char* file);
|
||||
extern void check_err2(const int stat, const int cdlline, const int line, const char* file);
|
||||
extern const char* kind_string(int kind);
|
||||
extern int getrootid(int grpid);
|
||||
|
||||
/* Inline functions */
|
||||
#define isunlimited(dimset,i) ((dimset)->dimsyms[i]->dim.isunlimited)
|
||||
|
@ -19,7 +19,8 @@ EXTRA_DIST = ref_nctest_classic.nc ref_nctest_64bit_offset.nc \
|
||||
compare_test_files.sh run_valgrind_tests.sh CMakeLists.txt
|
||||
|
||||
CLEANFILES = nctest_classic.nc nctest_64bit_offset.nc \
|
||||
nctest_netcdf4.nc test2.nc temp.tmp tst_*.nc
|
||||
nctest_netcdf4.nc test2.nc temp.tmp tst_*.nc \
|
||||
nctest_classic.cdl ref_nctest_classic.cdl
|
||||
|
||||
# Run nctest and the script that compares the output with the
|
||||
# reference file.
|
||||
|
Loading…
Reference in New Issue
Block a user