diff --git a/.gitignore b/.gitignore index 1d5b8b37de..9d1fd87ebd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ ctest.c ctest64.c nc_test/test_get.c nc_test/test_put.c +nc_test/test_read.c +nc_test/test_write.c ##### # End ignored generated files. diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f6328f4fa..f42fbe3f76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ ################################## #Minimum required CMake Version -cmake_minimum_required(VERSION 2.8.11) +cmake_minimum_required(VERSION 3.6.1) #Project Name project(netCDF C) @@ -101,10 +101,10 @@ INCLUDE(${CMAKE_ROOT}/Modules/GetPrerequisites.cmake) INCLUDE(CheckCCompilerFlag) FIND_PACKAGE(PkgConfig QUIET) -# Check for Big Endian +# A check to see if the system is big endian TEST_BIG_ENDIAN(BIGENDIAN) IF(${BIGENDIAN}) - SET(WORDS_BIGENDIAN "1") + SET(WORDS_BIGENDIAN "1") ENDIF(${BIGENDIAN}) # A macro to check if a C linker supports a particular flag. @@ -627,6 +627,7 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4) SET(HDF5_C_LIBRARY ${HDF5_C_${NC_HDF5_LINK_TYPE_UPPER}_LIBRARY}) SET(HDF5_C_LIBRARY_hdf5 ${HDF5_C_${NC_HDF5_LINK_TYPE_UPPER}_LIBRARY}) SET(HDF5_HL_LIBRARY ${HDF5_HL_${NC_HDF5_LINK_TYPE_UPPER}_LIBRARY}) + SET(HDF5_LIBRARIES ${HDF5_C_${NC_HDF5_LINK_TYPE_UPPER}_LIBRARY} ${HDF5_HL_${NC_HDF5_LINK_TYPE_UPPER}_LIBRARY}) ENDIF() ENDIF(${HDF5_VERSION} VERSION_GREATER "1.8.15") @@ -651,12 +652,13 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4) ENDIF() ### - # The following options are not used in Windows. + # The following options are not used in Windows currently. ### IF(NOT MSVC) # Find out if HDF5 was built with parallel support. # Do that by checking for the targets H5Pget_fapl_mpiposx and # H5Pget_fapl_mpio in ${HDF5_LIB}. + CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5Pget_fapl_mpiposix "" HDF5_IS_PARALLEL_MPIPOSIX) CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5Pget_fapl_mpio "" HDF5_IS_PARALLEL_MPIO) IF(HDF5_IS_PARALLEL_MPIPOSIX OR HDF5_IS_PARALLEL_MPIO) @@ -991,14 +993,14 @@ IF(ENABLE_PNETCDF) FIND_LIBRARY(PNETCDF NAMES pnetcdf) FIND_PATH(PNETCDF_INCLUDE_DIR pnetcdf.h) IF(NOT PNETCDF) - MESSAGE(STATUS "Cannot find PNetCDF library. Disabling PNetCDF support.") + MESSAGE(STATUS "Cannot find PnetCDF library. Disabling PnetCDF support.") SET(USE_PNETCDF OFF CACHE BOOL "") ELSE(NOT PNETCDF) SET(USE_PARALLEL ON CACHE BOOL "") - # Check PNetCDF version. Must be >= 1.6.0 + # Check PnetCDF version. Must be >= 1.6.0 set(pnetcdf_h "${PNETCDF_INCLUDE_DIR}/pnetcdf.h" ) - message(STATUS "PNetCDF include file ${pnetcdf_h} will be searched for version") + message(STATUS "PnetCDF include file ${pnetcdf_h} will be searched for version") file(STRINGS "${pnetcdf_h}" pnetcdf_major_string REGEX "^#define PNETCDF_VERSION_MAJOR") string(REGEX REPLACE "[^0-9]" "" pnetcdf_major "${pnetcdf_major_string}") file(STRINGS "${pnetcdf_h}" pnetcdf_minor_string REGEX "^#define PNETCDF_VERSION_MINOR") @@ -1006,7 +1008,7 @@ IF(ENABLE_PNETCDF) file(STRINGS "${pnetcdf_h}" pnetcdf_sub_string REGEX "^#define PNETCDF_VERSION_SUB") string(REGEX REPLACE "[^0-9]" "" pnetcdf_sub "${pnetcdf_sub_string}") set(pnetcdf_version "${pnetcdf_major}.${pnetcdf_minor}.${pnetcdf_sub}") - message(STATUS "Found PNetCDF version ${pnetcdf_version}") + message(STATUS "Found PnetCDF version ${pnetcdf_version}") if(${pnetcdf_version} VERSION_GREATER "1.6.0") SET(STATUS_PNETCDF "ON") @@ -1015,13 +1017,66 @@ IF(ENABLE_PNETCDF) # pnetcdf => parallel SET(STATUS_PARALLEL ON) SET(USE_PARALLEL ON) - MESSAGE(STATUS "Using PNetCDF Library: ${PNETCDF}") + MESSAGE(STATUS "Using PnetCDF Library: ${PNETCDF}") ELSE() - MESSAGE(WARNING "ENABLE_PNETCDF requires version 1.6.1 or later; found version ${pnetcdf_version}. PNetCDF is disabled") + MESSAGE(WARNING "ENABLE_PNETCDF requires version 1.6.1 or later; found version ${pnetcdf_version}. PnetCDF is disabled") ENDIF() ENDIF(NOT PNETCDF) ENDIF() +# Options to enable use of fill values for elements casuing NC_ERANGE +SET(STATUS_ERANGE_FILL "OFF") +OPTION(ENABLE_ERANGE_FILL "Enable use of fill value when out-of-range type conversion causes NC_ERANGE error." OF) +IF(ENABLE_ERANGE_FILL) + SET(STATUS_ERANGE_FILL "ON") +ENDIF() + +# Options to use a more relaxed coordinate argument boundary check +SET(STATUS_RELAX_COORD_BOUND "OFF") +OPTION(ENABLE_ZERO_LENGTH_COORD_BOUND "Enable a more relaxed boundary error check NC_EINVALCOORDS to allow coordinate start argument equal to dimension size when argument count is zero." OFF) +IF(ENABLE_ZERO_LENGTH_COORD_BOUND) + SET(STATUS_RELAX_COORD_BOUND "ON") +ENDIF() + +# check and conform with PnetCDF settings on ERANGE_FILL and RELAX_COORD_BOUND +IF(STATUS_PNETCDF) + file(STRINGS "${pnetcdf_h}" enable_erange_fill_pnetcdf REGEX "^#define PNETCDF_ERANGE_FILL") + string(REGEX REPLACE "[^0-9]" "" erange_fill_pnetcdf "${enable_erange_fill_pnetcdf}") + IF("x${erange_fill_pnetcdf}" STREQUAL "x1") + IF(NOT STATUS_ERANGE_FILL) + MESSAGE(WARNING "Enable erange-fill to conform with PnetCDF setting") + SET(STATUS_ERANGE_FILL "ON") + ENDIF() + ELSE() + IF(STATUS_ERANGE_FILL) + MESSAGE(WARNING "Disable erange-fill to conform with PnetCDF setting") + SET(STATUS_ERANGE_FILL "OFF") + ENDIF() + ENDIF() + file(STRINGS "${pnetcdf_h}" relax_coord_bound_pnetcdf REGEX "^#define PNETCDF_RELAX_COORD_BOUND") + string(REGEX REPLACE "[^0-9]" "" relax_coord_bound "${relax_coord_bound_pnetcdf}") + IF("x${relax_coord_bound}" STREQUAL "x1") + IF(NOT STATUS_RELAX_COORD_BOUND) + MESSAGE(WARNING "Enable relax-coord-bound to conform with PnetCDF setting") + SET(STATUS_RELAX_COORD_BOUND "ON") + ENDIF() + ELSE() + IF(STATUS_RELAX_COORD_BOUND) + MESSAGE(WARNING "Disable relax-coord-bound to conform with PnetCDF setting") + SET(STATUS_RELAX_COORD_BOUND "OFF") + ENDIF() + ENDIF() +ENDIF() + +IF(STATUS_ERANGE_FILL) + SET(M4FLAGS "-DERANGE_FILL" CACHE STRING "") +ENDIF() + +IF(STATUS_RELAX_COORD_BOUND) + MESSAGE(STATUS "Enabling a more relatexed check for NC_EINVALCOORDS") + ADD_DEFINITIONS(-DRELAX_COORD_BOUND) +ENDIF() + # Enable Parallel Tests. OPTION(ENABLE_PARALLEL_TESTS "Enable Parallel IO Tests. Ignored if netCDF4 is not enabled, or if there is no parallel I/O Support." ${USE_PARALLEL}) IF(ENABLE_PARALLEL_TESTS AND USE_PARALLEL) @@ -1155,6 +1210,9 @@ CHECK_INCLUDE_FILE("stdbool.h" HAVE_STDBOOL_H) CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H) CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H) CHECK_INCLUDE_FILE("stdio.h" HAVE_STDIO_H) +IF(MSVC) +CHECK_INCLUDE_FILE("io.h" HAVE_IO_H) +ENDIF(MSVC) CHECK_INCLUDE_FILE("stdlib.h" HAVE_STDLIB_H) CHECK_INCLUDE_FILE("stdarg.h" HAVE_STDARG_H) CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H) @@ -1251,9 +1309,13 @@ ENDIF(SIZEOF_PTRDIFF_T) # __int64 is used on Windows for large file support. CHECK_TYPE_SIZE("__int64" SIZEOF___INT_64) -CHECK_TYPE_SIZE("uchar" SIZEOF_UCHAR) CHECK_TYPE_SIZE("int64_t" SIZEOF_INT64_T) CHECK_TYPE_SIZE("uint64_t" SIZEOF_UINT64_T) +CHECK_TYPE_SIZE("unsigned char" SIZEOF_UCHAR) +CHECK_TYPE_SIZE("unsigned short int" SIZEOF_UNSIGNED_SHORT_INT) +CHECK_TYPE_SIZE("unsigned int" SIZEOF_UNSIGNED_INT) +CHECK_TYPE_SIZE("long long" SIZEOF_LONGLONG) +CHECK_TYPE_SIZE("unsigned long long" SIZEOF_ULONGLONG) # On windows systems, we redefine off_t as __int64 # to enable LFS. This is true on 32 and 64 bit system.s @@ -1348,7 +1410,7 @@ IF(HAVE_M4) ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${filename}.c COMMAND ${NC_M4} - ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${filename}.m4 > ${CMAKE_CURRENT_SOURCE_DIR}/${filename}.c + ARGS ${M4FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/${filename}.m4 > ${CMAKE_CURRENT_SOURCE_DIR}/${filename}.c VERBATIM ) ENDIF(HAVE_M4) @@ -1826,6 +1888,7 @@ is_enabled(ENABLE_DAP4 HAS_DAP4) is_enabled(USE_DISKLESS HAS_DISKLESS) is_enabled(USE_MMAP HAS_MMAP) is_enabled(JNA HAS_JNA) +is_enabled(STATUS_RELAX_COORD_BOUND RELAX_COORD_BOUND) # Generate file from template. CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/libnetcdf.settings.in" diff --git a/Makefile.am b/Makefile.am index aa4a3d67d5..136a0bb3c5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -131,6 +131,7 @@ settings_DATA=libnetcdf.settings #### MM4= ./nc_test/test_put ./nc_test/test_get \ + ./nc_test/test_write ./nc_test/test_read \ ./libsrc/netcdf ./libsrc/putget ./libsrc/ncx \ ./libsrc/t_ncxx ./libsrc/attr diff --git a/acinclude.m4 b/acinclude.m4 index b88246a154..2040f45d2c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -749,3 +749,25 @@ esac ])# AX_C_FLOAT_WORDS_BIGENDIAN +dnl Find the full path of a header file +dnl +dnl UD_CHECK_HEADER_PATH(file, [action-if-found], [action-if-not-found]) +dnl Example: +dnl UD_CHECK_HEADER_PATH([math.h]) +dnl AC_MSG_NOTICE([ac_cv_header_path_math_h=$ac_cv_header_path_math_h]) +dnl +dnl +AC_DEFUN([UD_CHECK_HEADER_PATH], +[ + AS_VAR_PUSHDEF([ac_Path], [ac_cv_header_path_$1])dnl + AC_CACHE_CHECK( + [for full path of header file $1], [ac_Path], + [AC_PREPROC_IFELSE( + [AC_LANG_PROGRAM([[#include <$1>]])], + [AS_VAR_SET([ac_Path], [`sed -n '/\.h"/s/.*"\(.*\)".*/\1/p' conftest.i | grep -m 1 $1`])], + [AC_MSG_RESULT([not found])] + )]) + AS_VAR_SET_IF([ac_Path], [$2], [$3]) + AS_VAR_POPDEF([ac_Path])dnl +]) + diff --git a/config.h.cmake.in b/config.h.cmake.in index bda3b3c605..bf20c2e0aa 100644 --- a/config.h.cmake.in +++ b/config.h.cmake.in @@ -45,7 +45,9 @@ are set when opening a binary file on Windows. */ #define fdopen _fdopen #define write _write #define strtoll _strtoi64 -#endif +#endif /*_MSC_VER */ + +#cmakedefine const /* Define if building universal (internal helper macro) */ #cmakedefine AC_APPLE_UNIVERSAL_BUILD 1 @@ -456,6 +458,27 @@ are set when opening a binary file on Windows. */ /* Define to the version of this package. */ #cmakedefine PACKAGE_VERSION "${netCDF_VERSION}" +/* The size of `ulonglong` as computed by sizeof. */ +#cmakedefine SIZEOF_ULONGLONG @SIZEOF_ULONGLONG@ + +/* The size of `longlong` as computed by sizeof. */ +#cmakedefine SIZEOF_LONGLONG @SIZEOF_LONGLONG@ + +/* The size of `uchar` as computed by sizeof. */ +#cmakedefine SIZEOF_UCHAR @SIZEOF_UCHAR@ + +/* The size of `ssize_t` as computed by sizeof. */ +#cmakedefine SIZEOF_SSIZE_T @SIZEOF_SSIZE_T@ + +/* The size of `__int64` found on Windows systems. */ +#cmakedefine SIZEOF___INT64 ${SIZEOF___INT64} + +/* The size of `void*` as computed by sizeof. */ +#cmakedefine SIZEOF_VOIDSTAR ${SIZEOF_VOIDSTAR} + +/* The size of `short` as computed by sizeof. */ +#cmakedefine SIZEOF_OFF64_T ${SIZEOF_OFF64_T} + /* The size of `double', as computed by sizeof. */ #cmakedefine SIZEOF_DOUBLE ${SIZEOF_DOUBLE} @@ -607,9 +630,6 @@ are set when opening a binary file on Windows. */ #cmakedefine __CHAR_UNSIGNED__ #endif -/* Define to empty if `const' does not conform to ANSI C. */ -#cmakedefine const - /* Define to `long int' if does not define. */ #cmakedefine off_t long int diff --git a/configure.ac b/configure.ac index f3c619b478..7a780ed1b7 100644 --- a/configure.ac +++ b/configure.ac @@ -890,6 +890,13 @@ AC_CHECK_SIZEOF(unsigned long long) $SLEEPCMD AC_CHECK_SIZEOF(unsigned long long) +$SLEEPCMD +if test "$ac_cv_type_uchar" = yes ; then + AC_CHECK_SIZEOF(uchar) +else + AC_CHECK_SIZEOF(unsigned char) +fi + $SLEEPCMD if test "$ac_cv_type_ushort" = yes ; then AC_CHECK_SIZEOF(ushort) @@ -1110,6 +1117,83 @@ if test "x$enable_parallel" = xyes; then AC_DEFINE([USE_PARALLEL], [1], [if true, pnetcdf or parallel netcdf-4 is in use]) fi +AC_ARG_ENABLE([erange_fill], + [AS_HELP_STRING([--enable-erange-fill], + [Enable use of fill value when out-of-range type + conversion causes NC_ERANGE error. @<:@default: disabled@:>@])], + [enable_erange_fill=${enableval}], [enable_erange_fill=no] +) + +AC_ARG_ENABLE([zero-length-coord-bound], + [AS_HELP_STRING([--enable-zero-length-coord-bound], + [Enable a more relaxed boundary error check NC_EINVALCOORDS + to allow coordinate start argument equal to dimension size + when argument count is zero. @<:@default: disabled@:>@])], + [enable_zero_length_coord_bound=${enableval}], [enable_zero_length_coord_bound=no] +) + +# check PnetCDF's settings on enable_erange_fill and relax_coord_bound +if test "x$enable_pnetcdf" = xyes; then + UD_CHECK_HEADER_PATH([pnetcdf.h]) + + AC_MSG_CHECKING([if erange-fill is enabled in PnetCDF]) + erange_fill_pnetcdf=`grep PNETCDF_ERANGE_FILL ${ac_cv_header_path_pnetcdf_h}` + if test "x$erange_fill_pnetcdf" = x; then + erange_fill_pnetcdf=no + else + erange_fill_pnetcdf=`echo ${erange_fill_pnetcdf} | cut -d' ' -f3` + if test "x$coord_bound_pnetcdf" = x0; then + enable_erange_fill_pnetcdf=no + else + enable_erange_fill_pnetcdf=yes + fi + fi + AC_MSG_NOTICE([$enable_erange_fill_pnetcdf]) + if test "$enable_erange_fill" != "$enable_erange_fill_pnetcdf"; then + if test "$enable_erange_fill_pnetcdf" = yes; then + AC_MSG_WARN([Enable erange-fill to conform with PnetCDF setting]) + else + AC_MSG_WARN([Disable erange-fill to conform with PnetCDF setting]) + fi + enable_erange_fill=$enable_erange_fill_pnetcdf + fi + + AC_MSG_CHECKING([if relax-coord-bound is enabled in PnetCDF]) + relax_coord_bound_pnetcdf=`grep PNETCDF_RELAX_COORD_BOUND ${ac_cv_header_path_pnetcdf_h}` + if test "x$relax_coord_bound_pnetcdf" = x; then + elax_coord_bound_pnetcdf=no + else + coord_bound_pnetcdf=`echo ${relax_coord_bound_pnetcdf} | cut -d' ' -f3` + if test "x$coord_bound_pnetcdf" = x0; then + relax_coord_bound_pnetcdf=no + else + relax_coord_bound_pnetcdf=yes + fi + fi + AC_MSG_NOTICE([$relax_coord_bound_pnetcdf]) + if test "$enable_zero_length_coord_bound" != "$relax_coord_bound_pnetcdf"; then + if test "$relax_coord_bound_pnetcdf" = yes; then + AC_MSG_WARN([Enable relax-coord-bound to conform with PnetCDF setting]) + else + AC_MSG_WARN([Disable relax-coord-bound to conform with PnetCDF setting]) + fi + enable_zero_length_coord_bound=$relax_coord_bound_pnetcdf + fi +fi + +if test "x$enable_erange_fill" = xyes ; then + if test "x$M4FLAGS" = x ; then + M4FLAGS="-DERANGE_FILL" + else + M4FLAGS="$M4FLAGS -DERANGE_FILL" + fi +fi +AC_SUBST(M4FLAGS) + +if test "x$enable_zero_length_coord_bound" = xyes; then + AC_DEFINE([RELAX_COORD_BOUND], [1], [if true, NC_EINVALCOORDS check is more relaxed]) +fi + # Check for downloading/building fortran via postinstall script. if test "x$enable_remote_fortran_bootstrap" = xyes; then AC_DEFINE([BUILD_FORTRAN], 1, [If true, will attempt to download and build netcdf-fortran.]) @@ -1282,6 +1366,7 @@ AC_SUBST(HAS_PARALLEL4,[$enable_parallel4]) AC_SUBST(HAS_DISKLESS,[$enable_diskless]) AC_SUBST(HAS_MMAP,[$enable_mmap]) AC_SUBST(HAS_JNA,[$enable_jna]) +AC_SUBST(RELAX_COORD_BOUND,[$enable_relax_coord_bound]) # Include some specifics for netcdf on windows. #AH_VERBATIM([_WIN32_STRICMP], diff --git a/gdb-branch.txt b/gdb-branch.txt new file mode 100644 index 0000000000..c5561c28a6 --- /dev/null +++ b/gdb-branch.txt @@ -0,0 +1,18 @@ +set breakpoint pending yes +break test_nc_redef +commands +break util.c:888 if i == 6 +end + +#break util.c:903 if i == 6 +#break util.c:1020 +#break util.c:1014 if i == 6 && j == 0 +#break util.c:1016 if i == 6 && j == 0 +#commands +#break putget.c:10948 +#end + +#break test_write.c:216 +#commands +#break ncx_put_int_double +#end diff --git a/gdb-master.txt b/gdb-master.txt new file mode 100644 index 0000000000..9b9550d62b --- /dev/null +++ b/gdb-master.txt @@ -0,0 +1,12 @@ +set breakpoint pending yes +break test_nc_redef +commands +break util.c:835 if i == 6 +end + +#break test_write.c:139 +#break util.c:961 if i == 6 && j == 0 +#break util.c:963 if i == 6 && j == 0 +#commands +#break putget.c:10414 +#end diff --git a/gh319 Notes.md b/gh319 Notes.md new file mode 100644 index 0000000000..bc9f7ae9de --- /dev/null +++ b/gh319 Notes.md @@ -0,0 +1,10 @@ +# Notes related to bug gh319 + +## NNotes + +## Results and Debugging Table + +Variable | Master | GH319 +---------- |--------|------ +expect | 127 | 255 +value / value[0] | 127 | -1 \ No newline at end of file diff --git a/include/nc.h b/include/nc.h index 9d086851ff..c4cddde292 100644 --- a/include/nc.h +++ b/include/nc.h @@ -38,11 +38,7 @@ typedef struct NC { typedef struct { /* all xdr'd */ size_t nchars; -#ifdef __arm__ - signed char *cp; -#else - char *cp; -#endif + char *cp; } NC_string; @@ -55,18 +51,10 @@ free_NC_string(NC_string *ncstrp); extern int NC_check_name(const char *name); -#ifdef __arm__ -extern NC_string * -new_NC_string(size_t slen, const signed char *str); -extern int -set_NC_string(NC_string *ncstrp, const signed char *str); -#else extern NC_string * new_NC_string(size_t slen, const char *str); extern int set_NC_string(NC_string *ncstrp, const char *str); -#endif - /* End defined in string.c */ diff --git a/include/nc3internal.h b/include/nc3internal.h index 5b291d5cb7..75a0e0854f 100644 --- a/include/nc3internal.h +++ b/include/nc3internal.h @@ -389,6 +389,12 @@ NC_sync(NC3_INFO* ncp); extern int NC_calcsize(const NC3_INFO* ncp, off_t *filesizep); +extern int +NC3_inq_default_fill_value(int xtype, void *fillp); + +extern int +NC3_inq_var_fill(const NC_var *varp, void *fill_value); + /* End defined in nc.c */ /* Begin defined in v1hpg.c */ diff --git a/libdispatch/dstring.c b/libdispatch/dstring.c index 37aa67825b..3466e53957 100644 --- a/libdispatch/dstring.c +++ b/libdispatch/dstring.c @@ -228,13 +228,8 @@ NC_check_name(const char *name) NC_new_string(count, str) */ -#ifdef __arm__ -NC_string * -new_NC_string(size_t slen, const signed char *str) -#else NC_string * new_NC_string(size_t slen, const char *str) -#endif { NC_string *ncstrp; size_t sz = M_RNDUP(sizeof(NC_string)) + slen + 1; @@ -269,13 +264,8 @@ new_NC_string(size_t slen, const char *str) NC_re_string() */ -#ifdef __arm__ - int - set_NC_string(NC_string *ncstrp, const signed char *str) -#else - int +int set_NC_string(NC_string *ncstrp, const char *str) -#endif { size_t slen; diff --git a/libdispatch/dvarget.c b/libdispatch/dvarget.c index 6db41494a9..30291d7b29 100644 --- a/libdispatch/dvarget.c +++ b/libdispatch/dvarget.c @@ -143,6 +143,7 @@ NCDEFAULT_get_vars(int ncid, int varid, const size_t * start, NC* ncp; int memtypelen; size_t vartypelen; + size_t nels; char* value = (char*)value0; size_t numrecs; size_t varshape[NC_MAX_VAR_DIMS]; @@ -200,9 +201,18 @@ NCDEFAULT_get_vars(int ncid, int varid, const size_t * start, /* Do various checks and fixups on start/edges/stride */ simplestride = 1; /* assume so */ + nels = 1; for(i=0;i dimlen) return NC_EINVALCOORDS; +#else + if (mystart[i] >= dimlen) return NC_EINVALCOORDS; +#endif if(edges == NULL) { if(i == 0 && isrecvar) myedges[i] = numrecs - start[i]; @@ -210,23 +220,23 @@ NCDEFAULT_get_vars(int ncid, int varid, const size_t * start, myedges[i] = varshape[i] - mystart[i]; } else myedges[i] = edges[i]; - if(myedges[i] == 0) - return NC_NOERR; /* cannot read anything */ +#ifdef RELAX_COORD_BOUND + if (mystart[i] == dimlen && myedges[i] > 0) return NC_EINVALCOORDS; +#endif + /* myedges is unsigned, never < 0 */ + if(mystart[i] + myedges[i] > dimlen) + return NC_EEDGE; mystride[i] = (stride == NULL ? 1 : stride[i]); if(mystride[i] <= 0 /* cast needed for braindead systems with signed size_t */ || ((unsigned long) mystride[i] >= X_INT_MAX)) return NC_ESTRIDE; if(mystride[i] != 1) simplestride = 0; - /* illegal value checks */ - dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]); - /* mystart is unsigned, never < 0 */ - if(mystart[i] >= dimlen) - return NC_EINVALCOORDS; - /* myedges is unsigned, never < 0 */ - if(mystart[i] + myedges[i] > dimlen) - return NC_EEDGE; + if(myedges[i] == 0) + nels = 0; } + if(nels == 0) + return NC_NOERR; /* cannot read anything */ if(simplestride) { return NC_get_vara(ncid, varid, mystart, myedges, value, memtype); } @@ -376,17 +386,26 @@ NCDEFAULT_get_varm(int ncid, int varid, const size_t *start, mymap = mystride + varndims; /* - * Initialize I/O parameters. + * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { + size_t dimlen = + idim == 0 && isrecvar + ? numrecs + : varshape[idim]; + mystart[idim] = start != NULL ? start[idim] : 0; - if (edges != NULL && edges[idim] == 0) +#ifdef RELAX_COORD_BOUND + if (mystart[idim] > dimlen) +#else + if (mystart[idim] >= dimlen) +#endif { - status = NC_NOERR; /* read/write no data */ + status = NC_EINVALCOORDS; goto done; } @@ -405,6 +424,33 @@ NCDEFAULT_get_varm(int ncid, int varid, const size_t *start, myedges[idim] = varshape[idim] - mystart[idim]; #endif +#ifdef RELAX_COORD_BOUND + if (mystart[idim] == dimlen && myedges[idim] > 0) + { + status = NC_EINVALCOORDS; + goto done; + } +#endif + + if (mystart[idim] + myedges[idim] > dimlen) + { + status = NC_EEDGE; + goto done; + } + } + + + /* + * Initialize I/O parameters. + */ + for (idim = maxidim; idim >= 0; --idim) + { + if (edges != NULL && edges[idim] == 0) + { + status = NC_NOERR; /* read/write no data */ + goto done; + } + mystride[idim] = stride != NULL ? stride[idim] : 1; @@ -430,30 +476,6 @@ NCDEFAULT_get_varm(int ncid, int varid, const size_t *start, stop[idim] = (mystart[idim] + myedges[idim] * (size_t)mystride[idim]); } - /* - * Check start, edges - */ - for (idim = maxidim; idim >= 0; --idim) - { - size_t dimlen = - idim == 0 && isrecvar - ? numrecs - : varshape[idim]; - if (mystart[idim] >= dimlen) - { - status = NC_EINVALCOORDS; - goto done; - } - - if (mystart[idim] + myedges[idim] > dimlen) - { - status = NC_EEDGE; - goto done; - } - - } - - /* Lower body */ /* * As an optimization, adjust I/O parameters when the fastest diff --git a/libdispatch/dvarput.c b/libdispatch/dvarput.c index 6bc905fd5f..cad940fd94 100644 --- a/libdispatch/dvarput.c +++ b/libdispatch/dvarput.c @@ -128,6 +128,7 @@ NCDEFAULT_put_vars(int ncid, int varid, const size_t * start, nc_type vartype = NC_NAT; NC* ncp; size_t vartypelen; + size_t nels; int memtypelen; const char* value = (const char*)value0; int nrecdims; /* number of record dims for a variable */ @@ -189,9 +190,26 @@ NCDEFAULT_put_vars(int ncid, int varid, const size_t * start, /* Do various checks and fixups on start/edges/stride */ isstride1 = 1; /* assume so */ + nels = 1; for(i=0;i dimlen) return NC_EINVALCOORDS; +#else + if (mystart[i] >= dimlen) return NC_EINVALCOORDS; +#endif + } if(edges == NULL) { #if 0 if(i == 0 && isrecvar) @@ -204,31 +222,27 @@ NCDEFAULT_put_vars(int ncid, int varid, const size_t * start, myedges[i] = varshape[i] - mystart[i]; } else myedges[i] = edges[i]; - if(myedges[i] == 0) - return NC_NOERR; /* cannot write anything */ +#ifdef RELAX_COORD_BOUND + if(!is_recdim[i]) { + if (mystart[i] == dimlen && myedges[i] > 0) + return NC_EINVALCOORDS; + } +#endif + if(!is_recdim[i]) { + /* myediges is unsigned, will never be < 0 */ + if(mystart[i] + myedges[i] > dimlen) + return NC_EEDGE; + } mystride[i] = (stride == NULL ? 1 : stride[i]); if(mystride[i] <= 0 /* cast needed for braindead systems with signed size_t */ || ((unsigned long) mystride[i] >= X_INT_MAX)) return NC_ESTRIDE; if(mystride[i] != 1) isstride1 = 0; - /* illegal value checks */ -#if 0 - dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]); - if(i == 0 && isrecvar) {/*do nothing*/} -#else - dimlen = varshape[i]; - if(is_recdim[i]) {/*do nothing*/} -#endif - else { - /* mystart is unsigned, will never be < 0 */ - if(mystart[i] > dimlen) - return NC_EINVALCOORDS; - /* myediges is unsigned, will never be < 0 */ - if(mystart[i] + myedges[i] > dimlen) - return NC_EEDGE; - } + nels *= myedges[i]; } + if(nels == 0) + return NC_NOERR; /* cannot write anything */ if(isstride1) { return NC_put_vara(ncid, varid, mystart, myedges, value, memtype); } @@ -380,7 +394,7 @@ NCDEFAULT_put_varm( mymap = mystride + varndims; /* - * Initialize I/O parameters. + * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { @@ -388,17 +402,44 @@ NCDEFAULT_put_varm( ? start[idim] : 0; + myedges[idim] = edges != NULL + ? edges[idim] + : idim == 0 && isrecvar + ? numrecs - mystart[idim] + : varshape[idim] - mystart[idim]; + } + + for (idim = isrecvar; idim <= maxidim; ++idim) + { +#ifdef RELAX_COORD_BOUND + if (mystart[idim] > varshape[idim] || + (mystart[idim] == varshape[idim] && myedges[idim] > 0)) +#else + if (mystart[idim] >= varshape[idim]) +#endif + { + status = NC_EINVALCOORDS; + goto done; + } + + if (mystart[idim] + myedges[idim] > varshape[idim]) + { + status = NC_EEDGE; + goto done; + } + } + + /* + * Initialize I/O parameters. + */ + for (idim = maxidim; idim >= 0; --idim) + { if (edges != NULL && edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } - myedges[idim] = edges != NULL - ? edges[idim] - : idim == 0 && isrecvar - ? numrecs - mystart[idim] - : varshape[idim] - mystart[idim]; mystride[idim] = stride != NULL ? stride[idim] : 1; @@ -413,23 +454,6 @@ NCDEFAULT_put_varm( stop[idim] = mystart[idim] + myedges[idim] * (size_t)mystride[idim]; } - /* - * Check start, edges - */ - for (idim = isrecvar; idim < maxidim; ++idim) - { - if (mystart[idim] > varshape[idim]) - { - status = NC_EINVALCOORDS; - goto done; - } - if (mystart[idim] + myedges[idim] > varshape[idim]) - { - status = NC_EEDGE; - goto done; - } - } - /* Lower body */ /* * As an optimization, adjust I/O parameters when the fastest diff --git a/libsrc/attr.m4 b/libsrc/attr.m4 index 3d6c0d6e78..bf4c6fb3e0 100644 --- a/libsrc/attr.m4 +++ b/libsrc/attr.m4 @@ -9,6 +9,10 @@ dnl * See netcdf/COPYRIGHT file for copying and redistribution conditions. */ +#if HAVE_CONFIG_H +#include +#endif + #include "nc3internal.h" #include "ncdispatch.h" #include "nc3dispatch.h" @@ -398,6 +402,9 @@ NC_lookupattr(int ncid, if(ncap == NULL) return NC_ENOTVAR; + if(name == NULL) + return NC_EBADNAME; + tmp = NC_findattr(ncap, name); if(tmp == NULL) return NC_ENOTATT; @@ -634,31 +641,31 @@ dnl define(`XNCX_PAD_PUTN',dnl `dnl static int -ncx_pad_putn_I$1(void **xpp, size_t nelems, const $1 *tp, nc_type type) +ncx_pad_putn_I$1(void **xpp, size_t nelems, const $1 *tp, nc_type type, void *fillp) { switch(type) { case NC_CHAR: return NC_ECHAR; case NC_BYTE: - return ncx_pad_putn_schar_$1(xpp, nelems, tp); + return ncx_pad_putn_schar_$1(xpp, nelems, tp, fillp); case NC_SHORT: - return ncx_pad_putn_short_$1(xpp, nelems, tp); + return ncx_pad_putn_short_$1(xpp, nelems, tp, fillp); case NC_INT: - return ncx_putn_int_$1(xpp, nelems, tp); + return ncx_putn_int_$1(xpp, nelems, tp, fillp); case NC_FLOAT: - return ncx_putn_float_$1(xpp, nelems, tp); + return ncx_putn_float_$1(xpp, nelems, tp, fillp); case NC_DOUBLE: - return ncx_putn_double_$1(xpp, nelems, tp); + return ncx_putn_double_$1(xpp, nelems, tp, fillp); case NC_UBYTE: - return ncx_pad_putn_uchar_$1(xpp, nelems, tp); + return ncx_pad_putn_uchar_$1(xpp, nelems, tp, fillp); case NC_USHORT: - return ncx_putn_ushort_$1(xpp, nelems, tp); + return ncx_putn_ushort_$1(xpp, nelems, tp, fillp); case NC_UINT: - return ncx_putn_uint_$1(xpp, nelems, tp); + return ncx_putn_uint_$1(xpp, nelems, tp, fillp); case NC_INT64: - return ncx_putn_longlong_$1(xpp, nelems, tp); + return ncx_putn_longlong_$1(xpp, nelems, tp, fillp); case NC_UINT64: - return ncx_putn_ulonglong_$1(xpp, nelems, tp); + return ncx_putn_ulonglong_$1(xpp, nelems, tp, fillp); default: assert("ncx_pad_putn_I$1 invalid type" == 0); } @@ -743,31 +750,31 @@ XNCX_PAD_GETN(ulonglong) /* Common dispatcher for put cases */ static int dispatchput(void **xpp, size_t nelems, const void* tp, - nc_type atype, nc_type memtype) + nc_type atype, nc_type memtype, void *fillp) { switch (memtype) { case NC_CHAR: return ncx_pad_putn_text(xpp,nelems, (char *)tp); case NC_BYTE: - return ncx_pad_putn_Ischar(xpp, nelems, (schar*)tp, atype); + return ncx_pad_putn_Ischar(xpp, nelems, (schar*)tp, atype, fillp); case NC_SHORT: - return ncx_pad_putn_Ishort(xpp, nelems, (short*)tp, atype); + return ncx_pad_putn_Ishort(xpp, nelems, (short*)tp, atype, fillp); case NC_INT: - return ncx_pad_putn_Iint(xpp, nelems, (int*)tp, atype); + return ncx_pad_putn_Iint(xpp, nelems, (int*)tp, atype, fillp); case NC_FLOAT: - return ncx_pad_putn_Ifloat(xpp, nelems, (float*)tp, atype); + return ncx_pad_putn_Ifloat(xpp, nelems, (float*)tp, atype, fillp); case NC_DOUBLE: - return ncx_pad_putn_Idouble(xpp, nelems, (double*)tp, atype); + return ncx_pad_putn_Idouble(xpp, nelems, (double*)tp, atype, fillp); case NC_UBYTE: /*Synthetic*/ - return ncx_pad_putn_Iuchar(xpp,nelems, (uchar *)tp, atype); + return ncx_pad_putn_Iuchar(xpp,nelems, (uchar *)tp, atype, fillp); case NC_INT64: - return ncx_pad_putn_Ilonglong(xpp, nelems, (longlong*)tp, atype); + return ncx_pad_putn_Ilonglong(xpp, nelems, (longlong*)tp, atype, fillp); case NC_USHORT: - return ncx_pad_putn_Iushort(xpp, nelems, (ushort*)tp, atype); + return ncx_pad_putn_Iushort(xpp, nelems, (ushort*)tp, atype, fillp); case NC_UINT: - return ncx_pad_putn_Iuint(xpp, nelems, (uint*)tp, atype); + return ncx_pad_putn_Iuint(xpp, nelems, (uint*)tp, atype, fillp); case NC_UINT64: - return ncx_pad_putn_Iulonglong(xpp, nelems, (ulonglong*)tp, atype); + return ncx_pad_putn_Iulonglong(xpp, nelems, (ulonglong*)tp, atype, fillp); case NC_NAT: return NC_EBADTYPE; default: @@ -793,6 +800,7 @@ NC3_put_att( NC_attr **attrpp; NC_attr *old = NULL; NC_attr *attrp; + unsigned char fill[8]; /* fill value in internal representation */ status = NC_check_id(ncid, &nc); if(status != NC_NOERR) @@ -806,6 +814,10 @@ NC3_put_att( if(ncap == NULL) return NC_ENOTVAR; + if (name == NULL) + return NC_EBADNAME; + + /* check NC_EBADTYPE */ status = nc3_cktype(nc->mode, type); if(status != NC_NOERR) return status; @@ -828,6 +840,9 @@ NC3_put_att( /* 4 cases: exists X indef */ + status = NC3_inq_default_fill_value(type, &fill); + if (status != NC_NOERR) return status; + if(attrpp != NULL) { /* name in use */ if(!NC_indef(ncp)) { const size_t xsz = ncx_len_NC_attrV(type, nelems); @@ -842,7 +857,13 @@ NC3_put_att( if(nelems != 0) { void *xp = attrp->xvalue; - status = dispatchput(&xp, nelems, (const void*)value, type, memtype); + /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */ + if (!fIsSet(ncp->flags,NC_64BIT_DATA) && type == NC_BYTE && memtype == NC_UBYTE) { + status = NC3_inq_default_fill_value(NC_UBYTE, &fill); + if (status != NC_NOERR) return status; + status = dispatchput(&xp, nelems, value, memtype, memtype, &fill); + } else + status = dispatchput(&xp, nelems, value, type, memtype, &fill); } set_NC_hdirty(ncp); @@ -874,7 +895,13 @@ NC3_put_att( if(nelems != 0) { void *xp = attrp->xvalue; - status = dispatchput(&xp, nelems, (const void*)value, type, memtype); + /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */ + if (!fIsSet(ncp->flags,NC_64BIT_DATA) && type == NC_BYTE && memtype == NC_UBYTE) { + status = NC3_inq_default_fill_value(NC_UBYTE, &fill); + if (status != NC_NOERR) return status; + status = dispatchput(&xp, nelems, (const void*)value, memtype, memtype, &fill); + } else + status = dispatchput(&xp, nelems, (const void*)value, type, memtype, &fill); } if(attrpp != NULL) { @@ -904,9 +931,16 @@ NC3_get_att( nc_type memtype) { int status; + NC *nc; + NC3_INFO* ncp; NC_attr *attrp; const void *xp; + status = NC_check_id(ncid, &nc); + if(status != NC_NOERR) + return status; + ncp = NC3_DATA(nc); + status = NC_lookupattr(ncid, varid, name, &attrp); if(status != NC_NOERR) return status; @@ -922,7 +956,7 @@ NC3_get_att( xp = attrp->xvalue; switch (memtype) { case NC_CHAR: - return ncx_pad_getn_text(&xp, attrp->nelems , (char *)value); + return ncx_pad_getn_text(&xp, attrp->nelems, (char *)value); case NC_BYTE: return ncx_pad_getn_Ischar(&xp,attrp->nelems,(schar*)value,attrp->type); case NC_SHORT: @@ -936,14 +970,17 @@ NC3_get_att( case NC_INT64: return ncx_pad_getn_Ilonglong(&xp,attrp->nelems,(longlong*)value,attrp->type); case NC_UBYTE: /* Synthetic */ - return ncx_pad_getn_Iuchar(&xp, attrp->nelems , (uchar *)value, attrp->type); + /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */ + if (!fIsSet(ncp->flags,NC_64BIT_DATA) && attrp->type == NC_BYTE) + return ncx_pad_getn_Iuchar(&xp, attrp->nelems, (uchar *)value, NC_UBYTE); + else + return ncx_pad_getn_Iuchar(&xp, attrp->nelems, (uchar *)value, attrp->type); case NC_USHORT: return ncx_pad_getn_Iushort(&xp,attrp->nelems,(ushort*)value,attrp->type); case NC_UINT: return ncx_pad_getn_Iuint(&xp,attrp->nelems,(uint*)value,attrp->type); case NC_UINT64: return ncx_pad_getn_Iulonglong(&xp,attrp->nelems,(ulonglong*)value,attrp->type); - case NC_NAT: return NC_EBADTYPE; default: @@ -952,3 +989,4 @@ NC3_get_att( status = NC_EBADTYPE; return status; } + diff --git a/libsrc/dim.c b/libsrc/dim.c index 49c076e040..a809fc11ab 100644 --- a/libsrc/dim.c +++ b/libsrc/dim.c @@ -4,6 +4,10 @@ */ /* $Id: dim.c,v 1.83 2010/05/25 17:54:15 dmh Exp $ */ +#if HAVE_CONFIG_H +#include +#endif + #include "nc3internal.h" #include #include diff --git a/libsrc/ffio.c b/libsrc/ffio.c index b48e36d26a..e2ba64f70e 100644 --- a/libsrc/ffio.c +++ b/libsrc/ffio.c @@ -7,7 +7,11 @@ /* added correction by John Sheldon and Hans Vahlenkamp 15.4.1998*/ -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + +#include #include #include /* DEBUG */ #include @@ -145,7 +149,7 @@ fgrow2(const int fd, const off_t len) /* Begin ffio */ static int -ffio_pgout(ncio *const nciop, +ffio_pgout(ncio *const nciop, off_t const offset, const size_t extent, const void *const vp, off_t *posp) { @@ -215,7 +219,7 @@ ffio_pgin(ncio *const nciop, typedef struct ncio_ffio { off_t pos; /* buffer */ - off_t bf_offset; + off_t bf_offset; size_t bf_extent; size_t bf_cnt; void *bf_base; @@ -263,7 +267,7 @@ ncio_ffio_get(ncio *const nciop, #ifdef X_ALIGN size_t rem; #endif - + if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE)) return EPERM; /* attempt to write readonly file */ @@ -337,7 +341,7 @@ ncio_ffio_move(ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags) { int status = NC_NOERR; - off_t lower = from; + off_t lower = from; off_t upper = to; char *base; size_t diff = upper - lower; @@ -347,11 +351,11 @@ ncio_ffio_move(ncio *const nciop, off_t to, off_t from, if(to == from) return NC_NOERR; /* NOOP */ - + if(to > from) { /* growing */ - lower = from; + lower = from; upper = to; } else @@ -371,10 +375,10 @@ ncio_ffio_move(ncio *const nciop, off_t to, off_t from, return status; if(to > from) - (void) memmove(base + diff, base, nbytes); + (void) memmove(base + diff, base, nbytes); else - (void) memmove(base, base + diff, nbytes); - + (void) memmove(base, base + diff, nbytes); + (void) ncio_ffio_rel(nciop, lower, RGN_MODIFIED); return status; @@ -495,7 +499,7 @@ ncio_free(ncio *nciop) if(nciop->free != NULL) nciop->free(nciop->pvt); - + free(nciop); } @@ -507,7 +511,7 @@ ncio_ffio_new(const char *path, int ioflags) size_t sz_path = M_RNDUP(strlen(path) +1); size_t sz_ncio_pvt; ncio *nciop; - + #if ALWAYS_NC_SHARE /* DEBUG */ fSet(ioflags, NC_SHARE); #endif @@ -520,7 +524,7 @@ ncio_ffio_new(const char *path, int ioflags) nciop = (ncio *) malloc(sz_ncio + sz_path + sz_ncio_pvt); if(nciop == NULL) return NULL; - + nciop->ioflags = ioflags; *((int *)&nciop->fd) = -1; /* cast away const */ @@ -586,7 +590,7 @@ ncio_ffio_assign(const char *filename) { if(envstr == (char *) NULL) { envstr = "bufa:336:2"; /* this should be macroized */ } - + /* Insertion by Olaf Heudecker, AWI-Bremerhaven, 12.8.1998 to allow more versatile FFIO-assigns */ /* this is unnecessary and could have been included @@ -803,8 +807,8 @@ ffio_open(const char *path, } -/* - * Get file size in bytes. +/* + * Get file size in bytes. * Is use of ffseek() really necessary, or could we use standard fstat() call * and get st_size member? */ @@ -818,7 +822,7 @@ ncio_ffio_filesize(ncio *nciop, off_t *filesizep) current = ffseek(nciop->fd, 0, SEEK_CUR); /* save current */ *filesizep = ffseek(nciop->fd, 0, SEEK_END); /* get size */ - reset = ffseek(nciop->fd, current, SEEK_SET); /* reset */ + reset = ffseek(nciop->fd, current, SEEK_SET); /* reset */ if(reset != current) return EINVAL; @@ -855,7 +859,7 @@ ncio_ffio_pad_length(ncio *nciop, off_t length) } -static int +static int ncio_ffio_close(ncio *nciop, int doUnlink) { /* @@ -872,7 +876,7 @@ ncio_ffio_close(ncio *nciop, int doUnlink) status = nciop->sync(nciop); (void) ffclose(nciop->fd); - + if(doUnlink) (void) unlink(nciop->path); diff --git a/libsrc/lookup3.c b/libsrc/lookup3.c index 4464153ecc..f31e08ef89 100644 --- a/libsrc/lookup3.c +++ b/libsrc/lookup3.c @@ -46,7 +46,10 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy. */ /* #define SELF_TEST 1 */ -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + #include /* defines printf for tests */ #include /* defines time_t for timings in the test */ #ifndef HAVE_STDINT_H diff --git a/libsrc/memio.c b/libsrc/memio.c index aa87dcd7f7..8cda908c92 100644 --- a/libsrc/memio.c +++ b/libsrc/memio.c @@ -9,7 +9,10 @@ #define lseek64 lseek #endif -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -34,7 +37,7 @@ #endif #ifndef HAVE_SSIZE_T -#define ssize_t int +typedef int ssize_t; #endif #ifndef SEEK_SET diff --git a/libsrc/mmapio.c b/libsrc/mmapio.c index 5ed316b716..5681fc7e2b 100644 --- a/libsrc/mmapio.c +++ b/libsrc/mmapio.c @@ -3,7 +3,10 @@ * See netcdf/COPYRIGHT file for copying and redistribution conditions. */ -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/libsrc/nc3internal.c b/libsrc/nc3internal.c index fe5573198d..ac5a5aef0e 100644 --- a/libsrc/nc3internal.c +++ b/libsrc/nc3internal.c @@ -3,7 +3,10 @@ * See netcdf/COPYRIGHT file for copying and redistribution conditions. */ -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -351,9 +354,9 @@ read_numrecs(NC3_INFO *ncp) return status; if (fIsSet(ncp->flags, NC_64BIT_DATA)) { - long long tmp=0; - status = ncx_get_int64(&xp, &tmp); - new_nrecs = tmp; + unsigned long long tmp=0; + status = ncx_get_uint64(&xp, &tmp); + new_nrecs = (size_t)tmp; } else status = ncx_get_size_t(&xp, &new_nrecs); @@ -394,7 +397,7 @@ write_numrecs(NC3_INFO *ncp) { const size_t nrecs = NC_get_numrecs(ncp); if (fIsSet(ncp->flags, NC_64BIT_DATA)) - status = ncx_put_int64(&xp, nrecs); + status = ncx_put_uint64(&xp, (unsigned long long)nrecs); else status = ncx_put_size_t(&xp, &nrecs); } @@ -1724,3 +1727,95 @@ nc_delete(const char * path) { return nc_delete_mp(path, 0); } + +/*----< NC3_inq_default_fill_value() >---------------------------------------*/ +/* copy the default fill value to the memory space pointed by fillp */ +int +NC3_inq_default_fill_value(int xtype, void *fillp) +{ + if (fillp == NULL) return NC_NOERR; + + switch(xtype) { + case NC_CHAR : *(char*)fillp = NC_FILL_CHAR; break; + case NC_BYTE : *(signed char*)fillp = NC_FILL_BYTE; break; + case NC_SHORT : *(short*)fillp = NC_FILL_SHORT; break; + case NC_INT : *(int*)fillp = NC_FILL_INT; break; + case NC_FLOAT : *(float*)fillp = NC_FILL_FLOAT; break; + case NC_DOUBLE : *(double*)fillp = NC_FILL_DOUBLE; break; + case NC_UBYTE : *(unsigned char*)fillp = NC_FILL_UBYTE; break; + case NC_USHORT : *(unsigned short*)fillp = NC_FILL_USHORT; break; + case NC_UINT : *(unsigned int*)fillp = NC_FILL_UINT; break; + case NC_INT64 : *(long long*)fillp = NC_FILL_INT64; break; + case NC_UINT64 : *(unsigned long long*)fillp = NC_FILL_UINT64; break; + default : return NC_EBADTYPE; + } + return NC_NOERR; +} + + +/*----< NC3_inq_var_fill() >-------------------------------------------------*/ +/* inquire the fill value of a variable */ +int +NC3_inq_var_fill(const NC_var *varp, void *fill_value) +{ + NC_attr **attrpp = NULL; + + if (fill_value == NULL) return NC_EINVAL; + + /* + * find fill value + */ + attrpp = NC_findattr(&varp->attrs, _FillValue); + if ( attrpp != NULL ) { + /* User defined fill value */ + if ( (*attrpp)->type != varp->type || (*attrpp)->nelems != 1 ) + return NC_EBADTYPE; + + const void *xp = (*attrpp)->xvalue; + /* value stored in xvalue is in external representation, may need byte-swap */ + switch(varp->type) { + case NC_CHAR: return ncx_getn_text (&xp, 1, (char*)fill_value); + case NC_BYTE: return ncx_getn_schar_schar (&xp, 1, (signed char*)fill_value); + case NC_UBYTE: return ncx_getn_uchar_uchar (&xp, 1, (unsigned char*)fill_value); + case NC_SHORT: return ncx_getn_short_short (&xp, 1, (short*)fill_value); + case NC_USHORT: return ncx_getn_ushort_ushort (&xp, 1, (unsigned short*)fill_value); + case NC_INT: return ncx_getn_int_int (&xp, 1, (int*)fill_value); + case NC_UINT: return ncx_getn_uint_uint (&xp, 1, (unsigned int*)fill_value); + case NC_FLOAT: return ncx_getn_float_float (&xp, 1, (float*)fill_value); + case NC_DOUBLE: return ncx_getn_double_double (&xp, 1, (double*)fill_value); + case NC_INT64: return ncx_getn_longlong_longlong (&xp, 1, (long long*)fill_value); + case NC_UINT64: return ncx_getn_ulonglong_ulonglong(&xp, 1, (unsigned long long*)fill_value); + default: return NC_EBADTYPE; + } + } + else { + /* use the default */ + switch(varp->type){ + case NC_CHAR: *(char *)fill_value = NC_FILL_CHAR; + break; + case NC_BYTE: *(signed char *)fill_value = NC_FILL_BYTE; + break; + case NC_SHORT: *(short *)fill_value = NC_FILL_SHORT; + break; + case NC_INT: *(int *)fill_value = NC_FILL_INT; + break; + case NC_UBYTE: *(unsigned char *)fill_value = NC_FILL_UBYTE; + break; + case NC_USHORT: *(unsigned short *)fill_value = NC_FILL_USHORT; + break; + case NC_UINT: *(unsigned int *)fill_value = NC_FILL_UINT; + break; + case NC_INT64: *(long long *)fill_value = NC_FILL_INT64; + break; + case NC_UINT64: *(unsigned long long *)fill_value = NC_FILL_UINT64; + break; + case NC_FLOAT: *(float *)fill_value = NC_FILL_FLOAT; + break; + case NC_DOUBLE: *(double *)fill_value = NC_FILL_DOUBLE; + break; + default: + return NC_EINVAL; + } + } + return NC_NOERR; +} diff --git a/libsrc/ncio.c b/libsrc/ncio.c index f3349a01ef..fb7756914f 100644 --- a/libsrc/ncio.c +++ b/libsrc/ncio.c @@ -3,7 +3,10 @@ * See netcdf/COPYRIGHT file for copying and redistribution conditions. */ -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + #include #include "netcdf.h" diff --git a/libsrc/ncx.h b/libsrc/ncx.h index 94229d671f..805d110a38 100644 --- a/libsrc/ncx.h +++ b/libsrc/ncx.h @@ -231,19 +231,19 @@ extern int ncx_get_schar_double(const void *xp, double *ip); extern int -ncx_put_schar_schar(void *xp, const schar *ip); +ncx_put_schar_schar(void *xp, const schar *ip, void *fillp); extern int -ncx_put_schar_uchar(void *xp, const uchar *ip); +ncx_put_schar_uchar(void *xp, const uchar *ip, void *fillp); extern int -ncx_put_schar_short(void *xp, const short *ip); +ncx_put_schar_short(void *xp, const short *ip, void *fillp); extern int -ncx_put_schar_int(void *xp, const int *ip); +ncx_put_schar_int(void *xp, const int *ip, void *fillp); extern int -ncx_put_schar_long(void *xp, const long *ip); +ncx_put_schar_long(void *xp, const long *ip, void *fillp); extern int -ncx_put_schar_float(void *xp, const float *ip); +ncx_put_schar_float(void *xp, const float *ip, void *fillp); extern int -ncx_put_schar_double(void *xp, const double *ip); +ncx_put_schar_double(void *xp, const double *ip, void *fillp); #endif /* @@ -275,8 +275,17 @@ ncx_put_int32(void **xpp, const int ip); extern int ncx_put_int64(void **xpp, const long long ip); +extern int +ncx_get_uint32(const void **xpp, unsigned int *ip); +extern int +ncx_get_uint64(const void **xpp, unsigned long long *ip); +extern int +ncx_put_uint32(void **xpp, const unsigned int ip); +extern int +ncx_put_uint64(void **xpp, const unsigned long long ip); + extern int ncx_get_int_int(const void *xp, int *ip); -extern int ncx_put_int_int(void *xp, const int *ip); +extern int ncx_put_int_int(void *xp, const int *ip, void *fillp); /* * Aggregate numeric conversion functions. @@ -366,50 +375,50 @@ extern int ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_schar_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_schar_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_schar_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_schar_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_schar_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_schar_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_schar_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_schar_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_schar_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_schar_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_schar_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_schar_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_schar_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_schar_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_schar_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_schar_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_schar_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_schar_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_schar_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_schar_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); extern int -ncx_pad_putn_schar_schar (void **xpp, size_t nelems, const schar *ip); +ncx_pad_putn_schar_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_pad_putn_schar_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_pad_putn_schar_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_pad_putn_schar_short (void **xpp, size_t nelems, const short *ip); +ncx_pad_putn_schar_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_pad_putn_schar_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_pad_putn_schar_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_pad_putn_schar_int (void **xpp, size_t nelems, const int *ip); +ncx_pad_putn_schar_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_pad_putn_schar_uint (void **xpp, size_t nelems, const uint *ip); +ncx_pad_putn_schar_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_pad_putn_schar_long (void **xpp, size_t nelems, const long *ip); +ncx_pad_putn_schar_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_pad_putn_schar_float (void **xpp, size_t nelems, const float *ip); +ncx_pad_putn_schar_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *ip); +ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_pad_putn_schar_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_pad_putn_schar_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /*---- uchar ----------------------------------------------------------------*/ extern int @@ -459,50 +468,50 @@ extern int ncx_pad_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_uchar_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_uchar_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_uchar_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_uchar_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_uchar_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_uchar_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_uchar_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_uchar_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_uchar_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_uchar_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_uchar_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_uchar_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_uchar_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_uchar_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_uchar_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_uchar_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_uchar_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_uchar_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); extern int -ncx_pad_putn_uchar_schar (void **xpp, size_t nelems, const schar *ip); +ncx_pad_putn_uchar_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_pad_putn_uchar_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_pad_putn_uchar_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_pad_putn_uchar_short (void **xpp, size_t nelems, const short *ip); +ncx_pad_putn_uchar_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_pad_putn_uchar_int (void **xpp, size_t nelems, const int *ip); +ncx_pad_putn_uchar_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_pad_putn_uchar_uint (void **xpp, size_t nelems, const uint *ip); +ncx_pad_putn_uchar_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_pad_putn_uchar_long (void **xpp, size_t nelems, const long *ip); +ncx_pad_putn_uchar_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_pad_putn_uchar_float (void **xpp, size_t nelems, const float *ip); +ncx_pad_putn_uchar_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *ip); +ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_pad_putn_uchar_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_pad_putn_uchar_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /*---- short ----------------------------------------------------------------*/ extern int @@ -552,50 +561,50 @@ extern int ncx_pad_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_short_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_short_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_short_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_short_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_short_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_short_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_short_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_short_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_short_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_short_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_short_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_short_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_short_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_short_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_short_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_short_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_short_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_short_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_short_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_short_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); extern int -ncx_pad_putn_short_schar (void **xpp, size_t nelems, const schar *ip); +ncx_pad_putn_short_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_pad_putn_short_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_pad_putn_short_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_pad_putn_short_short (void **xpp, size_t nelems, const short *ip); +ncx_pad_putn_short_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_pad_putn_short_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_pad_putn_short_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_pad_putn_short_int (void **xpp, size_t nelems, const int *ip); +ncx_pad_putn_short_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_pad_putn_short_uint (void **xpp, size_t nelems, const uint *ip); +ncx_pad_putn_short_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_pad_putn_short_long (void **xpp, size_t nelems, const long *ip); +ncx_pad_putn_short_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_pad_putn_short_float (void **xpp, size_t nelems, const float *ip); +ncx_pad_putn_short_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *ip); +ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_pad_putn_short_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_pad_putn_short_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /*---- ushort ---------------------------------------------------------------*/ extern int @@ -645,50 +654,50 @@ extern int ncx_pad_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_ushort_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_ushort_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_ushort_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_ushort_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_ushort_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_ushort_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_ushort_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_ushort_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_ushort_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_ushort_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_ushort_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_ushort_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_ushort_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_ushort_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_ushort_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_ushort_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_ushort_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_ushort_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); extern int -ncx_pad_putn_ushort_schar (void **xpp, size_t nelems, const schar *ip); +ncx_pad_putn_ushort_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_pad_putn_ushort_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_pad_putn_ushort_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_pad_putn_ushort_short (void **xpp, size_t nelems, const short *ip); +ncx_pad_putn_ushort_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_pad_putn_ushort_int (void **xpp, size_t nelems, const int *ip); +ncx_pad_putn_ushort_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_pad_putn_ushort_uint (void **xpp, size_t nelems, const uint *ip); +ncx_pad_putn_ushort_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_pad_putn_ushort_long (void **xpp, size_t nelems, const long *ip); +ncx_pad_putn_ushort_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_pad_putn_ushort_float (void **xpp, size_t nelems, const float *ip); +ncx_pad_putn_ushort_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *ip); +ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_pad_putn_ushort_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_pad_putn_ushort_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /*---- int ------------------------------------------------------------------*/ extern int @@ -717,29 +726,29 @@ extern int ncx_getn_int_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_int_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_int_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_int_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_int_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_int_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_int_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_int_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_int_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_int_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_int_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_int_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_int_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_int_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_int_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_long_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_long_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_int_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_int_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_int_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_int_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_int_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_int_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /*---- uint -----------------------------------------------------------------*/ extern int @@ -768,29 +777,29 @@ extern int ncx_getn_uint_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_uint_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_uint_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_uint_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_uint_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_uint_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_uint_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_uint_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_uint_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_uint_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_uint_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_uint_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_uint_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_uint_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_uint_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_long_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_long_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_uint_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_uint_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_uint_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_uint_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_uint_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_uint_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_uint_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_uint_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /*---- float ----------------------------------------------------------------*/ extern int @@ -817,27 +826,27 @@ extern int ncx_getn_float_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_float_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_float_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_float_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_float_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_float_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_float_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_float_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_float_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_float_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_float_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_float_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_float_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_float_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_float_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_float_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_float_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_float_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_float_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_float_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_float_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /*---- double ---------------------------------------------------------------*/ extern int @@ -864,27 +873,27 @@ extern int ncx_getn_double_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_double_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_double_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_double_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_double_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_double_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_double_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_double_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_double_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_double_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_double_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_double_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_double_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_double_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_double_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_double_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_double_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_double_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_double_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_double_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_double_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /*---- longlong ----------------------------------------------------------------*/ extern int @@ -911,27 +920,27 @@ extern int ncx_getn_longlong_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_longlong_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_longlong_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_longlong_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_longlong_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_longlong_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_longlong_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_longlong_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_longlong_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_longlong_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_longlong_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_longlong_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_longlong_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_longlong_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_longlong_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_longlong_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_longlong_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_longlong_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_longlong_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_longlong_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_longlong_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_longlong_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_longlong_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /*---- ulonglong ---------------------------------------------------------------*/ extern int @@ -958,27 +967,27 @@ extern int ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); extern int -ncx_putn_ulonglong_schar (void **xpp, size_t nelems, const schar *ip); +ncx_putn_ulonglong_schar (void **xpp, size_t nelems, const schar *ip, void *fillp); extern int -ncx_putn_ulonglong_uchar (void **xpp, size_t nelems, const uchar *ip); +ncx_putn_ulonglong_uchar (void **xpp, size_t nelems, const uchar *ip, void *fillp); extern int -ncx_putn_ulonglong_short (void **xpp, size_t nelems, const short *ip); +ncx_putn_ulonglong_short (void **xpp, size_t nelems, const short *ip, void *fillp); extern int -ncx_putn_ulonglong_ushort(void **xpp, size_t nelems, const ushort *ip); +ncx_putn_ulonglong_ushort(void **xpp, size_t nelems, const ushort *ip, void *fillp); extern int -ncx_putn_ulonglong_int (void **xpp, size_t nelems, const int *ip); +ncx_putn_ulonglong_int (void **xpp, size_t nelems, const int *ip, void *fillp); extern int -ncx_putn_ulonglong_uint (void **xpp, size_t nelems, const uint *ip); +ncx_putn_ulonglong_uint (void **xpp, size_t nelems, const uint *ip, void *fillp); extern int -ncx_putn_ulonglong_long (void **xpp, size_t nelems, const long *ip); +ncx_putn_ulonglong_long (void **xpp, size_t nelems, const long *ip, void *fillp); extern int -ncx_putn_ulonglong_float (void **xpp, size_t nelems, const float *ip); +ncx_putn_ulonglong_float (void **xpp, size_t nelems, const float *ip, void *fillp); extern int -ncx_putn_ulonglong_double(void **xpp, size_t nelems, const double *ip); +ncx_putn_ulonglong_double(void **xpp, size_t nelems, const double *ip, void *fillp); extern int -ncx_putn_ulonglong_longlong (void **xpp, size_t nelems, const longlong *ip); +ncx_putn_ulonglong_longlong (void **xpp, size_t nelems, const longlong *ip, void *fillp); extern int -ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); +ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *ip, void *fillp); /* @@ -986,21 +995,6 @@ ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); */ /* read ASCII characters */ -#ifdef __arm__ - -extern int -ncx_getn_text(const void **xpp, size_t nchars, signed char *cp); -extern int -ncx_pad_getn_text(const void **xpp, size_t nchars, signed char *cp); - -/* write ASCII characters */ -extern int -ncx_putn_text(void **xpp, size_t nchars, const signed char *cp); -extern int -ncx_pad_putn_text(void **xpp, size_t nchars, const signed char *cp); - -#else // ifdef __arm__ - extern int ncx_getn_text(const void **xpp, size_t nchars, char *cp); extern int @@ -1012,7 +1006,6 @@ ncx_putn_text(void **xpp, size_t nchars, const char *cp); extern int ncx_pad_putn_text(void **xpp, size_t nchars, const char *cp); -#endif //ifdef __arm__ /* for symmetry */ #define ncx_getn_char_char(xpp, nelems, fillp) ncx_getn_text(xpp, nelems, fillp) diff --git a/libsrc/ncx.m4 b/libsrc/ncx.m4 index 2abf546e6c..96308cda09 100644 --- a/libsrc/ncx.m4 +++ b/libsrc/ncx.m4 @@ -1,50 +1,127 @@ +dnl Process this m4 file to produce 'C' language file. dnl -dnl sjl: this version of ncx.m4 has SX-specific optimisations as per -dnl Harveys mods to earlier versions. However, I have removed -dnl support for FLOAT2 and attempted to tidy up the mods to -dnl reduce the complexity a bit -dnl -dnl This is m4 source. -dnl Process using m4 to produce 'C' language file. +dnl This file is supposed to be the same as PnetCDF's ncx.m4 dnl dnl If you see this line, you can ignore the next one. /* Do not edit this file. It is produced from the corresponding .m4 source */ dnl /* - * Copyright 1996, University Corporation for Atmospheric Research - * See netcdf/COPYRIGHT file for copying and redistribution conditions. - * - * This file contains some routines derived from code - * which is copyrighted by Sun Microsystems, Inc. - * The "#ifdef vax" versions of - * ncx_put_float_float() - * ncx_get_float_float() - * ncx_put_double_double() - * ncx_get_double_double() - * ncx_putn_float_float() - * ncx_getn_float_float() - * ncx_putn_double_double() - * ncx_getn_double_double() - * are derived from xdr_float() and xdr_double() routines - * in the freely available, copyrighted Sun RPCSRC 3.9 - * distribution, xdr_float.c. - * Our "value added" is that these are always memory to memory, - * they handle IEEE subnormals properly, and their "n" versions - * operate speedily on arrays. + * Copyright (C) 2014, Northwestern University and Argonne National Laboratory + * See COPYRIGHT notice in top-level directory. */ -/* $Id: ncx.m4 2795 2014-10-27 23:12:51Z wkliao $ */ +/* $Id: ncx.m4 2601 2016-11-07 04:54:42Z wkliao $ */ -/* - * An external data representation interface. - */ +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +dnl +dnl If the m4 macro "ERANGE_FILL" is defined, the I/O to data elements +dnl that cause NC_ERANGE will be filled with the NC default fill values. +dnl + +define(`SKIP_LOOP', `ifdef(`ERANGE_FILL', `$1++; $2++; continue;')') -#pragma GCC diagnostic ignored "-Wdeprecated" +dnl +dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF +dnl in terms of function prefix names (ncmpi_ vs. nc_), integer data types +dnl (MPI_Offset vs. size_t), and function name substrings for external data +dnl types. +dnl + +ifdef(`PNETCDF',` +`#'if HAVE_CONFIG_H +`#'include +`#'endif',` +`#'if HAVE_CONFIG_H +`#'include +`#'endif') -#include "ncx.h" -#include "nc3dispatch.h" +#include +#include #include #include +ifdef(`PNETCDF',` +`#'include "ncx.h" +`#'include "macro.h"',` +`#'pragma GCC diagnostic ignored "-Wdeprecated" +`#'include "ncx.h" +`#'include "nc3dispatch.h"') + +define(`IntType', `ifdef(`PNETCDF', `MPI_Offset', `size_t')')dnl +define(`APIPrefix',`ifdef(`PNETCDF', `ncmpi', `nc')')dnl +define(`NC_TYPE', `ifdef(`PNETCDF', `ifelse( +`$1', `schar', `NC_BYTE',dnl +`$1', `uchar', `NC_UBYTE',dnl +`$1', `short', `NC_SHORT',dnl +`$1', `ushort', `NC_USHORT',dnl +`$1', `int', `NC_INT',dnl +`$1', `uint', `NC_UINT',dnl +`$1', `float', `NC_FLOAT',dnl +`$1', `double', `NC_DOUBLE',dnl +`$1', `int64', `NC_INT64',dnl +`$1', `uint64', `NC_UINT64')',dnl +`ifelse( +`$1', `int64', `longlong',dnl +`$1', `uint64', `ulonglong',dnl +`$1')')')dnl + +ifdef(`PNETCDF',,`define(`DEBUG_RETURN_ERROR',`return $1;')') +ifdef(`PNETCDF',,`define(`DEBUG_ASSIGN_ERROR',`$1 = $2;')') + +#ifdef HAVE_INTTYPES_H +#include /* uint16_t, uint32_t, uint64_t */ +#elif defined(HAVE_STDINT_H) +#include /* uint16_t, uint32_t, uint64_t */ +#endif + +dnl +dnl *fillp is the fill value in internal representation +dnl +define(`FillValue', `ifdef(`ERANGE_FILL', `ifelse( +`$1', `schar', `if (fillp != NULL) memcpy($2, fillp, 1);',dnl +`$1', `uchar', `if (fillp != NULL) memcpy($2, fillp, 1);',dnl +`$1', `short', `if (fillp != NULL) memcpy($2, fillp, 2);',dnl +`$1', `ushort', `if (fillp != NULL) memcpy($2, fillp, 2);',dnl +`$1', `int', `if (fillp != NULL) memcpy($2, fillp, 4);',dnl +`$1', `uint', `if (fillp != NULL) memcpy($2, fillp, 4);',dnl +`$1', `long', `if (fillp != NULL) memcpy($2, fillp, SIZEOF_LONG);', dnl +`$1', `ulong', `if (fillp != NULL) memcpy($2, fillp, SIZEOF_ULONG);',dnl +`$1', `float', `if (fillp != NULL) memcpy($2, fillp, 4);',dnl +`$1', `double', `if (fillp != NULL) memcpy($2, fillp, 8);',dnl +`$1', `longlong', `if (fillp != NULL) memcpy($2, fillp, 8);',dnl +`$1', `int64', `if (fillp != NULL) memcpy($2, fillp, 8);',dnl +`$1', `ulonglong', `if (fillp != NULL) memcpy($2, fillp, 8);',dnl +`$1', `uint64', `if (fillp != NULL) memcpy($2, fillp, 8);')')')dnl + +dnl +dnl +define(`FillDefaultValue', `ifelse( +`$1', `schar', `NC_FILL_BYTE', +`$1', `uchar', `NC_FILL_UBYTE', +`$1', `short', `NC_FILL_SHORT', +`$1', `ushort', `NC_FILL_USHORT', +`$1', `int', `NC_FILL_INT', +`$1', `uint', `NC_FILL_UINT', +`$1', `long', `NC_FILL_INT', +`$1', `ulong', `NC_FILL_UINT', +`$1', `float', `NC_FILL_FLOAT', +`$1', `double', `NC_FILL_DOUBLE', +`$1', `longlong', `NC_FILL_INT64', +`$1', `int64', `NC_FILL_INT64', +`$1', `ulonglong', `NC_FILL_UINT64', +`$1', `uint64', `NC_FILL_UINT64')')dnl + +/* + * The only error code returned from subroutines in this file is NC_ERANGE, + * if errors are detected. + */ + +/* + * An external data representation interface. + */ + /* alias poorly named limits.h macros */ #define SHORT_MAX SHRT_MAX #define SHORT_MIN SHRT_MIN @@ -92,14 +169,66 @@ dnl #define Min(a,b) ((a) < (b) ? (a) : (b)) #define Max(a,b) ((a) > (b) ? (a) : (b)) +#ifndef SIZEOF_UCHAR +#ifdef SIZEOF_UNSIGNED_CHAR +#define SIZEOF_UCHAR SIZEOF_UNSIGNED_CHAR +#else +#error "unknown SIZEOF_UCHAR" +#endif +#endif + #ifndef SIZEOF_USHORT +#ifdef SIZEOF_UNSIGNED_SHORT_INT #define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT_INT +#elif defined(SIZEOF_UNSIGNED_SHORT) +#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT +#else +#error "unknown SIZEOF_USHORT" +#endif #endif + #ifndef SIZEOF_UINT +#ifdef SIZEOF_UNSIGNED_INT #define SIZEOF_UINT SIZEOF_UNSIGNED_INT +#else +#error "unknown SIZEOF_UINT" +#endif +#endif + +#ifndef SIZEOF_LONGLONG +#ifdef SIZEOF_LONG_LONG +#define SIZEOF_LONGLONG SIZEOF_LONG_LONG +#else +#error "unknown SIZEOF_LONGLONG" +#endif +#endif + +#ifndef SIZEOF_INT64 +#ifdef SIZEOF_LONG_LONG +#define SIZEOF_INT64 SIZEOF_LONG_LONG +#elif defined(SIZEOF_LONGLONG) +#define SIZEOF_INT64 SIZEOF_LONGLONG +#else +#error "unknown SIZEOF_INT64" +#endif +#endif + +#ifndef SIZEOF_ULONGLONG +#ifdef SIZEOF_UNSIGNED_LONG_LONG +#define SIZEOF_ULONGLONG SIZEOF_UNSIGNED_LONG_LONG +#else +#error "unknown SIZEOF_ULONGLONG" +#endif +#endif + +#ifndef SIZEOF_UINT64 +#ifdef SIZEOF_UNSIGNED_LONG_LONG +#define SIZEOF_UINT64 SIZEOF_UNSIGNED_LONG_LONG +#elif defined(SIZEOF_ULONGLONG) +#define SIZEOF_UINT64 SIZEOF_ULONGLONG +#else +#error "unknown SIZEOF_UINT64" #endif -#ifndef SIZEOF_ULONG_LONG -#define SIZEOF_ULONG_LONG SIZEOF_UNSIGNED_LONG_LONG #endif /* @@ -113,7 +242,7 @@ dnl # define X_FLOAT_MIN (-X_FLOAT_MAX) #endif -#if _SX /* NEC SUPER UX */ +#if defined(_SX) && _SX != 0 /* NEC SUPER UX */ #define LOOPCNT 256 /* must be no longer than hardware vector length */ #if _INT64 #undef INT_MAX /* workaround cpp bug */ @@ -140,34 +269,52 @@ static const char nada[X_ALIGN] = {0, 0, 0, 0}; #ifndef WORDS_BIGENDIAN /* LITTLE_ENDIAN: DEC and intel */ /* - * Routines to convert to BIGENDIAN. - * Optimize the swapn?b() and swap?b() routines aggressivly. + * Routines to convert to BIG ENDIAN. + * Optimize the swapn?b() and swap?b() routines aggressively. */ #define SWAP2(a) ( (((a) & 0xff) << 8) | \ - (((a) >> 8) & 0xff) ) + (((a) >> 8) & 0xff) ) #define SWAP4(a) ( ((a) << 24) | \ - (((a) << 8) & 0x00ff0000) | \ - (((a) >> 8) & 0x0000ff00) | \ - (((a) >> 24) & 0x000000ff) ) - - -static void -swapn2b(void *dst, const void *src, size_t nn) -{ + (((a) << 8) & 0x00ff0000) | \ + (((a) >> 8) & 0x0000ff00) | \ + (((a) >> 24) & 0x000000ff) ) + +#define SWAP8(a) ( (((a) & 0x00000000000000FFULL) << 56) | \ + (((a) & 0x000000000000FF00ULL) << 40) | \ + (((a) & 0x0000000000FF0000ULL) << 24) | \ + (((a) & 0x00000000FF000000ULL) << 8) | \ + (((a) & 0x000000FF00000000ULL) >> 8) | \ + (((a) & 0x0000FF0000000000ULL) >> 24) | \ + (((a) & 0x00FF000000000000ULL) >> 40) | \ + (((a) & 0xFF00000000000000ULL) >> 56) ) + + +inline static void +swapn2b(void *dst, const void *src, IntType nn) +{ + /* it is OK if dst == src */ + int i; + uint16_t *op = (uint16_t*) dst; + uint16_t *ip = (uint16_t*) src; + for (i=0; i 0) * { * *op++ = *(++ip); * *op++ = *(ip++ -1); * } */ - while(nn > 3) + while (nn > 3) { *op++ = *(++ip); *op++ = *(ip++ -1); @@ -179,35 +326,79 @@ swapn2b(void *dst, const void *src, size_t nn) *op++ = *(ip++ -1); nn -= 4; } - while(nn-- > 0) + while (nn-- > 0) { *op++ = *(++ip); *op++ = *(ip++ -1); } +#endif } # ifndef vax -void +inline static void swap4b(void *dst, const void *src) { - uint32_t* op32 = (uint32_t*)(dst); - const uint32_t* ip32 = (const uint32_t*)(src); + /* copy over, make the below swap in-place */ + uint32_t tmp = *(uint32_t*)src; + tmp = SWAP4(tmp); + memcpy(dst, &tmp, 4); + + /* Codes below will cause "break strict-aliasing rules" in gcc + uint32_t *op = (uint32_t*)dst; + *op = *(uint32_t*)src; + *op = SWAP4(*op); + */ + + /* Below are copied from netCDF-4. + * See https://bugtracking.unidata.ucar.edu/browse/NCF-338 + * Quote "One issue we are wrestling with is how compilers optimize this + * code. For some reason, we are actually needing to add an artificial + * move to a 4 byte space to get it to work. I think what is happening is + * that the optimizer is bit shifting within a double, which is incorrect. + * The following code actually does work correctly. + * This is in Linux land, gcc. + * + * However, the above in-place byte-swap does not appear affected by this. + */ +#if 0 + uint32_t *ip = (uint32_t*)src; + uint32_t tempOut; /* cannot use pointer when gcc O2 optimizer is used */ + tempOut = SWAP4(*ip); + + *(float *)dst = *(float *)(&tempOut); +#endif + + /* OLD implementation that results in four load and four store CPU + instructions + char *op = dst; + const char *ip = src; + op[0] = ip[3]; + op[1] = ip[2]; + op[2] = ip[1]; + op[3] = ip[0]; + */ - *op32 = (((*ip32) ) << 24) | - (((*ip32) & 0x0000ff00u) << 8) | - (((*ip32) & 0x00ff0000u) >> 8) | - (((*ip32) ) >> 24); } # endif /* !vax */ -static void -swapn4b(void *dst, const void *src, size_t nn) +inline static void +swapn4b(void *dst, const void *src, IntType nn) { + int i; + uint32_t *op = (uint32_t*) dst; + uint32_t *ip = (uint32_t*) src; + for (i=0; i 0) * { * op[0] = ip[3]; * op[1] = ip[2]; @@ -217,7 +408,7 @@ swapn4b(void *dst, const void *src, size_t nn) * ip += 4; * } */ - while(nn > 3) + while (nn > 3) { op[0] = ip[3]; op[1] = ip[2]; @@ -239,7 +430,7 @@ swapn4b(void *dst, const void *src, size_t nn) ip += 16; nn -= 4; } - while(nn-- > 0) + while (nn-- > 0) { op[0] = ip[3]; op[1] = ip[2]; @@ -248,12 +439,29 @@ swapn4b(void *dst, const void *src, size_t nn) op += 4; ip += 4; } +#endif } # ifndef vax -static void +inline static void swap8b(void *dst, const void *src) { +#ifdef FLOAT_WORDS_BIGENDIAN + /* copy over, make the below swap in-place */ + *(uint64_t*)dst = *(uint64_t*)src; + + uint32_t *op = (uint32_t*)dst; + *op = SWAP4(*op); + op = (uint32_t*)((char*)dst+4); + *op = SWAP4(*op); +#else + uint64_t *op = (uint64_t*)dst; + /* copy over, make the below swap in-place */ + *op = *(uint64_t*)src; + *op = SWAP8(*op); +#endif + +#if 0 char *op = dst; const char *ip = src; # ifndef FLOAT_WORDS_BIGENDIAN @@ -274,19 +482,44 @@ swap8b(void *dst, const void *src) op[5] = ip[6]; op[6] = ip[5]; op[7] = ip[4]; -# endif +#endif +#endif } # endif /* !vax */ # ifndef vax -static void -swapn8b(void *dst, const void *src, size_t nn) -{ +inline static void +swapn8b(void *dst, const void *src, IntType nn) +{ +#ifdef FLOAT_WORDS_BIGENDIAN + int i; + uint64_t *dst_p = (uint64_t*) dst; + uint64_t *src_p = (uint64_t*) src; + for (i=0; i 0) * { * op[0] = ip[7]; * op[1] = ip[6]; @@ -301,7 +534,7 @@ swapn8b(void *dst, const void *src, size_t nn) * } */ # ifndef FLOAT_WORDS_BIGENDIAN - while(nn > 1) + while (nn > 1) { op[0] = ip[7]; op[1] = ip[6]; @@ -323,7 +556,7 @@ swapn8b(void *dst, const void *src, size_t nn) ip += 16; nn -= 2; } - while(nn-- != 0) + while (nn-- > 0) { op[0] = ip[7]; op[1] = ip[6]; @@ -337,7 +570,7 @@ swapn8b(void *dst, const void *src, size_t nn) ip += 8; } # else - while(nn-- != 0) + while (nn-- > 0) { op[0] = ip[3]; op[1] = ip[2]; @@ -350,7 +583,8 @@ swapn8b(void *dst, const void *src, size_t nn) op += 8; ip += 8; } -# endif +#endif +#endif } # endif /* !vax */ @@ -376,57 +610,37 @@ define(`Xmin', ``X_'Upcase($1)`_MIN'')dnl define(`IXmax', ``IX_'Upcase($1)`_MAX'')dnl dnl define(`Fmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Imin($1)')')dnl -define(`Dmin', `ifelse(index(`$1',`u'), 0, `0', `Imin($1)')')dnl +define(`Dmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Imin($1)')')dnl define(`FXmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Xmin($1)')')dnl define(`DXmin', `ifelse(index(`$1',`u'), 0, `0', `Xmin($1)')')dnl -dnl -dnl For GET APIs: -dnl check for negative xx if xp is signed && ip is unsigned -dnl Don't check for negative xx if xp is signed && ip is signed -dnl Don't check for negative xx if xp is unsigned -dnl -define(`GETI_CheckNeg', `ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, ` if (xx < 0) return NC_ERANGE; /* because ip is unsigned */')')')dnl - -dnl -dnl For PUT APIs: -dnl check for negative ip if xp is unsigned && ip is signed -dnl Don't check for negative ip if xp is unsigned && ip is unsigned -dnl Don't check for negative ip if xp is signed -dnl -define(`PUTI_CheckNeg', `ifelse(index(`$1',`u'), 0, `ifelse(index(`$2',`u'), 0, , ` if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */')')')dnl +define(`Cast_Signed2Unsigned', + `ifelse(index(`$1',`u'), 0, + `ifelse(index(`$2',`u'), 0, , `(signed)')')')dnl dnl -dnl For GET APIs and either $1 and $2 is float or double: +dnl For GET APIs boundary check dnl define(`GETF_CheckBND', -`ifelse(`$1', `double', ` if(xx > Upcase($2)_MAX || xx < Dmin($2)) return NC_ERANGE;', - `ifelse(`$1', `float', `ifelse(`$2', `double',,` if(xx > (double)Upcase($2)_MAX || xx < Fmin($2)) return NC_ERANGE;')')'dnl -)') - -dnl -dnl For PUT APIs and either $1 and $2 is float or double: -dnl -define(`PUTF_CheckBND', -`ifelse(`$2', `double', ` if(*ip > Xmax($1) || *ip < DXmin($1)) return NC_ERANGE;', - `ifelse(`$2', `float', ` if(*ip > (double)Xmax($1) || *ip < FXmin($1)) return NC_ERANGE;')'dnl -)') - -dnl -dnl For GET APIs and $1 and $2 are not float or double -dnl -define(`GETI_CheckBND', -``#'if IXmax($1) > Imax($2) - if (xx > Imax($2)'`ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, , ` || xx < Imin($2)')')'`) return NC_ERANGE;' -`#'endif) - -dnl -dnl For PUT APIs and $1 and $2 are not float or double -dnl -define(`PUTI_CheckBND', -``#'if IXmax($1) < Imax($2) - if (*ip > IXmax($1)'`ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, , ` || *ip < Xmin($1)')')'`) return NC_ERANGE;' -`#'endif) +`if (xx > (double)Upcase($1)_MAX || xx < Dmin($1)) { + ifdef(`ERANGE_FILL',`*ip = FillDefaultValue($1);') + DEBUG_RETURN_ERROR(NC_ERANGE) + } + *ip = ($1)xx;')dnl + +dnl +dnl For GET APIs boudnary check for when $1 is either 'longlong' or 'ulonglong' +dnl +define(`GETF_CheckBND2', + `ifelse(index(`$1',`u'), 0, +`if (xx == Upcase($1)_MAX) *ip = Upcase($1)_MAX;',dnl for unsigned type +`if (xx == Upcase($1)_MAX) *ip = Upcase($1)_MAX; + else if (xx == Upcase($1)_MIN) *ip = Upcase($1)_MIN;') + else if (xx > (double)Upcase($1)_MAX || xx < Dmin($1)) { + ifdef(`ERANGE_FILL',`*ip = FillDefaultValue($1);') + DEBUG_RETURN_ERROR(NC_ERANGE) + } + else *ip = ($1)xx;') /* * Primitive numeric conversion functions. @@ -438,13 +652,19 @@ dnl NCX_GET1F(xtype, itype) for floating-point types dnl define(`NCX_GET1F',dnl `dnl -int -ncx_get_$1_$2(const void *xp, $2 *ip) +static int +APIPrefix`x_get_'NC_TYPE($1)_$2(const void *xp, $2 *ip) { ix_$1 xx; get_ix_$1(xp, &xx); - *ip = ($2) xx; -GETF_CheckBND($1, $2) + ifelse(`$1', `float', `ifelse(`$2', `longlong', GETF_CheckBND2($2), + `$2', `ulonglong', GETF_CheckBND2($2), + `$2', `double', `*ip = ($2)xx;', + GETF_CheckBND($2))', + `$1', `double', `ifelse(`$2', `longlong', GETF_CheckBND2($2), + `$2', `ulonglong', GETF_CheckBND2($2), + GETF_CheckBND($2))', + `*ip = ($2)xx;') return NC_NOERR; } ')dnl @@ -455,23 +675,41 @@ dnl NCX_GET1I(xtype, itype, isComptable) for integral types dnl define(`NCX_GET1I',dnl `dnl -int -ncx_get_$1_$2(const void *xp, $2 *ip) +static int +APIPrefix`x_get_'NC_TYPE($1)_$2(const void *xp, $2 *ip) { + int err=NC_NOERR; ifelse(`$3', `1', ``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX - get_ix_$1(xp, (ix_$1 *)ip); - return NC_NOERR; + get_ix_$1(xp, (ix_$1 *)ip); `#'else ')dnl - ix_$1 xx; - get_ix_$1(xp, &xx); - *ip = ($2) xx; -GETI_CheckBND($1, $2) -GETI_CheckNeg($1, $2) -ifelse(`$3', `1', ``#'endif + ix_$1 xx; + get_ix_$1(xp, &xx); + +`#'if IXmax($1) > Imax($2) + if (xx > Imax($2)'`ifelse(index(`$1',`u'), 0, , + index(`$2',`u'), 0, , + ` || xx < Imin($2)')'`) { +ifdef(`ERANGE_FILL',`dnl + *ip = FillDefaultValue($2); + DEBUG_RETURN_ERROR(NC_ERANGE)',` + DEBUG_ASSIGN_ERROR(err, NC_ERANGE)') + }' +`#'endif + +`ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0,`dnl + if (xx < 0) { +ifdef(`ERANGE_FILL',`dnl + *ip = FillDefaultValue($2); + DEBUG_RETURN_ERROR(NC_ERANGE)',` + DEBUG_ASSIGN_ERROR(err, NC_ERANGE)') /* because ip is unsigned */ + }')'dnl + + *ip = ($2) xx; +`ifelse(`$3', `1', ``#'endif ')dnl - return NC_NOERR; + return err; } ')dnl @@ -481,13 +719,24 @@ dnl NCX_PUT1F(xtype, itype) for floating-point types dnl define(`NCX_PUT1F',dnl `dnl -int -ncx_put_$1_$2(void *xp, const $2 *ip) +static int +APIPrefix`x_put_'NC_TYPE($1)_$2(void *xp, const $2 *ip, void *fillp) { - ix_$1 xx = (ix_$1)*ip; - put_ix_$1(xp, &xx); -PUTF_CheckBND($1, $2) - return NC_NOERR; + int err=NC_NOERR; + ix_$1 xx = FillDefaultValue($1); + + ifelse(`$2', `double', `if (*ip > Xmax($1) || *ip < DXmin($1)) { + FillValue($1, &xx) + DEBUG_ASSIGN_ERROR(err, NC_ERANGE) + } ifdef(`ERANGE_FILL',`else')', + `$2', `float', `if (*ip > (double)Xmax($1) || *ip < FXmin($1)) { + FillValue($1, &xx) + DEBUG_ASSIGN_ERROR(err, NC_ERANGE) + } ifdef(`ERANGE_FILL',`else')') + xx = (ix_$1)*ip; + + put_ix_$1(xp, &xx); + return err; } ')dnl @@ -497,22 +746,37 @@ dnl NCX_PUT1I(xtype, itype, isComptable) for integral types dnl define(`NCX_PUT1I',dnl `dnl -int -ncx_put_$1_$2(void *xp, const $2 *ip) +static int +APIPrefix`x_put_'NC_TYPE($1)_$2(void *xp, const $2 *ip, void *fillp) { + int err=NC_NOERR; ifelse(`$3', `1', ``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX - put_ix_$1(xp, (const ix_$1 *)ip); - return NC_NOERR; + put_ix_$1(xp, (const ix_$1 *)ip); `#'else ')dnl - ix_$1 xx = (ix_$1)*ip; - put_ix_$1(xp, &xx); -PUTI_CheckBND($1, $2) -PUTI_CheckNeg($1, $2) + ix_$1 xx = FillDefaultValue($1); + +`#'if IXmax($1) < Imax($2) + if (*ip > IXmax($1)'`ifelse(index(`$1',`u'), 0, , + index(`$2',`u'), 0, , + ` || *ip < Xmin($1)')'`) { + FillValue($1, &xx) + DEBUG_ASSIGN_ERROR(err, NC_ERANGE) + } ifdef(`ERANGE_FILL',`else') +`#'endif +ifelse(index(`$1',`u'), 0, `ifelse(index(`$2',`u'), 0, ,`dnl + if (*ip < 0) { + FillValue($1, &xx) + DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */ + } ifdef(`ERANGE_FILL',`else') +')')dnl + xx = (ix_$1)*ip; + + put_ix_$1(xp, &xx); ifelse(`$3', `1', ``#'endif ')dnl - return NC_NOERR; + return err; } ')dnl @@ -522,7 +786,7 @@ ifelse(`$3', `1', ``#'endif /* We don't implement any x_schar and x_uchar primitives. */ -/* x_short -------------------------------------------------------------------*/ +/* external NC_SHORT --------------------------------------------------------*/ #if SHORT_MAX == X_SHORT_MAX typedef short ix_short; @@ -538,7 +802,7 @@ typedef long ix_short; #define IX_SHORT_MAX LONG_MAX #elif LLONG_MAX >= X_SHORT_MAX typedef long long ix_short; -#define SIZEOF_IX_SHORT SIZEOF_LONG_LONG +#define SIZEOF_IX_SHORT SIZEOF_LONGLONG #define IX_SHORT_MAX LLONG_MAX #else #error "ix_short implementation" @@ -548,50 +812,51 @@ static void get_ix_short(const void *xp, ix_short *ip) { const uchar *cp = (const uchar *) xp; - *ip = *cp++ << 8; + *ip = (ix_short)(*cp++ << 8); #if SIZEOF_IX_SHORT > X_SIZEOF_SHORT - if(*ip & 0x8000) + if (*ip & 0x8000) { /* extern is negative */ *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */ } #endif - *ip |= *cp; + *ip = (ix_short)(*ip | *cp); } static void put_ix_short(void *xp, const ix_short *ip) { uchar *cp = (uchar *) xp; - *cp++ = (*ip) >> 8; - *cp = (*ip) & 0xff; -} - -static NCX_GET1I(short, schar, 0) -static NCX_GET1I(short, short, 1) -static NCX_GET1I(short, int, 1) -static NCX_GET1I(short, longlong, 1) -static NCX_GET1I(short, ushort, 0) -static NCX_GET1I(short, uchar, 0) -static NCX_GET1I(short, uint, 0) -static NCX_GET1I(short, ulonglong, 0) -static NCX_GET1F(short, float) -static NCX_GET1F(short, double) + *cp++ = (uchar)((*ip) >> 8); + *cp = (uchar)((*ip) & 0xff); +} + +NCX_GET1I(short, schar, 0) +NCX_GET1I(short, short, 1) +NCX_GET1I(short, int, 1) +NCX_GET1I(short, long, 1) +NCX_GET1I(short, longlong, 1) +NCX_GET1I(short, ushort, 0) +NCX_GET1I(short, uchar, 0) +NCX_GET1I(short, uint, 0) +NCX_GET1I(short, ulonglong, 0) +NCX_GET1F(short, float) +NCX_GET1F(short, double) static int -ncx_put_short_schar(void *xp, const schar *ip) +APIPrefix`x_put_'NC_TYPE(short)_schar(void *xp, const schar *ip, void *fillp) { uchar *cp = (uchar *) xp; - if(*ip & 0x80) + if (*ip & 0x80) *cp++ = 0xff; else *cp++ = 0; - *cp = (uchar)(signed)*ip; + *cp = (uchar)*ip; return NC_NOERR; } static int -ncx_put_short_uchar(void *xp, const uchar *ip) +APIPrefix`x_put_'NC_TYPE(short)_uchar(void *xp, const uchar *ip, void *fillp) { uchar *cp = (uchar *) xp; *cp++ = 0; @@ -599,16 +864,17 @@ ncx_put_short_uchar(void *xp, const uchar *ip) return NC_NOERR; } -static NCX_PUT1I(short, short, 1) -static NCX_PUT1I(short, int, 1) -static NCX_PUT1I(short, longlong, 1) -static NCX_PUT1I(short, ushort, 0) -static NCX_PUT1I(short, uint, 0) -static NCX_PUT1I(short, ulonglong, 0) -static NCX_PUT1F(short, float) -static NCX_PUT1F(short, double) +NCX_PUT1I(short, short, 1) +NCX_PUT1I(short, int, 1) +NCX_PUT1I(short, long, 1) +NCX_PUT1I(short, longlong, 1) +NCX_PUT1I(short, ushort, 0) +NCX_PUT1I(short, uint, 0) +NCX_PUT1I(short, ulonglong, 0) +NCX_PUT1F(short, float) +NCX_PUT1F(short, double) -/* x_ushort ------------------------------------------------------------------*/ +/* external NC_USHORT -------------------------------------------------------*/ #if USHORT_MAX == X_USHORT_MAX typedef unsigned short ix_ushort; @@ -624,7 +890,7 @@ typedef unsigned long ix_ushort; #define IX_USHORT_MAX ULONG_MAX #elif ULLONG_MAX >= X_USHORT_MAX typedef unsigned long long ix_ushort; -#define SIZEOF_IX_USHORT SIZEOF_ULONG_LONG +#define SIZEOF_IX_USHORT SIZEOF_ULONGLONG #define IX_USHORT_MAX ULLONG_MAX #else #error "ix_ushort implementation" @@ -634,52 +900,64 @@ static void get_ix_ushort(const void *xp, ix_ushort *ip) { const uchar *cp = (const uchar *) xp; - *ip = *cp++ << 8; + *ip = (ix_ushort)(*cp++ << 8); #if SIZEOF_IX_SHORT > X_SIZEOF_SHORT - if(*ip & 0x8000) + if (*ip & 0x8000) { /* extern is negative */ *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */ } #endif - *ip |= *cp; + *ip = (ix_ushort)(*ip | *cp); } static void put_ix_ushort(void *xp, const ix_ushort *ip) { uchar *cp = (uchar *) xp; - *cp++ = (*ip) >> 8; - *cp = (*ip) & 0xff; -} - -static NCX_GET1I(ushort, schar, 0) -static NCX_GET1I(ushort, short, 0) -static NCX_GET1I(ushort, int, 0) -static NCX_GET1I(ushort, longlong, 0) -static NCX_GET1I(ushort, ushort, 1) -static NCX_GET1I(ushort, uchar, 1) -static NCX_GET1I(ushort, uint, 1) -static NCX_GET1I(ushort, ulonglong, 1) -static NCX_GET1F(ushort, float) -static NCX_GET1F(ushort, double) + *cp++ = (uchar)((*ip) >> 8); + *cp = (uchar)((*ip) & 0xff); +} + +NCX_GET1I(ushort, schar, 0) +NCX_GET1I(ushort, short, 0) +NCX_GET1I(ushort, int, 0) +NCX_GET1I(ushort, long, 0) +NCX_GET1I(ushort, longlong, 0) +NCX_GET1I(ushort, ushort, 1) +NCX_GET1I(ushort, uchar, 1) +NCX_GET1I(ushort, uint, 1) +NCX_GET1I(ushort, ulonglong, 1) +NCX_GET1F(ushort, float) +NCX_GET1F(ushort, double) static int -ncx_put_ushort_schar(void *xp, const schar *ip) +APIPrefix`x_put_'NC_TYPE(ushort)_schar(void *xp, const schar *ip, void *fillp) { - uchar *cp = (uchar *) xp; - if(*ip & 0x80) - *cp++ = 0xff; - else - *cp++ = 0; - *cp = (uchar)(signed)*ip; - if (*ip < 0) return NC_ERANGE; + int err=NC_NOERR; + uchar *cp; + if (*ip < 0) { +ifdef(`ERANGE_FILL', `dnl + if (fillp != NULL) memcpy(xp, fillp, 2); +#ifndef WORDS_BIGENDIAN + swapn2b(xp, xp, 1); +#endif + DEBUG_RETURN_ERROR(NC_ERANGE)',`dnl + DEBUG_ASSIGN_ERROR(err, NC_ERANGE)') + } - return NC_NOERR; + cp = (uchar *) xp; + if (*ip & 0x80) + *cp++ = 0xff; + else + *cp++ = 0; + *cp = (uchar)*ip; + + return err; } static int -ncx_put_ushort_uchar(void *xp, const uchar *ip) +APIPrefix`x_put_'NC_TYPE(ushort)_uchar(void *xp, const uchar *ip, void *fillp) { uchar *cp = (uchar *) xp; *cp++ = 0; @@ -687,16 +965,17 @@ ncx_put_ushort_uchar(void *xp, const uchar *ip) return NC_NOERR; } -static NCX_PUT1I(ushort, short, 0) -static NCX_PUT1I(ushort, int, 0) -static NCX_PUT1I(ushort, longlong, 0) -static NCX_PUT1I(ushort, ushort, 1) -static NCX_PUT1I(ushort, uint, 1) -static NCX_PUT1I(ushort, ulonglong, 1) -static NCX_PUT1F(ushort, float) -static NCX_PUT1F(ushort, double) +NCX_PUT1I(ushort, short, 0) +NCX_PUT1I(ushort, int, 0) +NCX_PUT1I(ushort, long, 0) +NCX_PUT1I(ushort, longlong, 0) +NCX_PUT1I(ushort, ushort, 1) +NCX_PUT1I(ushort, uint, 1) +NCX_PUT1I(ushort, ulonglong, 1) +NCX_PUT1F(ushort, float) +NCX_PUT1F(ushort, double) -/* x_int ---------------------------------------------------------------------*/ +/* external NC_INT ----------------------------------------------------------*/ #if SHORT_MAX == X_INT_MAX typedef short ix_int; @@ -722,7 +1001,7 @@ get_ix_int(const void *xp, ix_int *ip) *ip = *cp++ << 24; #if SIZEOF_IX_INT > X_SIZEOF_INT - if(*ip & 0x80000000) + if (*ip & 0x80000000) { /* extern is negative */ *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */ @@ -738,28 +1017,31 @@ put_ix_int(void *xp, const ix_int *ip) { uchar *cp = (uchar *) xp; - *cp++ = (*ip) >> 24; - *cp++ = ((*ip) & 0x00ff0000) >> 16; - *cp++ = ((*ip) & 0x0000ff00) >> 8; - *cp = ((*ip) & 0x000000ff); + *cp++ = (uchar)( (*ip) >> 24); + *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16); + *cp++ = (uchar)(((*ip) & 0x0000ff00) >> 8); + *cp = (uchar)( (*ip) & 0x000000ff); } -static NCX_GET1I(int, schar, 0) -static NCX_GET1I(int, short, 1) - NCX_GET1I(int, int, 1) -static NCX_GET1I(int, longlong, 1) -static NCX_GET1I(int, ushort, 0) -static NCX_GET1I(int, uchar, 0) -static NCX_GET1I(int, uint, 0) -static NCX_GET1I(int, ulonglong, 0) -static NCX_GET1F(int, float) -static NCX_GET1F(int, double) +#if X_SIZEOF_INT != SIZEOF_INT +NCX_GET1I(int, int, 1) +#endif +NCX_GET1I(int, schar, 0) +NCX_GET1I(int, short, 1) +NCX_GET1I(int, long, 1) +NCX_GET1I(int, longlong, 1) +NCX_GET1I(int, ushort, 0) +NCX_GET1I(int, uchar, 0) +NCX_GET1I(int, uint, 0) +NCX_GET1I(int, ulonglong, 0) +NCX_GET1F(int, float) +NCX_GET1F(int, double) static int -ncx_put_int_schar(void *xp, const schar *ip) +APIPrefix`x_put_'NC_TYPE(int)_schar(void *xp, const schar *ip, void *fillp) { uchar *cp = (uchar *) xp; - if(*ip & 0x80) + if (*ip & 0x80) { *cp++ = 0xff; *cp++ = 0xff; @@ -771,12 +1053,12 @@ ncx_put_int_schar(void *xp, const schar *ip) *cp++ = 0x00; *cp++ = 0x00; } - *cp = (uchar)(signed)*ip; + *cp = (uchar)*ip; return NC_NOERR; } static int -ncx_put_int_uchar(void *xp, const uchar *ip) +APIPrefix`x_put_'NC_TYPE(int)_uchar(void *xp, const uchar *ip, void *fillp) { uchar *cp = (uchar *) xp; *cp++ = 0x00; @@ -786,17 +1068,20 @@ ncx_put_int_uchar(void *xp, const uchar *ip) return NC_NOERR; } -static NCX_PUT1I(int, short, 1) - NCX_PUT1I(int, int, 1) -static NCX_PUT1I(int, longlong, 1) -static NCX_PUT1I(int, ushort, 0) -static NCX_PUT1I(int, uint, 0) -static NCX_PUT1I(int, ulonglong, 0) -static NCX_PUT1F(int, float) -static NCX_PUT1F(int, double) +#if X_SIZEOF_INT != SIZEOF_INT +NCX_PUT1I(int, int, 1) +#endif +NCX_PUT1I(int, short, 1) +NCX_PUT1I(int, long, 1) +NCX_PUT1I(int, longlong, 1) +NCX_PUT1I(int, ushort, 0) +NCX_PUT1I(int, uint, 0) +NCX_PUT1I(int, ulonglong, 0) +NCX_PUT1F(int, float) +NCX_PUT1F(int, double) -/* x_uint --------------------------------------------------------------------*/ +/* external NC_UINT ---------------------------------------------------------*/ #if USHORT_MAX == X_UINT_MAX typedef ushort ix_uint; @@ -820,10 +1105,10 @@ get_ix_uint(const void *xp, ix_uint *ip) { const uchar *cp = (const uchar *) xp; - *ip = *cp++ << 24; - *ip |= (*cp++ << 16); - *ip |= (*cp++ << 8); - *ip |= *cp; + *ip = (ix_uint)(*cp++ << 24); + *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 16)); + *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 8)); + *ip = (ix_uint)(*ip | *cp); } static void @@ -831,42 +1116,51 @@ put_ix_uint(void *xp, const ix_uint *ip) { uchar *cp = (uchar *) xp; - *cp++ = (*ip) >> 24; - *cp++ = ((*ip) & 0x00ff0000) >> 16; - *cp++ = ((*ip) & 0x0000ff00) >> 8; - *cp = ((*ip) & 0x000000ff); + *cp++ = (uchar)((*ip) >> 24); + *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16); + *cp++ = (uchar)(((*ip) & 0x0000ff00) >> 8); + *cp = (uchar)( (*ip) & 0x000000ff); } #if X_SIZEOF_UINT != SIZEOF_UINT -static NCX_GET1I(uint, uint, 1) +NCX_GET1I(uint, uint, 1) #endif -static NCX_GET1I(uint, schar, 0) -static NCX_GET1I(uint, short, 0) -static NCX_GET1I(uint, int, 0) -static NCX_GET1I(uint, longlong, 0) -static NCX_GET1I(uint, ushort, 1) -static NCX_GET1I(uint, uchar, 1) -static NCX_GET1I(uint, ulonglong, 1) -static NCX_GET1F(uint, float) -static NCX_GET1F(uint, double) +NCX_GET1I(uint, schar, 0) +NCX_GET1I(uint, short, 0) +NCX_GET1I(uint, int, 0) +NCX_GET1I(uint, long, 0) +NCX_GET1I(uint, longlong, 0) +NCX_GET1I(uint, ushort, 1) +NCX_GET1I(uint, uchar, 1) +NCX_GET1I(uint, ulonglong, 1) +NCX_GET1F(uint, float) +NCX_GET1F(uint, double) static int -ncx_put_uint_schar(void *xp, const schar *ip) +APIPrefix`x_put_'NC_TYPE(uint)_schar(void *xp, const schar *ip, void *fillp) { - uchar *cp = (uchar *) xp; - *cp++ = 0x00; - *cp++ = 0x00; - *cp++ = 0x00; - *cp = (uchar)(signed)*ip; + uchar *cp; + if (*ip < 0) { +ifdef(`ERANGE_FILL', `dnl + if (fillp != NULL) memcpy(xp, fillp, 4); +#ifndef WORDS_BIGENDIAN + swapn4b(xp, xp, 1); +#endif') + DEBUG_RETURN_ERROR(NC_ERANGE) + } - if (*ip < 0) return NC_ERANGE; + cp = (uchar *) xp; + *cp++ = 0x00; + *cp++ = 0x00; + *cp++ = 0x00; + *cp = (uchar)*ip; - return NC_NOERR; + return NC_NOERR; } static int -ncx_put_uint_uchar(void *xp, const uchar *ip) +APIPrefix`x_put_'NC_TYPE(uint)_uchar(void *xp, const uchar *ip, void *fillp) { uchar *cp = (uchar *) xp; *cp++ = 0x00; @@ -877,32 +1171,34 @@ ncx_put_uint_uchar(void *xp, const uchar *ip) } #if X_SIZEOF_UINT != SIZEOF_UINT -static NCX_PUT1I(uint, uint, 1) +NCX_PUT1I(uint, uint, 1) #endif -static NCX_PUT1I(uint, short, 0) -static NCX_PUT1I(uint, int, 0) -static NCX_PUT1I(uint, longlong, 0) -static NCX_PUT1I(uint, ushort, 1) -static NCX_PUT1I(uint, ulonglong, 1) -static NCX_PUT1F(uint, float) -static NCX_PUT1F(uint, double) +NCX_PUT1I(uint, short, 0) +NCX_PUT1I(uint, int, 0) +NCX_PUT1I(uint, long, 0) +NCX_PUT1I(uint, longlong, 0) +NCX_PUT1I(uint, ushort, 1) +NCX_PUT1I(uint, ulonglong, 1) +NCX_PUT1F(uint, float) +NCX_PUT1F(uint, double) + -/* x_float -------------------------------------------------------------------*/ +/* external NC_FLOAT --------------------------------------------------------*/ #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT) -static void +inline static void get_ix_float(const void *xp, float *ip) { #ifdef WORDS_BIGENDIAN - (void) memcpy(ip, xp, sizeof(float)); + (void) memcpy(ip, xp, SIZEOF_FLOAT); #else swap4b(ip, xp); #endif } -static void +inline static void put_ix_float(void *xp, const float *ip) { #ifdef WORDS_BIGENDIAN @@ -912,7 +1208,7 @@ put_ix_float(void *xp, const float *ip) #endif } -#elif vax +#elif defined(vax) && vax != 0 /* What IEEE single precision floating point looks like on a Vax */ struct ieee_single { @@ -961,7 +1257,7 @@ define(`GET_VAX_DFLOAT_Body',dnl switch(exp) { case 0 : /* ieee subnormal */ - if(isp->mant_hi == min.ieee.mant_hi + if (isp->mant_hi == min.ieee.mant_hi && isp->mant_lo_hi == min.ieee.mant_lo_hi && isp->mant_lo_lo == min.ieee.mant_lo_lo) { @@ -973,7 +1269,7 @@ define(`GET_VAX_DFLOAT_Body',dnl | isp->mant_lo_hi << 8 | isp->mant_lo_lo; unsigned tmp = mantissa >> 20; - if(tmp >= 4) { + if (tmp >= 4) { vsp->exp = 2; } else if (tmp >= 2) { vsp->exp = 1; @@ -1036,8 +1332,8 @@ define(`PUT_VAX_DFLOAT_Body',dnl } break; case 0xff : /* max.s.exp */ - if( vsp->mantissa2 == max.s.mantissa2 - && vsp->mantissa1 == max.s.mantissa1) + if (vsp->mantissa2 == max.s.mantissa2 && + vsp->mantissa1 == max.s.mantissa1) { /* map largest vax float to ieee infinity */ *isp = max.ieee; @@ -1127,11 +1423,11 @@ define(`GET_IX_FLOAT_Body',dnl `dnl cray_single *csp = (cray_single *) ip; - if(isp->exp == 0) + if (isp->exp == 0) { /* ieee subnormal */ *ip = (double)isp->mant; - if(isp->mant != 0) + if (isp->mant != 0) { csp->exp -= (ieee_single_bias + 22); } @@ -1156,13 +1452,13 @@ define(`PUT_IX_FLOAT_Body',dnl isp->sign = csp->sign; - if(ieee_exp >= 0xff) + if (ieee_exp >= 0xff) { /* NC_ERANGE => ieee Inf */ isp->exp = 0xff; isp->mant = 0x0; } - else if(ieee_exp > 0) + else if (ieee_exp > 0) { /* normal ieee representation */ isp->exp = ieee_exp; @@ -1171,7 +1467,7 @@ define(`PUT_IX_FLOAT_Body',dnl isp->mant = (((csp->mant << 1) & 0xffffffffffff) >> (48 - 23)); } - else if(ieee_exp > -23) + else if (ieee_exp > -23) { /* ieee subnormal, right shift */ const int rshift = (48 - 23 - ieee_exp); @@ -1179,7 +1475,7 @@ define(`PUT_IX_FLOAT_Body',dnl isp->mant = csp->mant >> rshift; #if 0 - if(csp->mant & (1 << (rshift -1))) + if (csp->mant & (1 << (rshift -1))) { /* round up */ isp->mant++; @@ -1200,7 +1496,7 @@ static void get_ix_float(const void *xp, float *ip) { - if(word_align(xp) == 0) + if (word_align(xp) == 0) { const ieee_single_hi *isp = (const ieee_single_hi *) xp; GET_IX_FLOAT_Body @@ -1215,7 +1511,7 @@ GET_IX_FLOAT_Body static void put_ix_float(void *xp, const float *ip) { - if(word_align(xp) == 0) + if (word_align(xp) == 0) { ieee_single_hi *isp = (ieee_single_hi*)xp; PUT_IX_FLOAT_Body @@ -1235,10 +1531,10 @@ get_ix_float(const void *xp, float *ip) ieee_double *idp = (ieee_double *) ip; - if(word_align(xp) == 0) + if (word_align(xp) == 0) { const ieee_single_hi *isp = (const ieee_single_hi *) xp; - if(isp->exp == 0 && isp->mant == 0) + if (isp->exp == 0 && isp->mant == 0) { idp->exp = 0; idp->mant = 0; @@ -1253,7 +1549,7 @@ get_ix_float(const void *xp, float *ip) else { const ieee_single_lo *isp = (const ieee_single_lo *) xp; - if(isp->exp == 0 && isp->mant == 0) + if (isp->exp == 0 && isp->mant == 0) { idp->exp = 0; idp->mant = 0; @@ -1271,10 +1567,10 @@ static void put_ix_float(void *xp, const float *ip) { const ieee_double *idp = (const ieee_double *) ip; - if(word_align(xp) == 0) + if (word_align(xp) == 0) { ieee_single_hi *isp = (ieee_single_hi*)xp; - if(idp->exp > (ieee_double_bias - ieee_single_bias)) + if (idp->exp > (ieee_double_bias - ieee_single_bias)) isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias); else isp->exp = 0; @@ -1284,7 +1580,7 @@ put_ix_float(void *xp, const float *ip) else { ieee_single_lo *isp = (ieee_single_lo*)xp; - if(idp->exp > (ieee_double_bias - ieee_single_bias)) + if (idp->exp > (ieee_double_bias - ieee_single_bias)) isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias); else isp->exp = 0; @@ -1300,7 +1596,7 @@ put_ix_float(void *xp, const float *ip) #if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT) static int -ncx_get_float_float(const void *xp, float *ip) +APIPrefix`x_get_'NC_TYPE(float)_float(const void *xp, float *ip, void *fillp) { /* TODO */ get_ix_float(xp, ip); @@ -1310,41 +1606,49 @@ ncx_get_float_float(const void *xp, float *ip) #define ix_float float -static NCX_GET1F(float, schar) -static NCX_GET1F(float, short) -static NCX_GET1F(float, int) -static NCX_GET1F(float, double) -static NCX_GET1F(float, longlong) -static NCX_GET1F(float, uchar) -static NCX_GET1F(float, ushort) -static NCX_GET1F(float, uint) -static NCX_GET1F(float, ulonglong) +NCX_GET1F(float, schar) +NCX_GET1F(float, short) +NCX_GET1F(float, int) +NCX_GET1F(float, long) +NCX_GET1F(float, double) +NCX_GET1F(float, longlong) +NCX_GET1F(float, uchar) +NCX_GET1F(float, ushort) +NCX_GET1F(float, uint) +NCX_GET1F(float, ulonglong) #if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT) static int -ncx_put_float_float(void *xp, const float *ip) +APIPrefix`x_put_'NC_TYPE(float)_float(void *xp, const float *ip, void *fillp) { - put_ix_float(xp, ip); + int err=NC_NOERR; + float *_ip=ip; #ifdef NO_IEEE_FLOAT - if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) - return NC_ERANGE; + ifdef(`ERANGE_FILL',`float tmp;') + if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) { + FillValue(float, &tmp) + ifdef(`ERANGE_FILL',`_ip = &tmp;') + DEBUG_ASSIGN_ERROR(err, NC_ERANGE) + } #endif - return NC_NOERR; + put_ix_float(xp, _ip); + return err; } #endif -static NCX_PUT1F(float, schar) -static NCX_PUT1F(float, short) -static NCX_PUT1F(float, int) -static NCX_PUT1F(float, double) -static NCX_PUT1F(float, longlong) -static NCX_PUT1F(float, uchar) -static NCX_PUT1F(float, ushort) -static NCX_PUT1F(float, uint) -static NCX_PUT1F(float, ulonglong) +NCX_PUT1F(float, schar) +NCX_PUT1F(float, short) +NCX_PUT1F(float, int) +NCX_PUT1F(float, long) +NCX_PUT1F(float, double) +NCX_PUT1F(float, longlong) +NCX_PUT1F(float, uchar) +NCX_PUT1F(float, ushort) +NCX_PUT1F(float, uint) +NCX_PUT1F(float, ulonglong) -/* x_double ------------------------------------------------------------------*/ +/* external NC_DOUBLE -------------------------------------------------------*/ #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) @@ -1352,7 +1656,7 @@ static void get_ix_double(const void *xp, double *ip) { #ifdef WORDS_BIGENDIAN - (void) memcpy(ip, xp, sizeof(double)); + (void) memcpy(ip, xp, SIZEOF_DOUBLE); #else swap8b(ip, xp); #endif @@ -1368,7 +1672,7 @@ put_ix_double(void *xp, const double *ip) #endif } -#elif vax +#elif defined(vax) && vax != 0 /* What IEEE double precision floating point looks like on a Vax */ struct ieee_double { @@ -1502,14 +1806,14 @@ define(`PUT_VAX_DDOUBLE_Body',dnl unsigned mant_hi = (vdp->mantissa1 << 13) | (vdp->mantissa2 >> 3); - if((vdp->mantissa4 & 7) > 4) + if ((vdp->mantissa4 & 7) > 4) { /* round up */ mant_lo++; - if(mant_lo == 0) + if (mant_lo == 0) { mant_hi++; - if(mant_hi > 0xffffff) + if (mant_hi > 0xffffff) { mant_hi = 0; exp++; @@ -1543,11 +1847,11 @@ get_ix_double(const void *xp, double *ip) const ieee_double *idp = (const ieee_double *) xp; cray_single *csp = (cray_single *) ip; - if(idp->exp == 0) + if (idp->exp == 0) { /* ieee subnormal */ *ip = (double)idp->mant; - if(idp->mant != 0) + if (idp->mant != 0) { csp->exp -= (ieee_double_bias + 51); } @@ -1571,13 +1875,13 @@ put_ix_double(void *xp, const double *ip) idp->sign = csp->sign; - if(ieee_exp >= 0x7ff) + if (ieee_exp >= 0x7ff) { /* NC_ERANGE => ieee Inf */ idp->exp = 0x7ff; idp->mant = 0x0; } - else if(ieee_exp > 0) + else if (ieee_exp > 0) { /* normal ieee representation */ idp->exp = ieee_exp; @@ -1586,14 +1890,14 @@ put_ix_double(void *xp, const double *ip) idp->mant = (((csp->mant << 1) & 0xffffffffffff) << (52 - 48)); } - else if(ieee_exp >= (-(52 -48))) + else if (ieee_exp >= (-(52 -48))) { /* ieee subnormal, left shift */ const int lshift = (52 - 48) + ieee_exp; idp->mant = csp->mant << lshift; idp->exp = 0; } - else if(ieee_exp >= -52) + else if (ieee_exp >= -52) { /* ieee subnormal, right shift */ const int rshift = (- (52 - 48) - ieee_exp); @@ -1601,7 +1905,7 @@ put_ix_double(void *xp, const double *ip) idp->mant = csp->mant >> rshift; #if 0 - if(csp->mant & (1 << (rshift -1))) + if (csp->mant & (1 << (rshift -1))) { /* round up */ idp->mant++; @@ -1623,47 +1927,36 @@ put_ix_double(void *xp, const double *ip) #define ix_double double -static NCX_GET1F(double, schar) -static NCX_GET1F(double, short) -static NCX_GET1F(double, int) -static NCX_GET1F(double, longlong) -static NCX_GET1F(double, uchar) -static NCX_GET1F(double, ushort) -static NCX_GET1F(double, uint) - -int -ncx_get_double_ulonglong(const void *xp, unsigned long long *ip) -{ - double xx; - get_ix_double(xp, &xx); - *ip = (unsigned long long) xx; - if(xx > ULONG_LONG_MAX || xx < 0) - return NC_ERANGE; - return NC_NOERR; -} +NCX_GET1F(double, schar) +NCX_GET1F(double, short) +NCX_GET1F(double, int) +NCX_GET1F(double, long) +NCX_GET1F(double, longlong) +NCX_GET1F(double, uchar) +NCX_GET1F(double, ushort) +NCX_GET1F(double, uint) +NCX_GET1F(double, ulonglong) static int -ncx_get_double_float(const void *xp, float *ip) +APIPrefix`x_get_'NC_TYPE(double)_float(const void *xp, float *ip) { - double xx; - get_ix_double(xp, &xx); - if(xx > FLT_MAX) - { - *ip = FLT_MAX; - return NC_ERANGE; - } - if(xx < (-FLT_MAX)) - { - *ip = (-FLT_MAX); - return NC_ERANGE; - } - *ip = (float) xx; - return NC_NOERR; + double xx; + get_ix_double(xp, &xx); + if (xx > FLT_MAX) { + ifdef(`ERANGE_FILL', `*ip = NC_FILL_FLOAT;', `*ip = FLT_MAX;') + DEBUG_RETURN_ERROR(NC_ERANGE) + } + if (xx < (-FLT_MAX)) { + ifdef(`ERANGE_FILL', `*ip = NC_FILL_FLOAT;', `*ip = (-FLT_MAX);') + DEBUG_RETURN_ERROR(NC_ERANGE) + } + *ip = (float) xx; + return NC_NOERR; } #if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE || defined(NO_IEEE_FLOAT) static int -ncx_get_double_double(const void *xp, double *ip) +APIPrefix`x_get_'NC_TYPE(double)_double(const void *xp, double *ip, void *fillp) { /* TODO */ get_ix_double(xp, ip); @@ -1671,182 +1964,208 @@ ncx_get_double_double(const void *xp, double *ip) } #endif -static NCX_PUT1F(double, schar) -static NCX_PUT1F(double, uchar) -static NCX_PUT1F(double, short) -static NCX_PUT1F(double, ushort) -static NCX_PUT1F(double, int) -static NCX_PUT1F(double, uint) -static NCX_PUT1F(double, longlong) -static NCX_PUT1F(double, ulonglong) +NCX_PUT1F(double, schar) +NCX_PUT1F(double, uchar) +NCX_PUT1F(double, short) +NCX_PUT1F(double, ushort) +NCX_PUT1F(double, int) +NCX_PUT1F(double, long) +NCX_PUT1F(double, uint) +NCX_PUT1F(double, longlong) +NCX_PUT1F(double, ulonglong) static int -ncx_put_double_float(void *xp, const float *ip) +APIPrefix`x_put_'NC_TYPE(double)_float(void *xp, const float *ip, void *fillp) { - double xx = (double) *ip; - put_ix_double(xp, &xx); -#if 1 /* TODO: figure this out */ - if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) - return NC_ERANGE; + int err=NC_NOERR; + double xx = FillDefaultValue(double); +#if 1 /* TODO: figure this out (if condition below will never be true)*/ + if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) { + FillValue(double, &xx) + DEBUG_ASSIGN_ERROR(err, NC_ERANGE) + } ifdef(`ERANGE_FILL',`else') #endif - return NC_NOERR; + xx = (double) *ip; + + put_ix_double(xp, &xx); + return err; } #if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE || defined(NO_IEEE_FLOAT) static int -ncx_put_double_double(void *xp, const double *ip) +APIPrefix`x_put_'NC_TYPE(double)_double(void *xp, const double *ip, void *fillp) { - put_ix_double(xp, ip); + int err=NC_NOERR; + double *_ip = ip; #ifdef NO_IEEE_FLOAT - if(*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) - return NC_ERANGE; + ifdef(`ERANGE_FILL',`double tmp=NC_FILL_DOUBLE;') + if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) { + FillValue(double, &tmp) + ifdef(`ERANGE_FILL',`_ip = &tmp;') + DEBUG_ASSIGN_ERROR(err, NC_ERANGE) + } #endif - return NC_NOERR; + put_ix_double(xp, _ip); + return err; } #endif -/* x_longlong ---------------------------------------------------------------------*/ +/* external NC_INT64 --------------------------------------------------------*/ -#if SHORT_MAX == X_LONGLONG_MAX -typedef short ix_longlong; -#define SIZEOF_IX_LONGLONG SIZEOF_SHORT -#define IX_LONGLONG_MAX SHORT_MAX -#elif LONG_LONG_MAX >= X_LONGLONG_MAX -typedef longlong ix_longlong; -#define SIZEOF_IX_LONGLONG SIZEOF_LONGLONG -#define IX_LONGLONG_MAX LONG_LONG_MAX -#elif LONG_MAX >= X_LONGLONG_MAX -typedef long ix_longlong; -#define SIZEOF_IX_LONGLONG SIZEOF_LONG -#define IX_LONGLONG_MAX LONG_MAX +#if SHORT_MAX == X_INT64_MAX +typedef short ix_int64; +#define SIZEOF_IX_INT64 SIZEOF_SHORT +#define IX_INT64_MAX SHORT_MAX +#elif LONG_LONG_MAX >= X_INT64_MAX +typedef longlong ix_int64; +#define SIZEOF_IX_INT64 SIZEOF_LONGLONG +#define IX_INT64_MAX LONG_LONG_MAX +#elif LONG_MAX >= X_INT64_MAX +typedef long ix_int64; +#define SIZEOF_IX_INT64 SIZEOF_LONG +#define IX_INT64_MAX LONG_MAX #else -#error "ix_longlong implementation" +#error "ix_int64 implementation" #endif static void -get_ix_longlong(const void *xp, ix_longlong *ip) +get_ix_int64(const void *xp, ix_int64 *ip) { const uchar *cp = (const uchar *) xp; - *ip = ((long long)(*cp++) << 56); - *ip |= ((long long)(*cp++) << 48); - *ip |= ((long long)(*cp++) << 40); - *ip |= ((long long)(*cp++) << 32); - *ip |= ((long long)(*cp++) << 24); - *ip |= ((long long)(*cp++) << 16); - *ip |= ((long long)(*cp++) << 8); - *ip |= (long long)*cp; + *ip = ((ix_int64)(*cp++) << 56); + *ip |= ((ix_int64)(*cp++) << 48); + *ip |= ((ix_int64)(*cp++) << 40); + *ip |= ((ix_int64)(*cp++) << 32); + *ip |= ((ix_int64)(*cp++) << 24); + *ip |= ((ix_int64)(*cp++) << 16); + *ip |= ((ix_int64)(*cp++) << 8); + *ip |= (ix_int64)*cp; } static void -put_ix_longlong(void *xp, const ix_longlong *ip) +put_ix_int64(void *xp, const ix_int64 *ip) { uchar *cp = (uchar *) xp; - *cp++ = (*ip) >> 56; - *cp++ = ((*ip) & 0x00ff000000000000LL) >> 48; - *cp++ = ((*ip) & 0x0000ff0000000000LL) >> 40; - *cp++ = ((*ip) & 0x000000ff00000000LL) >> 32; - *cp++ = ((*ip) & 0x00000000ff000000LL) >> 24; - *cp++ = ((*ip) & 0x0000000000ff0000LL) >> 16; - *cp++ = ((*ip) & 0x000000000000ff00LL) >> 8; - *cp = ((*ip) & 0x00000000000000ffLL); -} - -static NCX_GET1I(longlong, schar, 0) -static NCX_GET1I(longlong, short, 1) -static NCX_GET1I(longlong, int, 1) -static NCX_GET1I(longlong, longlong, 1) -static NCX_GET1I(longlong, ushort, 0) -static NCX_GET1I(longlong, uchar, 0) -static NCX_GET1I(longlong, uint, 0) -static NCX_GET1I(longlong, ulonglong, 0) -static NCX_GET1F(longlong, float) -static NCX_GET1F(longlong, double) - -static NCX_PUT1I(longlong, schar, 0) -static NCX_PUT1I(longlong, short, 1) -static NCX_PUT1I(longlong, int, 1) -static NCX_PUT1I(longlong, longlong, 1) -static NCX_PUT1I(longlong, ushort, 0) -static NCX_PUT1I(longlong, uchar, 0) -static NCX_PUT1I(longlong, uint, 0) -static NCX_PUT1I(longlong, ulonglong, 0) -static NCX_PUT1F(longlong, float) -static NCX_PUT1F(longlong, double) - -/* x_ulonglong --------------------------------------------------------------------*/ - -#if USHORT_MAX == X_ULONGLONG_MAX -typedef ushort ix_ulonglong; -#define SIZEOF_IX_ULONGLONG SIZEOF_USHORT -#define IX_ULONGLONG_MAX USHORT_MAX -#elif ULONG_LONG_MAX >= X_ULONGLONG_MAX -typedef ulonglong ix_ulonglong; -#define SIZEOF_IX_ULONGLONG SIZEOF_ULONGLONG -#define IX_ULONGLONG_MAX ULONG_LONG_MAX -#elif ULONG_MAX >= X_ULONGLONG_MAX -typedef ulong ix_ulonglong; -#define SIZEOF_IX_ULONGLONG SIZEOF_ULONG -#define IX_ULONGLONG_MAX ULONG_MAX + *cp++ = (uchar)((*ip) >> 56); + *cp++ = (uchar)(((*ip) & 0x00ff000000000000LL) >> 48); + *cp++ = (uchar)(((*ip) & 0x0000ff0000000000LL) >> 40); + *cp++ = (uchar)(((*ip) & 0x000000ff00000000LL) >> 32); + *cp++ = (uchar)(((*ip) & 0x00000000ff000000LL) >> 24); + *cp++ = (uchar)(((*ip) & 0x0000000000ff0000LL) >> 16); + *cp++ = (uchar)(((*ip) & 0x000000000000ff00LL) >> 8); + *cp = (uchar)( (*ip) & 0x00000000000000ffLL); +} + +#if X_SIZEOF_INT64 != SIZEOF_LONGLONG +NCX_GET1I(int64, longlong, 1) +#endif +NCX_GET1I(int64, schar, 0) +NCX_GET1I(int64, short, 1) +NCX_GET1I(int64, int, 1) +NCX_GET1I(int64, long, 1) +NCX_GET1I(int64, ushort, 0) +NCX_GET1I(int64, uchar, 0) +NCX_GET1I(int64, uint, 0) +NCX_GET1I(int64, ulonglong, 0) +NCX_GET1F(int64, float) +NCX_GET1F(int64, double) + +#if X_SIZEOF_INT64 != SIZEOF_LONGLONG +NCX_PUT1I(int64, longlong, 1) +#endif +NCX_PUT1I(int64, schar, 0) +NCX_PUT1I(int64, short, 1) +NCX_PUT1I(int64, int, 1) +NCX_PUT1I(int64, long, 1) +NCX_PUT1I(int64, ushort, 0) +NCX_PUT1I(int64, uchar, 0) +NCX_PUT1I(int64, uint, 0) +NCX_PUT1I(int64, ulonglong, 0) +NCX_PUT1F(int64, float) +NCX_PUT1F(int64, double) + + +/* external NC_UINT64 -------------------------------------------------------*/ + +#if USHORT_MAX == X_UINT64_MAX +typedef ushort ix_uint64; +#define SIZEOF_IX_UINT64 SIZEOF_USHORT +#define IX_UINT64_MAX USHORT_MAX +#elif ULONG_LONG_MAX >= X_UINT64_MAX +typedef ulonglong ix_uint64; +#define SIZEOF_IX_UINT64 SIZEOF_ULONGLONG +#define IX_UINT64_MAX ULONG_LONG_MAX +#elif ULONG_MAX >= X_UINT64_MAX +typedef ulong ix_uint64; +#define SIZEOF_IX_UINT64 SIZEOF_ULONG +#define IX_UINT64_MAX ULONG_MAX #else -#error "ix_ulonglong implementation" +#error "ix_uint64 implementation" #endif static void -get_ix_ulonglong(const void *xp, ix_ulonglong *ip) +get_ix_uint64(const void *xp, ix_uint64 *ip) { const uchar *cp = (const uchar *) xp; - *ip = ((unsigned long long)(*cp++) << 56); - *ip |= ((unsigned long long)(*cp++) << 48); - *ip |= ((unsigned long long)(*cp++) << 40); - *ip |= ((unsigned long long)(*cp++) << 32); - *ip |= ((unsigned long long)(*cp++) << 24); - *ip |= ((unsigned long long)(*cp++) << 16); - *ip |= ((unsigned long long)(*cp++) << 8); - *ip |= (unsigned long long)*cp; + *ip = ((ix_uint64)(*cp++) << 56); + *ip |= ((ix_uint64)(*cp++) << 48); + *ip |= ((ix_uint64)(*cp++) << 40); + *ip |= ((ix_uint64)(*cp++) << 32); + *ip |= ((ix_uint64)(*cp++) << 24); + *ip |= ((ix_uint64)(*cp++) << 16); + *ip |= ((ix_uint64)(*cp++) << 8); + *ip |= (ix_uint64)*cp; } static void -put_ix_ulonglong(void *xp, const ix_ulonglong *ip) +put_ix_uint64(void *xp, const ix_uint64 *ip) { uchar *cp = (uchar *) xp; - *cp++ = (*ip) >> 56; - *cp++ = ((*ip) & 0x00ff000000000000ULL) >> 48; - *cp++ = ((*ip) & 0x0000ff0000000000ULL) >> 40; - *cp++ = ((*ip) & 0x000000ff00000000ULL) >> 32; - *cp++ = ((*ip) & 0x00000000ff000000ULL) >> 24; - *cp++ = ((*ip) & 0x0000000000ff0000ULL) >> 16; - *cp++ = ((*ip) & 0x000000000000ff00ULL) >> 8; - *cp = ((*ip) & 0x00000000000000ffULL); -} - -static NCX_GET1I(ulonglong, schar, 0) -static NCX_GET1I(ulonglong, short, 0) -static NCX_GET1I(ulonglong, int, 0) -static NCX_GET1I(ulonglong, longlong, 0) -static NCX_GET1I(ulonglong, ushort, 1) -static NCX_GET1I(ulonglong, uchar, 1) -static NCX_GET1I(ulonglong, uint, 1) -static NCX_GET1I(ulonglong, ulonglong, 1) -static NCX_GET1F(ulonglong, float) -static NCX_GET1F(ulonglong, double) - -static NCX_PUT1I(ulonglong, schar, 0) -static NCX_PUT1I(ulonglong, short, 0) -static NCX_PUT1I(ulonglong, int, 0) -static NCX_PUT1I(ulonglong, longlong, 0) -static NCX_PUT1I(ulonglong, uchar, 1) -static NCX_PUT1I(ulonglong, ushort, 1) -static NCX_PUT1I(ulonglong, uint, 1) -static NCX_PUT1I(ulonglong, ulonglong, 1) -static NCX_PUT1F(ulonglong, float) -static NCX_PUT1F(ulonglong, double) + *cp++ = (uchar)((*ip) >> 56); + *cp++ = (uchar)(((*ip) & 0x00ff000000000000ULL) >> 48); + *cp++ = (uchar)(((*ip) & 0x0000ff0000000000ULL) >> 40); + *cp++ = (uchar)(((*ip) & 0x000000ff00000000ULL) >> 32); + *cp++ = (uchar)(((*ip) & 0x00000000ff000000ULL) >> 24); + *cp++ = (uchar)(((*ip) & 0x0000000000ff0000ULL) >> 16); + *cp++ = (uchar)(((*ip) & 0x000000000000ff00ULL) >> 8); + *cp = (uchar)( (*ip) & 0x00000000000000ffULL); +} + +#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG +NCX_GET1I(uint64, ulonglong, 1) +#endif +NCX_GET1I(uint64, schar, 0) +NCX_GET1I(uint64, short, 0) +NCX_GET1I(uint64, int, 0) +NCX_GET1I(uint64, long, 0) +NCX_GET1I(uint64, longlong, 0) +NCX_GET1I(uint64, ushort, 1) +NCX_GET1I(uint64, uchar, 1) +NCX_GET1I(uint64, uint, 1) +NCX_GET1F(uint64, float) +NCX_GET1F(uint64, double) + +#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG +NCX_PUT1I(uint64, ulonglong, 1) +#endif +NCX_PUT1I(uint64, schar, 0) +NCX_PUT1I(uint64, short, 0) +NCX_PUT1I(uint64, int, 0) +NCX_PUT1I(uint64, long, 0) +NCX_PUT1I(uint64, longlong, 0) +NCX_PUT1I(uint64, uchar, 1) +NCX_PUT1I(uint64, ushort, 1) +NCX_PUT1I(uint64, uint, 1) +NCX_PUT1F(uint64, float) +NCX_PUT1F(uint64, double) + /* x_size_t */ @@ -1856,7 +2175,7 @@ static NCX_PUT1F(ulonglong, double) #endif int -ncx_put_size_t(void **xpp, const size_t *ulp) +APIPrefix`x_put_size_t'(void **xpp, const size_t *ulp) { /* similar to put_ix_int() */ uchar *cp = (uchar *) *xpp; @@ -1872,14 +2191,14 @@ ncx_put_size_t(void **xpp, const size_t *ulp) } int -ncx_get_size_t(const void **xpp, size_t *ulp) +APIPrefix`x_get_size_t'(const void **xpp, size_t *ulp) { /* similar to get_ix_int */ const uchar *cp = (const uchar *) *xpp; - *ulp = (unsigned)(*cp++ << 24); - *ulp |= (*cp++ << 16); - *ulp |= (*cp++ << 8); + *ulp = (size_t)(*cp++ << 24); + *ulp |= (size_t)(*cp++ << 16); + *ulp |= (size_t)(*cp++ << 8); *ulp |= *cp; *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T); @@ -1889,18 +2208,19 @@ ncx_get_size_t(const void **xpp, size_t *ulp) /* x_off_t */ int -ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t) +APIPrefix`x_put_off_t'(void **xpp, const off_t *lp, size_t sizeof_off_t) { - /* similar to put_ix_int() */ - uchar *cp = (uchar *) *xpp; - /* No negative offsets stored in netcdf */ + /* No negative offsets stored in netcdf */ if (*lp < 0) { /* Assume this is an overflow of a 32-bit int... */ - return NC_ERANGE; + DEBUG_RETURN_ERROR(NC_ERANGE) } assert(sizeof_off_t == 4 || sizeof_off_t == 8); + /* similar to put_ix_int() */ + uchar *cp = (uchar *) *xpp; + if (sizeof_off_t == 4) { *cp++ = (uchar) ((*lp) >> 24); *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16); @@ -1920,13 +2240,13 @@ ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t) *cp = (uchar)( (*lp) & 0x000000ff); #else *cp++ = (uchar) ((*lp) >> 56); - *cp++ = (uchar)(((*lp) & 0x00ff000000000000ULL) >> 48); - *cp++ = (uchar)(((*lp) & 0x0000ff0000000000ULL) >> 40); - *cp++ = (uchar)(((*lp) & 0x000000ff00000000ULL) >> 32); - *cp++ = (uchar)(((*lp) & 0x00000000ff000000ULL) >> 24); - *cp++ = (uchar)(((*lp) & 0x0000000000ff0000ULL) >> 16); - *cp++ = (uchar)(((*lp) & 0x000000000000ff00ULL) >> 8); - *cp = (uchar)( (*lp) & 0x00000000000000ffULL); + *cp++ = (uchar)(((*lp) & 0x00ff000000000000LL) >> 48); + *cp++ = (uchar)(((*lp) & 0x0000ff0000000000LL) >> 40); + *cp++ = (uchar)(((*lp) & 0x000000ff00000000LL) >> 32); + *cp++ = (uchar)(((*lp) & 0x00000000ff000000LL) >> 24); + *cp++ = (uchar)(((*lp) & 0x0000000000ff0000LL) >> 16); + *cp++ = (uchar)(((*lp) & 0x000000000000ff00LL) >> 8); + *cp = (uchar)( (*lp) & 0x00000000000000ffLL); #endif } *xpp = (void *)((char *)(*xpp) + sizeof_off_t); @@ -1934,7 +2254,7 @@ ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t) } int -ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t) +APIPrefix`x_get_off_t'(const void **xpp, off_t *lp, size_t sizeof_off_t) { /* similar to get_ix_int() */ const uchar *cp = (const uchar *) *xpp; @@ -1959,7 +2279,7 @@ ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t) * on this system. Set an error code and return. */ if (*lp != 0) { - return NC_ERANGE; + DEBUG_RETURN_ERROR(NC_ERANGE) } *lp = ((off_t)(*cp++) << 24); @@ -1973,7 +2293,7 @@ ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t) * than 2^32 which is not allowed, but is not caught * by the previous check */ - return NC_ERANGE; + DEBUG_RETURN_ERROR(NC_ERANGE) } #else *lp = ((off_t)(*cp++) << 56); @@ -1990,62 +2310,68 @@ ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t) return NC_NOERR; } -/*----< ncx_get_int32() >--------------------------------------------------*/ +/*----< APIPrefix`x_get_uint32'() >------------------------------------------*/ int -ncx_get_int32(const void **xpp, - int *ip) +APIPrefix`x_get_uint32'(const void **xpp, uint *ip) { +#ifdef WORDS_BIGENDIAN + /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on + * some system, such as HPUX */ + (void) memcpy(ip, *xpp, SIZEOF_UINT); +#else const uchar *cp = (const uchar *) *xpp; - /* cannot call swap4b(), as lp is 8-byte */ - *ip = (*cp++ << 24); - *ip |= (*cp++ << 16); - *ip |= (*cp++ << 8); - *ip |= *cp; - + *ip = (uint)(*cp++ << 24); + *ip = (uint)(*ip | (uint)(*cp++ << 16)); + *ip = (uint)(*ip | (uint)(*cp++ << 8)); + *ip = (uint)(*ip | *cp); +#endif /* advance *xpp 4 bytes */ *xpp = (void *)((const char *)(*xpp) + 4); return NC_NOERR; } -/*----< ncx_get_int64() >-------------------------------------------------*/ +/*----< APIPrefix`x_get_uint64'() >------------------------------------------*/ int -ncx_get_int64(const void **xpp, - long long *llp) +APIPrefix`x_get_uint64'(const void **xpp, unsigned long long *ullp) { +#ifdef WORDS_BIGENDIAN + /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on + * some system, such as HPUX */ + (void) memcpy(ullp, *xpp, SIZEOF_UINT64); +#else const uchar *cp = (const uchar *) *xpp; - /* below is the same as calling swap8b(llp, *xpp) */ - *llp = ((long long)(*cp++) << 56); - *llp |= ((long long)(*cp++) << 48); - *llp |= ((long long)(*cp++) << 40); - *llp |= ((long long)(*cp++) << 32); - *llp |= ((long long)(*cp++) << 24); - *llp |= ((long long)(*cp++) << 16); - *llp |= ((long long)(*cp++) << 8); - *llp |= (long long)*cp; - + /* below is the same as calling swap8b(ullp, *xpp) */ + *ullp = (unsigned long long)(*cp++) << 56; + *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 48); + *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 40); + *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 32); + *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 24); + *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 16); + *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 8); + *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp)); +#endif /* advance *xpp 8 bytes */ *xpp = (void *)((const char *)(*xpp) + 8); return NC_NOERR; } -/*---< ncx_put_int32() >-----------------------------------------------------*/ -/* copy the contents of lp (a signed 32-bit integer) to xpp in Big Endian +/*---< APIPrefix`x_put_uint32'() >-------------------------------------------*/ +/* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian * form and advance *xpp 4 bytes */ int -ncx_put_int32(void **xpp, - const int ip) +APIPrefix`x_put_uint32'(void **xpp, const unsigned int ip) { #ifdef WORDS_BIGENDIAN - int *ptr = (int*) (*xpp); /* typecast to 4-byte integer */ - *ptr = ip; + /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on + * some system, such as HPUX */ + (void) memcpy(*xpp, &ip, X_SIZEOF_UINT); #else /* bitwise shifts below are to produce an integer in Big Endian */ - /* cannot call swap4b(), as lp is 8-byte */ uchar *cp = (uchar *) *xpp; *cp++ = (uchar)((ip & 0xff000000) >> 24); *cp++ = (uchar)((ip & 0x00ff0000) >> 16); @@ -2058,28 +2384,28 @@ ncx_put_int32(void **xpp, return NC_NOERR; } -/*---< ncx_put_int64() >-----------------------------------------------------*/ -/* copy the contents of lp (a signed 64-bit integer) to xpp in Big Endian +/*---< APIPrefix`x_put_uint64'() >-------------------------------------------*/ +/* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian * form and advance *xpp 8 bytes */ int -ncx_put_int64(void **xpp, - const long long ip) +APIPrefix`x_put_uint64'(void **xpp, const unsigned long long ip) { #ifdef WORDS_BIGENDIAN - long long *ptr = (long long*) (*xpp); /* typecast to 8-byte integer */ - *ptr = ip; + /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on + * some system, such as HPUX */ + (void) memcpy(*xpp, &ip, X_SIZEOF_UINT64); #else uchar *cp = (uchar *) *xpp; /* below is the same as calling swap8b(*xpp, &ip) */ - *cp++ = (uchar)((ip & 0xff00000000000000ULL) >> 56); - *cp++ = (uchar)((ip & 0x00ff000000000000ULL) >> 48); - *cp++ = (uchar)((ip & 0x0000ff0000000000ULL) >> 40); - *cp++ = (uchar)((ip & 0x000000ff00000000ULL) >> 32); - *cp++ = (uchar)((ip & 0x00000000ff000000ULL) >> 24); - *cp++ = (uchar)((ip & 0x0000000000ff0000ULL) >> 16); - *cp++ = (uchar)((ip & 0x000000000000ff00ULL) >> 8); - *cp = (uchar)( ip & 0x00000000000000ffULL); + *cp++ = (uchar) (ip >> 56); + *cp++ = (uchar)((ip & 0x00ff000000000000LL) >> 48); + *cp++ = (uchar)((ip & 0x0000ff0000000000LL) >> 40); + *cp++ = (uchar)((ip & 0x000000ff00000000LL) >> 32); + *cp++ = (uchar)((ip & 0x00000000ff000000LL) >> 24); + *cp++ = (uchar)((ip & 0x0000000000ff0000LL) >> 16); + *cp++ = (uchar)((ip & 0x000000000000ff00LL) >> 8); + *cp = (uchar) (ip & 0x00000000000000ffLL); #endif /* advance *xpp 8 bytes */ *xpp = (void *)((char *)(*xpp) + 8); @@ -2092,8 +2418,8 @@ ncx_put_int64(void **xpp, * Aggregate numeric conversion functions. */ dnl -define(`GETN_CheckBND', `ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, `|| xp[i] < 0', `|| xp[i] < Imin($2)')')')dnl -define(`PUTN_CheckBND', `ifelse(index(`$2',`u'), 0, , `ifelse(index(`$1',`u'), 0, `|| tp[i] < 0', `|| tp[i] < Xmin($1)')')')dnl +define(`GETN_CheckBND', `ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0, `|| xp[i] < 0', `|| xp[i] < Imin($2)')')dnl +define(`PUTN_CheckBND', `ifelse(index(`$2',`u'), 0, , index(`$1',`u'), 0, `|| tp[i] < 0', `|| tp[i] < Xmin($1)')')dnl dnl dnl dnl dnl @@ -2102,8 +2428,8 @@ dnl NCX_GETN_Byte_Body (body for one byte types on diagonal) dnl define(`NCX_GETN_Byte_Body',dnl `dnl - (void) memcpy(tp, *xpp, nelems); - *xpp = (void *)((schar *)(*xpp) + nelems); + (void) memcpy(tp, *xpp, (size_t)nelems); + *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; ')dnl dnl dnl dnl @@ -2112,99 +2438,86 @@ dnl NCX_PAD_GETN_Byte_body (body for one byte types on diagonal) dnl define(`NCX_PAD_GETN_Byte_Body',dnl `dnl - size_t rndup = nelems % X_ALIGN; + IntType rndup = nelems % X_ALIGN; - if(rndup) + if (rndup) rndup = X_ALIGN - rndup; - (void) memcpy(tp, *xpp, nelems); + (void) memcpy(tp, *xpp, (size_t)nelems); *xpp = (void *)((char *)(*xpp) + nelems + rndup); return NC_NOERR; ')dnl dnl dnl dnl dnl -dnl NCX_GETN_CHAR(Type) +dnl NCX_GETN_BYTE(xtype, itype) dnl -define(`NCX_GETN_CHAR',dnl +define(`NCX_GETN_BYTE',dnl `dnl int -ncx_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp) +APIPrefix`x_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp) { - int status = NC_NOERR; - $1 *xp = ($1 *)(*xpp); + int status = NC_NOERR; + $1 *xp = ($1 *)(*xpp); - while(nelems-- != 0) - { -ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, ` if (*xp < 0) status = NC_ERANGE;')') - *tp++ = *xp++; - } + while (nelems-- != 0) { + ifelse(index(`$1',`u'), 0, , + index(`$2',`u'), 0, ` + if (*xp < 0) { + ifdef(`ERANGE_FILL',`*tp = FillDefaultValue($2);') + DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */ + SKIP_LOOP(xp, tp) + }')dnl - *xpp = (const void *)xp; - return status; + *tp++ = ($2) Cast_Signed2Unsigned($2,$1) (*xp++); /* type cast from $1 to $2 */ + } + + *xpp = (const void *)xp; + return status; } ')dnl dnl dnl dnl dnl -dnl NCX_PAD_GETN_CHAR(Type) +dnl NCX_PAD_GETN_BYTE(xtype, itype) dnl -define(`NCX_PAD_GETN_CHAR',dnl +define(`NCX_PAD_GETN_BYTE',dnl `dnl int -ncx_pad_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp) +APIPrefix`x_pad_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp) { - int status = NC_NOERR; - size_t rndup = nelems % X_ALIGN; - $1 *xp = ($1 *) *xpp; + int status = NC_NOERR; + IntType rndup = nelems % X_ALIGN; + $1 *xp = ($1 *) *xpp; - if(rndup) - rndup = X_ALIGN - rndup; + if (rndup) + rndup = X_ALIGN - rndup; - while(nelems-- != 0) - { -ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, ` if (*xp < 0) status = NC_ERANGE;')') - *tp++ = *xp++; - } + while (nelems-- != 0) { + ifelse(index(`$1',`u'), 0, , + index(`$2',`u'), 0, ` + if (*xp < 0) { + ifdef(`ERANGE_FILL', `*tp = FillDefaultValue($2);') + DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */ + SKIP_LOOP(xp, tp) + }')dnl - *xpp = (void *)(xp + rndup); - return status; -} -')dnl -dnl dnl dnl -dnl -dnl NCX_GETNo(XType, Type) deprecated -dnl -define(`NCX_GETNo',dnl -`dnl -int -ncx_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp) -{ - const char *xp = (const char *) *xpp; - int status = NC_NOERR; - $1 xx; - - for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++) - { - const int lstatus = ncx_get_$1_$1(xp, &xx); - *tp = ($2)xx; - if(lstatus != NC_NOERR) - status = lstatus; - } + *tp++ = ($2) Cast_Signed2Unsigned($2,$1) (*xp++); /* type cast from $1 to $2 */ + } - *xpp = (const void *)xp; - return status; + *xpp = (void *)(xp + rndup); + return status; } ')dnl dnl dnl dnl dnl -dnl NCX_GETN(XType, Type, condition) +dnl NCX_GETN(xtype, itype) dnl define(`NCX_GETN',dnl `dnl int -ncx_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp) +APIPrefix`x_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp) { -`#'if _SX && Xsizeof($1) == Isizeof($1) +`#'if defined(_SX) && _SX != 0 && Xsizeof($1) == Isizeof($1) /* basic algorithm is: * - ensure sane alignment of input data @@ -2227,7 +2540,7 @@ ncx_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp) for (j=0; j Xmax($1) ifelse(index(`$2',`u'), 0, , `ifelse(index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')')) - status = NC_ERANGE; - *xp++ = ($1) (signed)*tp++; - } + while (nelems-- != 0) { + if (*tp > ($2)Xmax($1) ifelse(index(`$2',`u'), 0, , index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')) { + FillValue($1, xp) + DEBUG_ASSIGN_ERROR(status, NC_ERANGE) + SKIP_LOOP(xp, tp) + } + *xp++ = ($1) Cast_Signed2Unsigned($1,$2) *tp++; /* type cast from $2 to $1 */ + } - *xpp = (void *)xp; - return status; + *xpp = (void *)xp; + return status; } ')dnl dnl dnl dnl dnl -dnl NCX_PAD_PUTN_CHAR(xtype, ttype) +dnl NCX_PAD_PUTN_BYTE(xtype, ttype) dnl -define(`NCX_PAD_PUTN_CHAR',dnl +define(`NCX_PAD_PUTN_BYTE',dnl `dnl int -ncx_pad_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp) +APIPrefix`x_pad_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp) { - int status = NC_NOERR; - size_t rndup = nelems % X_ALIGN; - $1 *xp = ($1 *) *xpp; - - if(rndup) - rndup = X_ALIGN - rndup; - - while(nelems-- != 0) - { - if(*tp > Xmax($1) ifelse(index(`$2',`u'), 0, , `ifelse(index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')')) - status = NC_ERANGE; - *xp++ = ($1) (signed) *tp++; - } + int status = NC_NOERR; + IntType rndup = nelems % X_ALIGN; + $1 *xp = ($1 *) *xpp; + if (rndup) rndup = X_ALIGN - rndup; - if(rndup) - { - (void) memcpy(xp, nada, rndup); - xp += rndup; - } + while (nelems-- != 0) { + if (*tp > ($2)Xmax($1) ifelse(index(`$2',`u'), 0, , index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')) { + FillValue($1, xp) + DEBUG_ASSIGN_ERROR(status, NC_ERANGE) + SKIP_LOOP(xp, tp) + } + *xp++ = ($1) Cast_Signed2Unsigned($1,$2) *tp++; /* type cast from $2 to $1 */ + } - *xpp = (void *)xp; - return status; -} -')dnl -dnl dnl dnl -dnl -dnl NCX_PUTNo(XType, Type) deprecated -dnl -define(`NCX_PUTNo',dnl -`dnl -int -ncx_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp) -{ - char *xp = (char *) *xpp; - int status = NC_NOERR; - $1 xx; - for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++) - { - xx = ($1) *tp; - { - int lstatus = ncx_put_$1_$1(xp, &xx); - if(lstatus != NC_NOERR) - status = lstatus; - } - } + if (rndup) { + (void) memcpy(xp, nada, (size_t)rndup); + xp += rndup; + } - *xpp = (void *)xp; - return status; + *xpp = (void *)xp; + return status; } ')dnl dnl dnl dnl dnl -dnl NCX_PUTN(XType, Type, condition) +dnl NCX_PUTN(xtype, itype) dnl define(`NCX_PUTN',dnl `dnl int -ncx_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp) +APIPrefix`x_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp) { -`#'if _SX && Xsizeof($1) == Isizeof($1) +`#'if defined(_SX) && _SX != 0 && Xsizeof($1) == Isizeof($1) /* basic algorithm is: * - ensure sane alignment of output data @@ -2433,7 +2722,7 @@ ncx_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp) $1 *xp; ifelse( $1$2, intfloat,dnl `dnl - double d; /* special case for ncx_putn_int_float */ + double d; /* special case for APIPrefix`x_putn_int_float' */ ')dnl int nrange = 0; /* number of range errors */ int realign = 0; /* "do we need to fix input data alignment?" */ @@ -2472,7 +2761,7 @@ ifelse( $1$2, intfloat,dnl } /* copy workspace back if necessary */ if (realign) { - memcpy(*xpp, tmp, ni*Xsizeof($1)); + memcpy(*xpp, tmp, (size_t)*ni*Xsizeof($1)); xp = ($1 *) *xpp; } /* update xpp and tp */ @@ -2489,8 +2778,8 @@ ifelse( $1$2, intfloat,dnl for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++) { - int lstatus = ncx_put_$1_$2(xp, tp); - if(lstatus != NC_NOERR) + int lstatus = APIPrefix`x_put_'NC_TYPE($1)_$2(xp, tp, fillp); + if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } @@ -2506,23 +2795,23 @@ dnl define(`NCX_PAD_PUTN_SHORT',dnl `dnl int -ncx_pad_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp) +APIPrefix`x_pad_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp) { - const size_t rndup = nelems % 2; + const IntType rndup = nelems % X_SIZEOF_SHORT; char *xp = (char *) *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++) { - int lstatus = ncx_put_$1_$2(xp, tp); - if(lstatus != NC_NOERR) + int lstatus = APIPrefix`x_put_'NC_TYPE($1)_$2(xp, tp, fillp); + if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } - if(rndup != 0) + if (rndup != 0) { - (void) memcpy(xp, nada, Xsizeof($1)); + (void) memcpy(xp, nada, (size_t)(Xsizeof($1))); xp += Xsizeof($1); } @@ -2539,186 +2828,237 @@ dnl dnl dnl /* schar ---------------------------------------------------------------------*/ -dnl NCX_GETN_CHAR(schar, schar) -int -ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp) -{ - NCX_GETN_Byte_Body -} -dnl NCX_GETN_CHAR(schar, uchar) +dnl NCX_GETN_BYTE(schar, schar) int -ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp) +APIPrefix`x_getn_'NC_TYPE(schar)_schar(const void **xpp, IntType nelems, schar *tp) { NCX_GETN_Byte_Body } -NCX_GETN_CHAR(schar, short) -NCX_GETN_CHAR(schar, int) -NCX_GETN_CHAR(schar, float) -NCX_GETN_CHAR(schar, double) -NCX_GETN_CHAR(schar, longlong) -NCX_GETN_CHAR(schar, ushort) -NCX_GETN_CHAR(schar, uint) -NCX_GETN_CHAR(schar, ulonglong) +NCX_GETN_BYTE(schar, uchar) +NCX_GETN_BYTE(schar, short) +NCX_GETN_BYTE(schar, int) +NCX_GETN_BYTE(schar, long) +NCX_GETN_BYTE(schar, float) +NCX_GETN_BYTE(schar, double) +NCX_GETN_BYTE(schar, longlong) +NCX_GETN_BYTE(schar, ushort) +NCX_GETN_BYTE(schar, uint) +NCX_GETN_BYTE(schar, ulonglong) -dnl NCX_PAD_GETN_CHAR(schar, schar) +dnl NCX_PAD_GETN_BYTE(schar, schar) int -ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp) +APIPrefix`x_pad_getn_'NC_TYPE(schar)_schar(const void **xpp, IntType nelems, schar *tp) { NCX_PAD_GETN_Byte_Body } -dnl NCX_PAD_GETN_CHAR(schar, uchar) -int -ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp) -{ - NCX_PAD_GETN_Byte_Body -} -NCX_PAD_GETN_CHAR(schar, short) -NCX_PAD_GETN_CHAR(schar, int) -NCX_PAD_GETN_CHAR(schar, float) -NCX_PAD_GETN_CHAR(schar, double) -NCX_PAD_GETN_CHAR(schar, longlong) -NCX_PAD_GETN_CHAR(schar, ushort) -NCX_PAD_GETN_CHAR(schar, uint) -NCX_PAD_GETN_CHAR(schar, ulonglong) +NCX_PAD_GETN_BYTE(schar, uchar) +NCX_PAD_GETN_BYTE(schar, short) +NCX_PAD_GETN_BYTE(schar, int) +NCX_PAD_GETN_BYTE(schar, long) +NCX_PAD_GETN_BYTE(schar, float) +NCX_PAD_GETN_BYTE(schar, double) +NCX_PAD_GETN_BYTE(schar, longlong) +NCX_PAD_GETN_BYTE(schar, ushort) +NCX_PAD_GETN_BYTE(schar, uint) +NCX_PAD_GETN_BYTE(schar, ulonglong) -dnl NCX_PUTN_CHAR(schar, schar) -int -ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp) -{ - NCX_PUTN_Byte_Body -} -dnl NCX_PUTN_CHAR(schar, uchar) +dnl NCX_PUTN_BYTE(schar, schar) int -ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp) +APIPrefix`x_putn_'NC_TYPE(schar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp) { NCX_PUTN_Byte_Body } -NCX_PUTN_CHAR(schar, short) -NCX_PUTN_CHAR(schar, int) -NCX_PUTN_CHAR(schar, float) -NCX_PUTN_CHAR(schar, double) -NCX_PUTN_CHAR(schar, longlong) -NCX_PUTN_CHAR(schar, ushort) -NCX_PUTN_CHAR(schar, uint) -NCX_PUTN_CHAR(schar, ulonglong) +NCX_PUTN_BYTE(schar, uchar) +NCX_PUTN_BYTE(schar, short) +NCX_PUTN_BYTE(schar, int) +NCX_PUTN_BYTE(schar, long) +NCX_PUTN_BYTE(schar, float) +NCX_PUTN_BYTE(schar, double) +NCX_PUTN_BYTE(schar, longlong) +NCX_PUTN_BYTE(schar, ushort) +NCX_PUTN_BYTE(schar, uint) +NCX_PUTN_BYTE(schar, ulonglong) -dnl NCX_PAD_PUTN_CHAR(schar, schar) +dnl NCX_PAD_PUTN_BYTE(schar, schar) int -ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp) +APIPrefix`x_pad_putn_'NC_TYPE(schar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp) { NCX_PAD_PUTN_Byte_Body } -dnl NCX_PAD_PUTN_CHAR(schar, uchar) -int -ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp) -{ - NCX_PAD_PUTN_Byte_Body -} -NCX_PAD_PUTN_CHAR(schar, short) -NCX_PAD_PUTN_CHAR(schar, int) -NCX_PAD_PUTN_CHAR(schar, float) -NCX_PAD_PUTN_CHAR(schar, double) -NCX_PAD_PUTN_CHAR(schar, longlong) -NCX_PAD_PUTN_CHAR(schar, ushort) -NCX_PAD_PUTN_CHAR(schar, uint) -NCX_PAD_PUTN_CHAR(schar, ulonglong) +NCX_PAD_PUTN_BYTE(schar, uchar) +NCX_PAD_PUTN_BYTE(schar, short) +NCX_PAD_PUTN_BYTE(schar, int) +NCX_PAD_PUTN_BYTE(schar, long) +NCX_PAD_PUTN_BYTE(schar, float) +NCX_PAD_PUTN_BYTE(schar, double) +NCX_PAD_PUTN_BYTE(schar, longlong) +NCX_PAD_PUTN_BYTE(schar, ushort) +NCX_PAD_PUTN_BYTE(schar, uint) +NCX_PAD_PUTN_BYTE(schar, ulonglong) /* uchar ---------------------------------------------------------------------*/ dnl -dnl NCX_GETN_CHAR(uchar, schar) +dnl NCX_GETN_BYTE(uchar, schar) int -ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp) +APIPrefix`x_getn_'NC_TYPE(uchar)_schar(const void **xpp, IntType nelems, schar *tp) { - NCX_GETN_Byte_Body + int status = NC_NOERR; + uchar *xp = (uchar *)(*xpp); + + while (nelems-- != 0) { + if (*xp > SCHAR_MAX) { + *tp = NC_FILL_BYTE; + DEBUG_ASSIGN_ERROR(status, NC_ERANGE) + SKIP_LOOP(xp, tp) + } + *tp++ = (schar) *xp++; /* type cast from uchar to schar */ + } + + *xpp = (const void *)xp; + return status; } -dnl NCX_GETN_CHAR(uchar, uchar) +dnl NCX_GETN_BYTE(uchar, uchar) int -ncx_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp) +APIPrefix`x_getn_'NC_TYPE(uchar)_uchar(const void **xpp, IntType nelems, uchar *tp) { NCX_GETN_Byte_Body } -NCX_GETN_CHAR(uchar, short) -NCX_GETN_CHAR(uchar, int) -NCX_GETN_CHAR(uchar, float) -NCX_GETN_CHAR(uchar, double) -NCX_GETN_CHAR(uchar, longlong) -NCX_GETN_CHAR(uchar, ushort) -NCX_GETN_CHAR(uchar, uint) -NCX_GETN_CHAR(uchar, ulonglong) +NCX_GETN_BYTE(uchar, short) +NCX_GETN_BYTE(uchar, int) +NCX_GETN_BYTE(uchar, long) +NCX_GETN_BYTE(uchar, float) +NCX_GETN_BYTE(uchar, double) +NCX_GETN_BYTE(uchar, longlong) +NCX_GETN_BYTE(uchar, ushort) +NCX_GETN_BYTE(uchar, uint) +NCX_GETN_BYTE(uchar, ulonglong) + +dnl NCX_PAD_GETN_BYTE(uchar, schar) +int +APIPrefix`x_pad_getn_'NC_TYPE(uchar)_schar(const void **xpp, IntType nelems, schar *tp) +{ + int status = NC_NOERR; + IntType rndup = nelems % X_ALIGN; + uchar *xp = (uchar *) *xpp; + + if (rndup) rndup = X_ALIGN - rndup; + + while (nelems-- != 0) { + if (*xp > SCHAR_MAX) { + *tp = NC_FILL_BYTE; + DEBUG_ASSIGN_ERROR(status, NC_ERANGE) + SKIP_LOOP(xp, tp) + } + *tp++ = (schar) *xp++; /* type cast from uchar to schar */ + } -dnl NCX_PAD_GETN_CHAR(uchar, schar) -int -ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp) -{ - NCX_PAD_GETN_Byte_Body + *xpp = (void *)(xp + rndup); + return status; } -dnl NCX_PAD_GETN_CHAR(uchar, uchar) +dnl NCX_PAD_GETN_BYTE(uchar, uchar) int -ncx_pad_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp) +APIPrefix`x_pad_getn_'NC_TYPE(uchar)_uchar(const void **xpp, IntType nelems, uchar *tp) { NCX_PAD_GETN_Byte_Body } -NCX_PAD_GETN_CHAR(uchar, short) -NCX_PAD_GETN_CHAR(uchar, int) -NCX_PAD_GETN_CHAR(uchar, float) -NCX_PAD_GETN_CHAR(uchar, double) -NCX_PAD_GETN_CHAR(uchar, longlong) -NCX_PAD_GETN_CHAR(uchar, ushort) -NCX_PAD_GETN_CHAR(uchar, uint) -NCX_PAD_GETN_CHAR(uchar, ulonglong) +NCX_PAD_GETN_BYTE(uchar, short) +NCX_PAD_GETN_BYTE(uchar, int) +NCX_PAD_GETN_BYTE(uchar, long) +NCX_PAD_GETN_BYTE(uchar, float) +NCX_PAD_GETN_BYTE(uchar, double) +NCX_PAD_GETN_BYTE(uchar, longlong) +NCX_PAD_GETN_BYTE(uchar, ushort) +NCX_PAD_GETN_BYTE(uchar, uint) +NCX_PAD_GETN_BYTE(uchar, ulonglong) + +dnl NCX_PUTN_BYTE(uchar, schar) +int +APIPrefix`x_putn_'NC_TYPE(uchar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp) +{ + int status = NC_NOERR; + uchar *xp = (uchar *) *xpp; + + while (nelems-- != 0) { + if (*tp < 0) { + FillValue(uchar, xp) + DEBUG_ASSIGN_ERROR(status, NC_ERANGE) + SKIP_LOOP(xp, tp) + } + *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */ + } -dnl NCX_PUTN_CHAR(uchar, schar) -int -ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp) -{ - NCX_PUTN_Byte_Body + *xpp = (void *)xp; + return status; } -dnl NCX_PUTN_CHAR(uchar, uchar) +dnl NCX_PUTN_BYTE(uchar, uchar) int -ncx_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp) +APIPrefix`x_putn_'NC_TYPE(uchar)_uchar(void **xpp, IntType nelems, const uchar *tp, void *fillp) { NCX_PUTN_Byte_Body } -NCX_PUTN_CHAR(uchar, short) -NCX_PUTN_CHAR(uchar, int) -NCX_PUTN_CHAR(uchar, float) -NCX_PUTN_CHAR(uchar, double) -NCX_PUTN_CHAR(uchar, longlong) -NCX_PUTN_CHAR(uchar, ushort) -NCX_PUTN_CHAR(uchar, uint) -NCX_PUTN_CHAR(uchar, ulonglong) +NCX_PUTN_BYTE(uchar, short) +NCX_PUTN_BYTE(uchar, int) +NCX_PUTN_BYTE(uchar, long) +NCX_PUTN_BYTE(uchar, float) +NCX_PUTN_BYTE(uchar, double) +NCX_PUTN_BYTE(uchar, longlong) +NCX_PUTN_BYTE(uchar, ushort) +NCX_PUTN_BYTE(uchar, uint) +NCX_PUTN_BYTE(uchar, ulonglong) + +dnl NCX_PAD_PUTN_BYTE(uchar, schar) +int +APIPrefix`x_pad_putn_'NC_TYPE(uchar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp) +{ + int status = NC_NOERR; + IntType rndup = nelems % X_ALIGN; + uchar *xp = (uchar *) *xpp; + + if (rndup) rndup = X_ALIGN - rndup; + + while (nelems-- != 0) { + if (*tp < 0) { + FillValue(uchar, xp) + DEBUG_ASSIGN_ERROR(status, NC_ERANGE) + SKIP_LOOP(xp, tp) + } + *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */ + } -dnl NCX_PAD_PUTN_UCHAR(uchar, schar) -int -ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp) -{ - NCX_PAD_PUTN_Byte_Body + if (rndup) { + (void) memcpy(xp, nada, (size_t)rndup); + xp += rndup; + } + + *xpp = (void *)xp; + return status; } dnl NCX_PAD_PUTN_UCHAR(uchar, uchar) int -ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp) +APIPrefix`x_pad_putn_'NC_TYPE(uchar)_uchar(void **xpp, IntType nelems, const uchar *tp, void *fillp) { NCX_PAD_PUTN_Byte_Body } -NCX_PAD_PUTN_CHAR(uchar, short) -NCX_PAD_PUTN_CHAR(uchar, int) -NCX_PAD_PUTN_CHAR(uchar, float) -NCX_PAD_PUTN_CHAR(uchar, double) -NCX_PAD_PUTN_CHAR(uchar, longlong) -NCX_PAD_PUTN_CHAR(uchar, ushort) -NCX_PAD_PUTN_CHAR(uchar, uint) -NCX_PAD_PUTN_CHAR(uchar, ulonglong) +NCX_PAD_PUTN_BYTE(uchar, short) +NCX_PAD_PUTN_BYTE(uchar, int) +NCX_PAD_PUTN_BYTE(uchar, long) +NCX_PAD_PUTN_BYTE(uchar, float) +NCX_PAD_PUTN_BYTE(uchar, double) +NCX_PAD_PUTN_BYTE(uchar, longlong) +NCX_PAD_PUTN_BYTE(uchar, ushort) +NCX_PAD_PUTN_BYTE(uchar, uint) +NCX_PAD_PUTN_BYTE(uchar, ulonglong) /* short ---------------------------------------------------------------------*/ #if X_SIZEOF_SHORT == SIZEOF_SHORT /* optimized version */ int -ncx_getn_short_short(const void **xpp, size_t nelems, short *tp) +APIPrefix`x_getn_'NC_TYPE(short)_short(const void **xpp, IntType nelems, short *tp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(tp, *xpp, nelems * sizeof(short)); + (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT); # else swapn2b(tp, *xpp, nelems); # endif @@ -2730,6 +3070,7 @@ NCX_GETN(short, short) #endif NCX_GETN(short, schar) NCX_GETN(short, int) +NCX_GETN(short, long) NCX_GETN(short, float) NCX_GETN(short, double) NCX_GETN(short, longlong) @@ -2742,6 +3083,7 @@ NCX_PAD_GETN_SHORT(short, schar) NCX_PAD_GETN_SHORT(short, uchar) NCX_PAD_GETN_SHORT(short, short) NCX_PAD_GETN_SHORT(short, int) +NCX_PAD_GETN_SHORT(short, long) NCX_PAD_GETN_SHORT(short, float) NCX_PAD_GETN_SHORT(short, double) NCX_PAD_GETN_SHORT(short, uint) @@ -2752,10 +3094,10 @@ NCX_PAD_GETN_SHORT(short, ushort) #if X_SIZEOF_SHORT == SIZEOF_SHORT /* optimized version */ int -ncx_putn_short_short(void **xpp, size_t nelems, const short *tp) +APIPrefix`x_putn_'NC_TYPE(short)_short(void **xpp, IntType nelems, const short *tp, void *fillp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(*xpp, tp, nelems * X_SIZEOF_SHORT); + (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT); # else swapn2b(*xpp, tp, nelems); # endif @@ -2767,6 +3109,7 @@ NCX_PUTN(short, short) #endif NCX_PUTN(short, schar) NCX_PUTN(short, int) +NCX_PUTN(short, long) NCX_PUTN(short, float) NCX_PUTN(short, double) NCX_PUTN(short, longlong) @@ -2779,6 +3122,7 @@ NCX_PAD_PUTN_SHORT(short, schar) NCX_PAD_PUTN_SHORT(short, uchar) NCX_PAD_PUTN_SHORT(short, short) NCX_PAD_PUTN_SHORT(short, int) +NCX_PAD_PUTN_SHORT(short, long) NCX_PAD_PUTN_SHORT(short, float) NCX_PAD_PUTN_SHORT(short, double) NCX_PAD_PUTN_SHORT(short, uint) @@ -2792,10 +3136,10 @@ NCX_PAD_PUTN_SHORT(short, ushort) #if X_SIZEOF_USHORT == SIZEOF_USHORT /* optimized version */ int -ncx_getn_ushort_ushort(const void **xpp, size_t nelems, unsigned short *tp) +APIPrefix`x_getn_'NC_TYPE(ushort)_ushort(const void **xpp, IntType nelems, unsigned short *tp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(tp, *xpp, nelems * sizeof(unsigned short)); + (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_USHORT); # else swapn2b(tp, *xpp, nelems); # endif @@ -2808,6 +3152,7 @@ NCX_GETN(ushort, ushort) NCX_GETN(ushort, schar) NCX_GETN(ushort, short) NCX_GETN(ushort, int) +NCX_GETN(ushort, long) NCX_GETN(ushort, float) NCX_GETN(ushort, double) NCX_GETN(ushort, longlong) @@ -2816,23 +3161,24 @@ NCX_GETN(ushort, uint) NCX_GETN(ushort, ulonglong) NCX_PAD_GETN_SHORT(ushort, schar) -NCX_PAD_GETN_SHORT(ushort, uchar) NCX_PAD_GETN_SHORT(ushort, short) -NCX_PAD_GETN_SHORT(ushort, ushort) NCX_PAD_GETN_SHORT(ushort, int) -NCX_PAD_GETN_SHORT(ushort, uint) +NCX_PAD_GETN_SHORT(ushort, long) NCX_PAD_GETN_SHORT(ushort, float) NCX_PAD_GETN_SHORT(ushort, double) +NCX_PAD_GETN_SHORT(ushort, uchar) +NCX_PAD_GETN_SHORT(ushort, ushort) +NCX_PAD_GETN_SHORT(ushort, uint) NCX_PAD_GETN_SHORT(ushort, longlong) NCX_PAD_GETN_SHORT(ushort, ulonglong) #if X_SIZEOF_USHORT == SIZEOF_USHORT /* optimized version */ int -ncx_putn_ushort_ushort(void **xpp, size_t nelems, const unsigned short *tp) +APIPrefix`x_putn_'NC_TYPE(ushort)_ushort(void **xpp, IntType nelems, const unsigned short *tp, void *fillp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(*xpp, tp, nelems * X_SIZEOF_USHORT); + (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT); # else swapn2b(*xpp, tp, nelems); # endif @@ -2845,6 +3191,7 @@ NCX_PUTN(ushort, ushort) NCX_PUTN(ushort, schar) NCX_PUTN(ushort, short) NCX_PUTN(ushort, int) +NCX_PUTN(ushort, long) NCX_PUTN(ushort, float) NCX_PUTN(ushort, double) NCX_PUTN(ushort, longlong) @@ -2856,6 +3203,7 @@ NCX_PAD_PUTN_SHORT(ushort, schar) NCX_PAD_PUTN_SHORT(ushort, uchar) NCX_PAD_PUTN_SHORT(ushort, short) NCX_PAD_PUTN_SHORT(ushort, int) +NCX_PAD_PUTN_SHORT(ushort, long) NCX_PAD_PUTN_SHORT(ushort, float) NCX_PAD_PUTN_SHORT(ushort, double) NCX_PAD_PUTN_SHORT(ushort, uint) @@ -2869,10 +3217,10 @@ NCX_PAD_PUTN_SHORT(ushort, ushort) #if X_SIZEOF_INT == SIZEOF_INT /* optimized version */ int -ncx_getn_int_int(const void **xpp, size_t nelems, int *tp) +APIPrefix`x_getn_'NC_TYPE(int)_int(const void **xpp, IntType nelems, int *tp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(tp, *xpp, nelems * sizeof(int)); + (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT); # else swapn4b(tp, *xpp, nelems); # endif @@ -2884,6 +3232,7 @@ NCX_GETN(int, int) #endif NCX_GETN(int, schar) NCX_GETN(int, short) +NCX_GETN(int, long) NCX_GETN(int, float) NCX_GETN(int, double) NCX_GETN(int, longlong) @@ -2895,10 +3244,10 @@ NCX_GETN(int, ulonglong) #if X_SIZEOF_INT == SIZEOF_INT /* optimized version */ int -ncx_putn_int_int(void **xpp, size_t nelems, const int *tp) +APIPrefix`x_putn_'NC_TYPE(int)_int(void **xpp, IntType nelems, const int *tp, void *fillp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(*xpp, tp, nelems * X_SIZEOF_INT); + (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT); # else swapn4b(*xpp, tp, nelems); # endif @@ -2910,6 +3259,7 @@ NCX_PUTN(int, int) #endif NCX_PUTN(int, schar) NCX_PUTN(int, short) +NCX_PUTN(int, long) NCX_PUTN(int, float) NCX_PUTN(int, double) NCX_PUTN(int, longlong) @@ -2923,10 +3273,10 @@ NCX_PUTN(int, ulonglong) #if X_SIZEOF_UINT == SIZEOF_UINT /* optimized version */ int -ncx_getn_uint_uint(const void **xpp, size_t nelems, unsigned int *tp) +APIPrefix`x_getn_'NC_TYPE(uint)_uint(const void **xpp, IntType nelems, unsigned int *tp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(tp, *xpp, nelems * sizeof(uint)); + (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT); # else swapn4b(tp, *xpp, nelems); # endif @@ -2939,6 +3289,7 @@ NCX_GETN(uint, uint) NCX_GETN(uint, schar) NCX_GETN(uint, short) NCX_GETN(uint, int) +NCX_GETN(uint, long) NCX_GETN(uint, float) NCX_GETN(uint, double) NCX_GETN(uint, longlong) @@ -2949,10 +3300,10 @@ NCX_GETN(uint, ulonglong) #if X_SIZEOF_UINT == SIZEOF_UINT /* optimized version */ int -ncx_putn_uint_uint(void **xpp, size_t nelems, const unsigned int *tp) +APIPrefix`x_putn_'NC_TYPE(uint)_uint(void **xpp, IntType nelems, const unsigned int *tp, void *fillp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(*xpp, tp, nelems * X_SIZEOF_UINT); + (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT); # else swapn4b(*xpp, tp, nelems); # endif @@ -2965,6 +3316,7 @@ NCX_PUTN(uint, uint) NCX_PUTN(uint, schar) NCX_PUTN(uint, short) NCX_PUTN(uint, int) +NCX_PUTN(uint, long) NCX_PUTN(uint, float) NCX_PUTN(uint, double) NCX_PUTN(uint, longlong) @@ -2978,23 +3330,23 @@ NCX_PUTN(uint, ulonglong) #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT) /* optimized version */ int -ncx_getn_float_float(const void **xpp, size_t nelems, float *tp) +APIPrefix`x_getn_'NC_TYPE(float)_float(const void **xpp, IntType nelems, float *tp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(tp, *xpp, nelems * sizeof(float)); + (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT); # else swapn4b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT); return NC_NOERR; } -#elif vax +#elif defined(vax) && vax != 0 int -ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip) +APIPrefix`x_getn_'NC_TYPE(float)_float(const void **xpp, IntType nfloats, float *ip) { float *const end = ip + nfloats; - while(ip < end) + while (ip < end) { GET_VAX_DFLOAT_Body(`(*xpp)') @@ -3005,15 +3357,15 @@ GET_VAX_DFLOAT_Body(`(*xpp)') } #else int -ncx_getn_float_float(const void **xpp, size_t nelems, float *tp) +APIPrefix`x_getn_'NC_TYPE(float)_float(const void **xpp, IntType nelems, float *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { - const int lstatus = ncx_get_float_float(xp, tp); - if(lstatus != NC_NOERR) + const int lstatus = APIPrefix`x_get_'NC_TYPE(float)_float(xp, tp, fillp); + if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } @@ -3025,6 +3377,7 @@ ncx_getn_float_float(const void **xpp, size_t nelems, float *tp) NCX_GETN(float, schar) NCX_GETN(float, short) NCX_GETN(float, int) +NCX_GETN(float, long) NCX_GETN(float, double) NCX_GETN(float, longlong) NCX_GETN(float, ushort) @@ -3032,45 +3385,38 @@ NCX_GETN(float, uchar) NCX_GETN(float, uint) NCX_GETN(float, ulonglong) +int +APIPrefix`x_putn_'NC_TYPE(float)_float(void **xpp, IntType nelems, const float *tp, void *fillp) #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT) /* optimized version */ -int -ncx_putn_float_float(void **xpp, size_t nelems, const float *tp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(*xpp, tp, nelems * X_SIZEOF_FLOAT); + (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT); # else swapn4b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT); return NC_NOERR; } -#elif vax -int -ncx_putn_float_float(void **xpp, size_t nfloats, const float *ip) +#elif defined(vax) && vax != 0 { - const float *const end = ip + nfloats; - - while(ip < end) - { -PUT_VAX_DFLOAT_Body(`(*xpp)') + const float *const end = tp + nelems; - ip++; + while (tp < end) { + PUT_VAX_DFLOAT_Body(`(*xpp)') + tp++; *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT; } return NC_NOERR; } #else -int -ncx_putn_float_float(void **xpp, size_t nelems, const float *tp) { char *xp = *xpp; int status = NC_NOERR; - for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) - { - int lstatus = ncx_put_float_float(xp, tp); - if(lstatus != NC_NOERR) + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { + int lstatus = APIPrefix`x_put_'NC_TYPE(float)_float(xp, tp, fillp); + if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } @@ -3081,6 +3427,7 @@ ncx_putn_float_float(void **xpp, size_t nelems, const float *tp) NCX_PUTN(float, schar) NCX_PUTN(float, short) NCX_PUTN(float, int) +NCX_PUTN(float, long) NCX_PUTN(float, double) NCX_PUTN(float, longlong) NCX_PUTN(float, uchar) @@ -3093,23 +3440,23 @@ NCX_PUTN(float, ulonglong) #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) /* optimized version */ int -ncx_getn_double_double(const void **xpp, size_t nelems, double *tp) +APIPrefix`x_getn_'NC_TYPE(double)_double(const void **xpp, IntType nelems, double *tp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(tp, *xpp, nelems * sizeof(double)); + (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE); # else swapn8b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); return NC_NOERR; } -#elif vax +#elif defined(vax) && vax != 0 int -ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip) +APIPrefix`x_getn_'NC_TYPE(double)_double(const void **xpp, IntType ndoubles, double *ip) { double *const end = ip + ndoubles; - while(ip < end) + while (ip < end) { GET_VAX_DDOUBLE_Body(`(*xpp)') ip++; @@ -3120,15 +3467,15 @@ GET_VAX_DDOUBLE_Body(`(*xpp)') /* vax */ #else int -ncx_getn_double_double(const void **xpp, size_t nelems, double *tp) +APIPrefix`x_getn_'NC_TYPE(double)_double(const void **xpp, IntType nelems, double *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { - const int lstatus = ncx_get_double_double(xp, tp); - if(lstatus != NC_NOERR) + const int lstatus = APIPrefix`x_get_'NC_TYPE(double)_double(xp, tp, fillp); + if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } @@ -3139,6 +3486,7 @@ ncx_getn_double_double(const void **xpp, size_t nelems, double *tp) NCX_GETN(double, schar) NCX_GETN(double, short) NCX_GETN(double, int) +NCX_GETN(double, long) NCX_GETN(double, float) NCX_GETN(double, longlong) NCX_GETN(double, uchar) @@ -3149,23 +3497,23 @@ NCX_GETN(double, ulonglong) #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) /* optimized version */ int -ncx_putn_double_double(void **xpp, size_t nelems, const double *tp) +APIPrefix`x_putn_'NC_TYPE(double)_double(void **xpp, IntType nelems, const double *tp, void *fillp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(*xpp, tp, nelems * X_SIZEOF_DOUBLE); + (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE); # else swapn8b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); return NC_NOERR; } -#elif vax +#elif defined(vax) && vax != 0 int -ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip) +APIPrefix`x_putn_'NC_TYPE(double)_double(void **xpp, IntType ndoubles, const double *ip, void *fillp) { const double *const end = ip + ndoubles; - while(ip < end) + while (ip < end) { PUT_VAX_DDOUBLE_Body(`(*xpp)') ip++; @@ -3176,15 +3524,15 @@ PUT_VAX_DDOUBLE_Body(`(*xpp)') /* vax */ #else int -ncx_putn_double_double(void **xpp, size_t nelems, const double *tp) +APIPrefix`x_putn_'NC_TYPE(double)_double(void **xpp, IntType nelems, const double *tp, void *fillp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { - int lstatus = ncx_put_double_double(xp, tp); - if(lstatus != NC_NOERR) + int lstatus = APIPrefix`x_put_'NC_TYPE(double)_double(xp, tp, fillp); + if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } @@ -3195,6 +3543,7 @@ ncx_putn_double_double(void **xpp, size_t nelems, const double *tp) NCX_PUTN(double, schar) NCX_PUTN(double, short) NCX_PUTN(double, int) +NCX_PUTN(double, long) NCX_PUTN(double, float) NCX_PUTN(double, longlong) NCX_PUTN(double, uchar) @@ -3203,113 +3552,117 @@ NCX_PUTN(double, uint) NCX_PUTN(double, ulonglong) -/* longlong -----------------------------------------------------------------------*/ +/* longlong ------------------------------------------------------------------*/ -#if X_SIZEOF_LONGLONG == SIZEOF_LONGLONG +#if X_SIZEOF_INT64 == SIZEOF_LONGLONG /* optimized version */ int -ncx_getn_longlong_longlong(const void **xpp, size_t nelems, long long *tp) +APIPrefix`x_getn_'NC_TYPE(int64)_longlong(const void **xpp, IntType nelems, long long *tp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(tp, *xpp, nelems * sizeof(long long)); + (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG); # else swapn8b(tp, *xpp, nelems); # endif - *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_LONGLONG); + *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64); return NC_NOERR; } #else -NCX_GETN(longlong, longlong) -#endif -NCX_GETN(longlong, schar) -NCX_GETN(longlong, short) -NCX_GETN(longlong, int) -NCX_GETN(longlong, float) -NCX_GETN(longlong, double) -NCX_GETN(longlong, uchar) -NCX_GETN(longlong, ushort) -NCX_GETN(longlong, uint) -NCX_GETN(longlong, ulonglong) - -#if X_SIZEOF_LONGLONG == SIZEOF_LONGLONG +NCX_GETN(int64, longlong) +#endif +NCX_GETN(int64, schar) +NCX_GETN(int64, short) +NCX_GETN(int64, int) +NCX_GETN(int64, long) +NCX_GETN(int64, float) +NCX_GETN(int64, double) +NCX_GETN(int64, uchar) +NCX_GETN(int64, ushort) +NCX_GETN(int64, uint) +NCX_GETN(int64, ulonglong) + +#if X_SIZEOF_INT64 == SIZEOF_LONGLONG /* optimized version */ int -ncx_putn_longlong_longlong(void **xpp, size_t nelems, const long long *tp) +APIPrefix`x_putn_'NC_TYPE(int64)_longlong(void **xpp, IntType nelems, const long long *tp, void *fillp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(*xpp, tp, nelems * X_SIZEOF_LONGLONG); + (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64); # else swapn8b(*xpp, tp, nelems); # endif - *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_LONGLONG); + *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64); return NC_NOERR; } #else -NCX_PUTN(longlong, longlong) -#endif -NCX_PUTN(longlong, schar) -NCX_PUTN(longlong, short) -NCX_PUTN(longlong, int) -NCX_PUTN(longlong, float) -NCX_PUTN(longlong, double) -NCX_PUTN(longlong, uchar) -NCX_PUTN(longlong, ushort) -NCX_PUTN(longlong, uint) -NCX_PUTN(longlong, ulonglong) - -/* ulonglong ----------------------------------------------------------------------*/ - -#if X_SIZEOF_ULONGLONG == SIZEOF_ULONGLONG +NCX_PUTN(int64, longlong) +#endif +NCX_PUTN(int64, schar) +NCX_PUTN(int64, short) +NCX_PUTN(int64, int) +NCX_PUTN(int64, long) +NCX_PUTN(int64, float) +NCX_PUTN(int64, double) +NCX_PUTN(int64, uchar) +NCX_PUTN(int64, ushort) +NCX_PUTN(int64, uint) +NCX_PUTN(int64, ulonglong) + +/* uint64 --------------------------------------------------------------------*/ + +#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG /* optimized version */ int -ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, unsigned long long *tp) +APIPrefix`x_getn_'NC_TYPE(uint64)_ulonglong(const void **xpp, IntType nelems, unsigned long long *tp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(tp, *xpp, nelems * sizeof(unsigned long long)); + (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG); # else swapn8b(tp, *xpp, nelems); # endif - *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_ULONGLONG); + *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64); return NC_NOERR; } #else -NCX_GETN(ulonglong, ulonglong) -#endif -NCX_GETN(ulonglong, schar) -NCX_GETN(ulonglong, short) -NCX_GETN(ulonglong, int) -NCX_GETN(ulonglong, float) -NCX_GETN(ulonglong, double) -NCX_GETN(ulonglong, longlong) -NCX_GETN(ulonglong, uchar) -NCX_GETN(ulonglong, ushort) -NCX_GETN(ulonglong, uint) - -#if X_SIZEOF_ULONGLONG == SIZEOF_ULONGLONG +NCX_GETN(uint64, ulonglong) +#endif +NCX_GETN(uint64, schar) +NCX_GETN(uint64, short) +NCX_GETN(uint64, int) +NCX_GETN(uint64, long) +NCX_GETN(uint64, float) +NCX_GETN(uint64, double) +NCX_GETN(uint64, longlong) +NCX_GETN(uint64, uchar) +NCX_GETN(uint64, ushort) +NCX_GETN(uint64, uint) + +#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG /* optimized version */ int -ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const unsigned long long *tp) +APIPrefix`x_putn_'NC_TYPE(uint64)_ulonglong(void **xpp, IntType nelems, const unsigned long long *tp, void *fillp) { #ifdef WORDS_BIGENDIAN - (void) memcpy(*xpp, tp, nelems * X_SIZEOF_ULONGLONG); + (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64); # else swapn8b(*xpp, tp, nelems); # endif - *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_ULONGLONG); + *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64); return NC_NOERR; } #else -NCX_PUTN(ulonglong, ulonglong) +NCX_PUTN(uint64, ulonglong) #endif -NCX_PUTN(ulonglong, schar) -NCX_PUTN(ulonglong, short) -NCX_PUTN(ulonglong, int) -NCX_PUTN(ulonglong, float) -NCX_PUTN(ulonglong, double) -NCX_PUTN(ulonglong, longlong) -NCX_PUTN(ulonglong, uchar) -NCX_PUTN(ulonglong, ushort) -NCX_PUTN(ulonglong, uint) +NCX_PUTN(uint64, schar) +NCX_PUTN(uint64, short) +NCX_PUTN(uint64, int) +NCX_PUTN(uint64, long) +NCX_PUTN(uint64, float) +NCX_PUTN(uint64, double) +NCX_PUTN(uint64, longlong) +NCX_PUTN(uint64, uchar) +NCX_PUTN(uint64, ushort) +NCX_PUTN(uint64, uint) /* @@ -3317,45 +3670,27 @@ NCX_PUTN(ulonglong, uint) */ /* text */ -#ifdef __arm__ -int -ncx_getn_text(const void **xpp, size_t nelems, signed char *tp) -#else + int -ncx_getn_text(const void **xpp, size_t nelems, char *tp) -#endif +APIPrefix`x_getn_text'(const void **xpp, IntType nelems, char *tp) { NCX_GETN_Byte_Body } -#ifdef __arm__ -int -ncx_pad_getn_text(const void **xpp, size_t nelems, signed char *tp) -#else int -ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp) -#endif +APIPrefix`x_pad_getn_text'(const void **xpp, IntType nelems, char *tp) { NCX_PAD_GETN_Byte_Body } -#ifdef __arm__ -int ncx_putn_text(void **xpp, size_t nelems, const signed char *tp) -#else int -ncx_putn_text(void **xpp, size_t nelems, const char *tp) -#endif +APIPrefix`x_putn_text'(void **xpp, IntType nelems, const char *tp) { NCX_PUTN_Byte_Body } -#ifdef __arm__ -int -ncx_pad_putn_text(void **xpp, size_t nelems, const signed char *tp) -#else int -ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp) -#endif +APIPrefix`x_pad_putn_text'(void **xpp, IntType nelems, const char *tp) { NCX_PAD_PUTN_Byte_Body } @@ -3364,25 +3699,25 @@ NCX_PAD_PUTN_Byte_Body /* opaque */ int -ncx_getn_void(const void **xpp, size_t nelems, void *tp) +APIPrefix`x_getn_void'(const void **xpp, IntType nelems, void *tp) { NCX_GETN_Byte_Body } int -ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp) +APIPrefix`x_pad_getn_void'(const void **xpp, IntType nelems, void *tp) { NCX_PAD_GETN_Byte_Body } int -ncx_putn_void(void **xpp, size_t nelems, const void *tp) +APIPrefix`x_putn_void'(void **xpp, IntType nelems, const void *tp) { NCX_PUTN_Byte_Body } int -ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp) +APIPrefix`x_pad_putn_void'(void **xpp, IntType nelems, const void *tp) { NCX_PAD_PUTN_Byte_Body } diff --git a/libsrc/ncx_cray.c b/libsrc/ncx_cray.c index 9fe32696b0..ce56ed9400 100644 --- a/libsrc/ncx_cray.c +++ b/libsrc/ncx_cray.c @@ -8,6 +8,10 @@ #error "ncx_cray.c is a cray specific implementation" #endif +#if HAVE_CONFIG_H +#include +#endif + /* * An external data representation interface. */ diff --git a/libsrc/posixio.c b/libsrc/posixio.c index 9965c59e5f..67fe48f810 100644 --- a/libsrc/posixio.c +++ b/libsrc/posixio.c @@ -6,8 +6,10 @@ /* For MinGW Build */ +#if HAVE_CONFIG_H +#include +#endif -#include "config.h" #include #include #include diff --git a/libsrc/putget.m4 b/libsrc/putget.m4 index e254b754a2..bf37fb082d 100644 --- a/libsrc/putget.m4 +++ b/libsrc/putget.m4 @@ -14,7 +14,10 @@ dnl */ /* $Id: putget.m4 2783 2014-10-26 05:19:35Z wkliao $ */ -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -101,7 +104,7 @@ NC_fill_$2( *vp++ = $4; } } - return ncx_putn_$2_$1(xpp, nelems, fillp); + return ncx_putn_$2_$1(xpp, nelems, fillp ifelse(`$1',`char',,`,NULL')); } ')dnl @@ -541,7 +544,11 @@ NCcoordck(NC3_INFO* ncp, const NC_var *varp, const size_t *coord) { if(*coord > X_UINT_MAX) /* rkr: bug fix from previous X_INT_MAX */ return NC_EINVALCOORDS; /* sanity check */ +#ifdef RELAX_COORD_BOUND + if(NC_readonly(ncp) && *coord > NC_get_numrecs(ncp)) +#else if(NC_readonly(ncp) && *coord >= NC_get_numrecs(ncp)) +#endif { if(!NC_doNsync(ncp)) return NC_EINVALCOORDS; @@ -551,7 +558,11 @@ NCcoordck(NC3_INFO* ncp, const NC_var *varp, const size_t *coord) const int status = read_numrecs(ncp); if(status != NC_NOERR) return status; +#ifdef RELAX_COORD_BOUND + if(*coord > NC_get_numrecs(ncp)) +#else if(*coord >= NC_get_numrecs(ncp)) +#endif return NC_EINVALCOORDS; } } @@ -578,7 +589,11 @@ fprintf(stderr," NCcoordck: ip %p, *ip %ld, up %p, *up %lu\n", #endif /* CDEBUG */ /* cast needed for braindead systems with signed size_t */ +#ifdef RELAX_COORD_BOUND + if((unsigned long) *ip > (unsigned long) *up ) +#else if((unsigned long) *ip >= (unsigned long) *up ) +#endif return NC_EINVALCOORDS; } @@ -602,6 +617,11 @@ NCedgeck(const NC3_INFO* ncp, const NC_var *varp, if(IS_RECVAR(varp)) { +#ifdef RELAX_COORD_BOUND + if (NC_readonly(ncp) && + (start[0] == NC_get_numrecs(ncp) && edges[0] > 0)) + return(NC_EINVALCOORDS); +#endif start++; edges++; shp++; @@ -609,6 +629,10 @@ NCedgeck(const NC3_INFO* ncp, const NC_var *varp, for(; start < end; start++, edges++, shp++) { +#ifdef RELAX_COORD_BOUND + if ((unsigned long) *start == *shp && *edges > 0) + return(NC_EINVALCOORDS); +#endif /* cast needed for braindead systems with signed size_t */ if((unsigned long) *edges > *shp || (unsigned long) *start + (unsigned long) *edges > *shp) @@ -680,12 +704,16 @@ putNCvx_$1_$2(NC3_INFO* ncp, const NC_var *varp, size_t remaining = varp->xsz * nelems; int status = NC_NOERR; void *xp; + void *fillp; if(nelems == 0) return NC_NOERR; assert(value != NULL); + fillp = malloc(varp->xsz); + status = NC3_inq_var_fill(varp, fillp); + for(;;) { size_t extent = MIN(remaining, ncp->chunk); @@ -696,7 +724,7 @@ putNCvx_$1_$2(NC3_INFO* ncp, const NC_var *varp, if(lstatus != NC_NOERR) return lstatus; - lstatus = ncx_putn_$1_$2(&xp, nput, value); + lstatus = ncx_putn_$1_$2(&xp, nput, value ifelse(`$1',`char',,`,fillp')); if(lstatus != NC_NOERR && status == NC_NOERR) { /* not fatal to the loop */ @@ -709,10 +737,11 @@ putNCvx_$1_$2(NC3_INFO* ncp, const NC_var *varp, remaining -= extent; if(remaining == 0) break; /* normal loop exit */ - offset += extent; + offset += (off_t)extent; value += nput; } + free(fillp); return status; } @@ -868,7 +897,7 @@ getNCvx_$1_$2(const NC3_INFO* ncp, const NC_var *varp, remaining -= extent; if(remaining == 0) break; /* normal loop exit */ - offset += extent; + offset += (off_t)extent; value += nget; } @@ -1172,10 +1201,14 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, #endif break; case CASE(NC_BYTE,NC_BYTE): - return getNCvx_schar_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_schar_schar(ncp,varp,start,nelems, (schar*)value); break; case CASE(NC_BYTE,NC_UBYTE): - return getNCvx_schar_uchar(ncp,varp,start,nelems,(unsigned char*)value); + if (fIsSet(ncp->flags,NC_64BIT_DATA)) + return getNCvx_schar_uchar(ncp,varp,start,nelems,(unsigned char*)value); + else + /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */ + return getNCvx_uchar_uchar(ncp,varp,start,nelems,(unsigned char*)value); break; case CASE(NC_BYTE,NC_SHORT): return getNCvx_schar_short(ncp,varp,start,nelems,(short*)value); @@ -1202,7 +1235,7 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, return getNCvx_schar_ushort(ncp,varp,start,nelems,(unsigned short*)value); break; case CASE(NC_SHORT,NC_BYTE): - return getNCvx_short_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_short_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_SHORT,NC_UBYTE): return getNCvx_short_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1233,7 +1266,7 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, break; case CASE(NC_INT,NC_BYTE): - return getNCvx_int_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_int_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_INT,NC_UBYTE): return getNCvx_int_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1264,7 +1297,7 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, break; case CASE(NC_FLOAT,NC_BYTE): - return getNCvx_float_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_float_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_FLOAT,NC_UBYTE): return getNCvx_float_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1295,7 +1328,7 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, break; case CASE(NC_DOUBLE,NC_BYTE): - return getNCvx_double_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_double_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_DOUBLE,NC_UBYTE): return getNCvx_double_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1329,7 +1362,7 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, return getNCvx_uchar_uchar(ncp,varp,start,nelems,(unsigned char*)value); break; case CASE(NC_UBYTE,NC_BYTE): - return getNCvx_uchar_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_uchar_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_UBYTE,NC_SHORT): return getNCvx_uchar_short(ncp,varp,start,nelems,(short*)value); @@ -1357,7 +1390,7 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, break; case CASE(NC_USHORT,NC_BYTE): - return getNCvx_ushort_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_ushort_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_USHORT,NC_UBYTE): return getNCvx_ushort_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1388,7 +1421,7 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, break; case CASE(NC_UINT,NC_BYTE): - return getNCvx_uint_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_uint_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_UINT,NC_UBYTE): return getNCvx_uint_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1419,7 +1452,7 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, break; case CASE(NC_INT64,NC_BYTE): - return getNCvx_longlong_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_longlong_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_INT64,NC_UBYTE): return getNCvx_longlong_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1450,7 +1483,7 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start, break; case CASE(NC_UINT64,NC_BYTE): - return getNCvx_ulonglong_schar(ncp,varp,start,nelems,(signed char*)value); + return getNCvx_ulonglong_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_UINT64,NC_UBYTE): return getNCvx_ulonglong_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1500,10 +1533,14 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_char_char(ncp,varp,start,nelems,(char*)value); break; case CASE(NC_BYTE,NC_BYTE): - return putNCvx_schar_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_schar_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_BYTE,NC_UBYTE): - return putNCvx_schar_uchar(ncp,varp,start,nelems,(unsigned char*)value); + if (fIsSet(ncp->flags,NC_64BIT_DATA)) + return putNCvx_schar_uchar(ncp,varp,start,nelems,(unsigned char*)value); + else + /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */ + return putNCvx_uchar_uchar(ncp,varp,start,nelems,(unsigned char*)value); break; case CASE(NC_BYTE,NC_SHORT): return putNCvx_schar_short(ncp,varp,start,nelems,(short*)value); @@ -1530,7 +1567,7 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_schar_ushort(ncp,varp,start,nelems,(unsigned short*)value); break; case CASE(NC_SHORT,NC_BYTE): - return putNCvx_short_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_short_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_SHORT,NC_UBYTE): return putNCvx_short_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1560,7 +1597,7 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_short_ushort(ncp,varp,start,nelems,(unsigned short*)value); break; case CASE(NC_INT,NC_BYTE): - return putNCvx_int_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_int_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_INT,NC_UBYTE): return putNCvx_int_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1590,7 +1627,7 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_int_ushort(ncp,varp,start,nelems,(unsigned short*)value); break; case CASE(NC_FLOAT,NC_BYTE): - return putNCvx_float_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_float_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_FLOAT,NC_UBYTE): return putNCvx_float_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1620,7 +1657,7 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_float_ushort(ncp,varp,start,nelems,(unsigned short*)value); break; case CASE(NC_DOUBLE,NC_BYTE): - return putNCvx_double_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_double_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_DOUBLE,NC_UBYTE): return putNCvx_double_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1653,7 +1690,7 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_uchar_uchar(ncp,varp,start,nelems,(unsigned char*)value); break; case CASE(NC_UBYTE,NC_BYTE): - return putNCvx_uchar_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_uchar_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_UBYTE,NC_SHORT): return putNCvx_uchar_short(ncp,varp,start,nelems,(short*)value); @@ -1680,7 +1717,7 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_uchar_ushort(ncp,varp,start,nelems,(unsigned short*)value); break; case CASE(NC_USHORT,NC_BYTE): - return putNCvx_ushort_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_ushort_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_USHORT,NC_UBYTE): return putNCvx_ushort_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1710,7 +1747,7 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_ushort_ushort(ncp,varp,start,nelems,(unsigned short*)value); break; case CASE(NC_UINT,NC_BYTE): - return putNCvx_uint_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_uint_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_UINT,NC_UBYTE): return putNCvx_uint_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1740,7 +1777,7 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_uint_ushort(ncp,varp,start,nelems,(unsigned short*)value); break; case CASE(NC_INT64,NC_BYTE): - return putNCvx_longlong_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_longlong_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_INT64,NC_UBYTE): return putNCvx_longlong_uchar(ncp,varp,start,nelems,(unsigned char*)value); @@ -1770,7 +1807,7 @@ writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start, return putNCvx_longlong_ushort(ncp,varp,start,nelems,(unsigned short*)value); break; case CASE(NC_UINT64,NC_BYTE): - return putNCvx_ulonglong_schar(ncp,varp,start,nelems,(signed char*)value); + return putNCvx_ulonglong_schar(ncp,varp,start,nelems,(schar*)value); break; case CASE(NC_UINT64,NC_UBYTE): return putNCvx_ulonglong_uchar(ncp,varp,start,nelems,(unsigned char*)value); diff --git a/libsrc/t_ncio.c b/libsrc/t_ncio.c index 52ded6e9dc..580548961e 100644 --- a/libsrc/t_ncio.c +++ b/libsrc/t_ncio.c @@ -4,13 +4,16 @@ */ /* $Id: t_ncio.c,v 1.10 2010/05/26 11:11:26 ed Exp $ */ -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + #include #include #include #include #include -#include "ncio.h" +#include "ncio.h" #ifndef NC_NOERR #define NC_NOERR 0 #endif @@ -105,7 +108,7 @@ modify_ex(off_t offset, size_t extent, void *vp) while(cp < end) { - *cp++ = (unsigned char) (cp - obuf); + *cp++ = (unsigned char) (cp - obuf); } } @@ -265,7 +268,7 @@ main(int ac, char *av[]) } - + if(!create) { status = ncio_open(path, flags, diff --git a/libsrc/t_ncxx.m4 b/libsrc/t_ncxx.m4 index 0166ccb4dc..81589c18f0 100644 --- a/libsrc/t_ncxx.m4 +++ b/libsrc/t_ncxx.m4 @@ -24,6 +24,10 @@ dnl * Otherwise, the program is silent and has exit code 0. */ +#if HAVE_CONFIG_H +#include +#endif + #undef NDEBUG /* always active assert() in this file */ #include diff --git a/libsrc/v1hpg.c b/libsrc/v1hpg.c index afdeb519a3..5c8906cb9f 100644 --- a/libsrc/v1hpg.c +++ b/libsrc/v1hpg.c @@ -3,7 +3,10 @@ * See netcdf/COPYRIGHT file for copying and redistribution conditions. */ -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + #include "nc3internal.h" #include #include @@ -85,11 +88,7 @@ fault_v1hs(v1hs *gsp, size_t extent) if(gsp->base != NULL) { -#ifdef __arm__ - const ptrdiff_t incr = (signed char *)gsp->pos - (signed char *)gsp->base; -#else - const ptrdiff_t incr = (char *)gsp->pos - (char *)gsp->base; -#endif + const ptrdiff_t incr = (char *)gsp->pos - (char *)gsp->base; status = rel_v1hs(gsp); if(status) return status; @@ -107,11 +106,7 @@ fault_v1hs(v1hs *gsp, size_t extent) gsp->pos = gsp->base; -#ifdef __arm__ - gsp->end = (signed char *)gsp->base + gsp->extent; -#else - gsp->end = (char *)gsp->base + gsp->extent; -#endif + gsp->end = (char *)gsp->base + gsp->extent; return NC_NOERR; } @@ -128,13 +123,8 @@ fprintf(stderr, "nextread %lu, remaining %lu\n", (unsigned long)nextread, (unsigned long)((char *)gsp->end - (char *)gsp->pos)); #endif -#ifdef __arm__ -if((signed char *)gsp->pos + nextread <= (signed char *)gsp->end) - return NC_NOERR; -#else - if((char *)gsp->pos + nextread <= (char *)gsp->end) - return NC_NOERR; -#endif + if((char *)gsp->pos + nextread <= (char *)gsp->end) + return NC_NOERR; return fault_v1hs(gsp, nextread); } @@ -150,10 +140,12 @@ v1h_put_size_t(v1hs *psp, const size_t *sp) status = check_v1hs(psp, X_SIZEOF_INT64); else status = check_v1hs(psp, X_SIZEOF_SIZE_T); - if(status != NC_NOERR) + if(status != NC_NOERR) return status; - if (psp->version == 5) - return ncx_put_int64(&psp->pos, *sp); + if (psp->version == 5) { + unsigned long long tmp = (unsigned long long) (*sp); + return ncx_put_uint64(&psp->pos, tmp); + } else return ncx_put_size_t(&psp->pos, sp); } @@ -167,11 +159,11 @@ v1h_get_size_t(v1hs *gsp, size_t *sp) status = check_v1hs(gsp, X_SIZEOF_INT64); else status = check_v1hs(gsp, X_SIZEOF_SIZE_T); - if(status != NC_NOERR) + if(status != NC_NOERR) return status; if (gsp->version == 5) { - long long tmp=0; - status = ncx_get_int64((const void **)(&gsp->pos), &tmp); + unsigned long long tmp=0; + status = ncx_get_uint64((const void **)(&gsp->pos), &tmp); *sp = (size_t)tmp; return status; } @@ -187,18 +179,10 @@ v1h_get_size_t(v1hs *gsp, size_t *sp) static int v1h_put_nc_type(v1hs *psp, const nc_type *typep) { - const int itype = (int) *typep; - int status = check_v1hs(psp, X_SIZEOF_INT); - if(status != NC_NOERR) - return status; - status = ncx_put_int_int(psp->pos, &itype); - -#ifdef __arm__ - psp->pos = (void *)((signed char *)psp->pos + X_SIZEOF_INT); -#else - psp->pos = (void *)((char *)psp->pos + X_SIZEOF_INT); -#endif - + const unsigned int itype = (unsigned int) *typep; + int status = check_v1hs(psp, X_SIZEOF_INT); + if(status != NC_NOERR) return status; + status = ncx_put_uint32(&psp->pos, itype); return status; } @@ -207,16 +191,10 @@ v1h_put_nc_type(v1hs *psp, const nc_type *typep) static int v1h_get_nc_type(v1hs *gsp, nc_type *typep) { - int type = 0; - int status = check_v1hs(gsp, X_SIZEOF_INT); - if(status != NC_NOERR) - return status; - status = ncx_get_int_int(gsp->pos, &type); -#ifdef __arm__ - gsp->pos = (void *)((signed char *)gsp->pos + X_SIZEOF_INT); -#else - gsp->pos = (void *)((char *)gsp->pos + X_SIZEOF_INT); -#endif + unsigned int type = 0; + int status = check_v1hs(gsp, X_SIZEOF_INT); + if(status != NC_NOERR) return status; + status = ncx_get_uint32((const void**)(&gsp->pos), &type); if(status != NC_NOERR) return status; @@ -248,16 +226,10 @@ v1h_get_nc_type(v1hs *gsp, nc_type *typep) static int v1h_put_NCtype(v1hs *psp, NCtype type) { - const int itype = (int) type; - int status = check_v1hs(psp, X_SIZEOF_INT); - if(status != NC_NOERR) - return status; - status = ncx_put_int_int(psp->pos, &itype); -#ifdef __arm__ - psp->pos = (void *)((signed char *)psp->pos + X_SIZEOF_INT); -#else - psp->pos = (void *)((char *)psp->pos + X_SIZEOF_INT); -#endif + const unsigned int itype = (unsigned int) type; + int status = check_v1hs(psp, X_SIZEOF_INT); + if(status != NC_NOERR) return status; + status = ncx_put_uint32(&psp->pos, itype); return status; } @@ -265,21 +237,13 @@ v1h_put_NCtype(v1hs *psp, NCtype type) static int v1h_get_NCtype(v1hs *gsp, NCtype *typep) { - int type = 0; - int status = check_v1hs(gsp, X_SIZEOF_INT); - if(status != NC_NOERR) - return status; - status = ncx_get_int_int(gsp->pos, &type); - -#ifdef __arm__ - gsp->pos = (void *)((signed char *)gsp->pos + X_SIZEOF_INT); -#else - gsp->pos = (void *)((char *)gsp->pos + X_SIZEOF_INT); -#endif - if(status != NC_NOERR) - return status; - /* else */ - *typep = (NCtype) type; + unsigned int type = 0; + int status = check_v1hs(gsp, X_SIZEOF_INT); + if(status != NC_NOERR) return status; + status = ncx_get_uint32((const void**)(&gsp->pos), &type); + if(status != NC_NOERR) return status; + /* else */ + *typep = (NCtype) type; return NC_NOERR; } @@ -340,11 +304,11 @@ static int v1h_get_NC_string(v1hs *gsp, NC_string **ncstrpp) { int status; - size_t nchars = 0; + size_t padding, nchars = 0; NC_string *ncstrp; status = v1h_get_size_t(gsp, &nchars); - if(status != NC_NOERR) + if(status != NC_NOERR) return status; ncstrp = new_NC_string(nchars, NULL); @@ -353,7 +317,6 @@ v1h_get_NC_string(v1hs *gsp, NC_string **ncstrpp) return NC_ENOMEM; } - #if 0 /* assert(ncstrp->nchars == nchars || ncstrp->nchars - nchars < X_ALIGN); */ assert(ncstrp->nchars % X_ALIGN == 0); @@ -362,22 +325,33 @@ v1h_get_NC_string(v1hs *gsp, NC_string **ncstrpp) status = check_v1hs(gsp, _RNDUP(ncstrp->nchars, X_ALIGN)); #endif - if(status != NC_NOERR) + if(status != NC_NOERR) goto unwind_alloc; status = ncx_pad_getn_text((const void **)(&gsp->pos), nchars, ncstrp->cp); - if(status != NC_NOERR) + if(status != NC_NOERR) goto unwind_alloc; + padding = _RNDUP(X_SIZEOF_CHAR * ncstrp->nchars, X_ALIGN) + - X_SIZEOF_CHAR * ncstrp->nchars; + if (padding > 0) { + /* CDF specification: Header padding uses null (\x00) bytes. */ + char pad[X_ALIGN-1]; + memset(pad, 0, X_ALIGN-1); + if (memcmp((char*)gsp->pos-padding, pad, padding) != 0) { + free_NC_string(ncstrp); + return NC_EINVAL; + } + } + *ncstrpp = ncstrp; - return NC_NOERR; + return NC_NOERR; unwind_alloc: free_NC_string(ncstrp); return status; - } /* End NC_string */ @@ -614,6 +588,28 @@ ncx_len_NC_attr(const NC_attr *attrp, int version) #undef MIN #define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn)) +/*----< ncmpix_len_nctype() >------------------------------------------------*/ +/* return the length of external data type */ +static int +ncmpix_len_nctype(nc_type type) { + switch(type) { + case NC_BYTE: + case NC_CHAR: + case NC_UBYTE: return X_SIZEOF_CHAR; + case NC_SHORT: return X_SIZEOF_SHORT; + case NC_USHORT: return X_SIZEOF_USHORT; + case NC_INT: return X_SIZEOF_INT; + case NC_UINT: return X_SIZEOF_UINT; + case NC_FLOAT: return X_SIZEOF_FLOAT; + case NC_DOUBLE: return X_SIZEOF_DOUBLE; + case NC_INT64: return X_SIZEOF_INT64; + case NC_UINT64: return X_SIZEOF_UINT64; + default: fprintf(stderr,"ncmpix_len_nctype bad type %d\n",type); + assert(0); + } + return 0; +} + /* * Put the values of an attribute * The loop is necessary since attrp->nelems @@ -626,7 +622,7 @@ v1h_put_NC_attrV(v1hs *psp, const NC_attr *attrp) const size_t perchunk = psp->extent; size_t remaining = attrp->xsz; void *value = attrp->xvalue; - size_t nbytes; + size_t nbytes, padding; assert(psp->extent % X_ALIGN == 0); @@ -634,23 +630,24 @@ v1h_put_NC_attrV(v1hs *psp, const NC_attr *attrp) nbytes = MIN(perchunk, remaining); status = check_v1hs(psp, nbytes); - if(status != NC_NOERR) + if(status != NC_NOERR) return status; (void) memcpy(psp->pos, value, nbytes); -#ifdef __arm__ - psp->pos = (void *)((signed char *)psp->pos + nbytes); - value = (void *)((signed char *)value + nbytes); -#else - psp->pos = (void *)((char *)psp->pos + nbytes); + psp->pos = (void *)((char *)psp->pos + nbytes); value = (void *)((char *)value + nbytes); -#endif - remaining -= nbytes; + remaining -= nbytes; } while(remaining != 0); - return NC_NOERR; + padding = attrp->xsz - ncmpix_len_nctype(attrp->type) * attrp->nelems; + if (padding > 0) { + /* CDF specification: Header padding uses null (\x00) bytes. */ + memset((char*)psp->pos-padding, 0, padding); + } + + return NC_NOERR; } /* Write a NC_attr to the header */ @@ -691,29 +688,34 @@ v1h_get_NC_attrV(v1hs *gsp, NC_attr *attrp) const size_t perchunk = gsp->extent; size_t remaining = attrp->xsz; void *value = attrp->xvalue; - size_t nget; + size_t nget, padding; do { nget = MIN(perchunk, remaining); status = check_v1hs(gsp, nget); - if(status != NC_NOERR) + if(status != NC_NOERR) return status; (void) memcpy(value, gsp->pos, nget); -#ifdef __arm__ - gsp->pos = (void *)((signed char *)gsp->pos + nget); + gsp->pos = (void*)((unsigned char *)gsp->pos + nget); + value = (void *)((signed char *)value + nget); -#else - gsp->pos = (void *)((char *)gsp->pos + nget); - value = (void *)((char *)value + nget); -#endif - remaining -= nget; + remaining -= nget; } while(remaining != 0); - return NC_NOERR; + padding = attrp->xsz - ncmpix_len_nctype(attrp->type) * attrp->nelems; + if (padding > 0) { + /* CDF specification: Header padding uses null (\x00) bytes. */ + char pad[X_ALIGN-1]; + memset(pad, 0, X_ALIGN-1); + if (memcmp((char*)gsp->pos-padding, pad, (size_t)padding) != 0) + return NC_EINVAL; + } + + return NC_NOERR; } @@ -939,7 +941,7 @@ v1h_put_NC_var(v1hs *psp, const NC_var *varp) if(status != NC_NOERR) return status; status = ncx_putn_longlong_int(&psp->pos, - varp->ndims, varp->dimids); + varp->ndims, varp->dimids, NULL); if(status != NC_NOERR) return status; } @@ -948,7 +950,7 @@ v1h_put_NC_var(v1hs *psp, const NC_var *varp) if(status != NC_NOERR) return status; status = ncx_putn_int_int(&psp->pos, - varp->ndims, varp->dimids); + varp->ndims, varp->dimids, NULL); if(status != NC_NOERR) return status; } @@ -1345,21 +1347,23 @@ ncx_put_NC(const NC3_INFO* ncp, void **xpp, off_t offset, size_t extent) } if (ps.version == 5) - status = ncx_putn_schar_schar(&ps.pos, sizeof(ncmagic5), ncmagic5); + status = ncx_putn_schar_schar(&ps.pos, sizeof(ncmagic5), ncmagic5, NULL); else if (ps.version == 2) - status = ncx_putn_schar_schar(&ps.pos, sizeof(ncmagic), ncmagic); + status = ncx_putn_schar_schar(&ps.pos, sizeof(ncmagic), ncmagic, NULL); else - status = ncx_putn_schar_schar(&ps.pos, sizeof(ncmagic1), ncmagic1); - if(status != NC_NOERR) + status = ncx_putn_schar_schar(&ps.pos, sizeof(ncmagic1), ncmagic1, NULL); + if(status != NC_NOERR) goto release; { const size_t nrecs = NC_get_numrecs(ncp); - if (ps.version == 5) - status = ncx_put_int64(&ps.pos, nrecs); + if (ps.version == 5) { + unsigned long long tmp = (unsigned long long) nrecs; + status = ncx_put_uint64(&ps.pos, tmp); + } else status = ncx_put_size_t(&ps.pos, &nrecs); - if(status != NC_NOERR) + if(status != NC_NOERR) goto release; } @@ -1486,8 +1490,8 @@ nc_get_NC(NC3_INFO* ncp) { size_t nrecs = 0; if (gs.version == 5) { - long long tmp = 0; - status = ncx_get_int64((const void **)(&gs.pos), &tmp); + unsigned long long tmp = 0; + status = ncx_get_uint64((const void **)(&gs.pos), &tmp); nrecs = (size_t)tmp; } else @@ -1497,11 +1501,8 @@ nc_get_NC(NC3_INFO* ncp) NC_set_numrecs(ncp, nrecs); } -#ifdef __arm__ - assert((signed char *)gs.pos < (signed char *)gs.end); -#else - assert((char *)gs.pos < (char *)gs.end); -#endif + assert((char *)gs.pos < (char *)gs.end); + status = v1h_get_NC_dimarray(&gs, &ncp->dims); if(status != NC_NOERR) goto unwind_get; diff --git a/libsrc/var.c b/libsrc/var.c index c7a965aa6f..b6b0bb2cc3 100644 --- a/libsrc/var.c +++ b/libsrc/var.c @@ -4,7 +4,10 @@ */ /* $Id: var.c,v 1.144 2010/05/30 00:50:35 russ Exp $ */ -#include "config.h" +#if HAVE_CONFIG_H +#include +#endif + #include "nc3internal.h" #include #include diff --git a/libsrc/winceio.c b/libsrc/winceio.c index 5b5523d522..c7a2e14ff5 100644 --- a/libsrc/winceio.c +++ b/libsrc/winceio.c @@ -5,7 +5,11 @@ /* $Id: winceio.c,v 1.2 2010/05/04 17:30:04 dmh Exp $ */ /* Dennis Heimbigner 2010-3-04 */ -#include "config.h" + +#if HAVE_CONFIG_H +#include +#endif + #include #include #include /* DEBUG */ @@ -68,7 +72,7 @@ fgrow(FILE* f, const off_t len) int status = NC_NOERR; long pos = ftell(f); long size; - pos = ftell(f); + pos = ftell(f); status = fseek(f,0,SEEK_END); if(ferror(f)) return EIO; size = ftell(f); @@ -99,7 +103,7 @@ fgrow2(FILE* f, const off_t len) int status = NC_NOERR; long pos = ftell(f); long size; - pos = ftell(f); + pos = ftell(f); status = fseek(f,0,SEEK_END); if(ferror(f)) return EIO; size = ftell(f); @@ -121,7 +125,7 @@ fgrow2(FILE* f, const off_t len) /* Begin ffio */ static int -fileio_pgout(ncio *const nciop, +fileio_pgout(ncio *const nciop, off_t const offset, const size_t extent, const void *const vp, off_t *posp) { @@ -180,7 +184,7 @@ fileio_pgin(ncio *const nciop, typedef struct ncio_ffio { off_t pos; /* buffer */ - off_t bf_offset; + off_t bf_offset; size_t bf_extent; size_t bf_cnt; void *bf_base; @@ -230,7 +234,7 @@ ncio_fileio_get(ncio *const nciop, #ifdef X_ALIGN size_t rem; #endif - + if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE)) return EPERM; /* attempt to write readonly file */ @@ -304,7 +308,7 @@ ncio_fileio_move(ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags) { int status = NC_NOERR; - off_t lower = from; + off_t lower = from; off_t upper = to; char *base; size_t diff = upper - lower; @@ -315,11 +319,11 @@ ncio_fileio_move(ncio *const nciop, off_t to, off_t from, if(to == from) return NC_NOERR; /* NOOP */ - + if(to > from) { /* growing */ - lower = from; + lower = from; upper = to; } else @@ -339,10 +343,10 @@ ncio_fileio_move(ncio *const nciop, off_t to, off_t from, return status; if(to > from) - (void) memmove(base + diff, base, nbytes); + (void) memmove(base + diff, base, nbytes); else - (void) memmove(base, base + diff, nbytes); - + (void) memmove(base, base + diff, nbytes); + (void) ncio_fileio_rel(nciop, lower, RGN_MODIFIED); return status; @@ -426,7 +430,7 @@ ncio_free(ncio *nciop) if(nciop->free != NULL) nciop->free(nciop->pvt); - + free(nciop); } @@ -437,7 +441,7 @@ ncio_new(const char *path, int ioflags) size_t sz_path = M_RNDUP(strlen(path) +1); size_t sz_ncio_pvt; ncio *nciop; - + #if ALWAYS_NC_SHARE /* DEBUG */ fSet(ioflags, NC_SHARE); #endif @@ -450,7 +454,7 @@ ncio_new(const char *path, int ioflags) nciop = (ncio *) malloc(sz_ncio + sz_path + sz_ncio_pvt); if(nciop == NULL) return NULL; - + nciop->ioflags = ioflags; *((int *)&nciop->fd) = -1; /* cast away const */ @@ -511,7 +515,7 @@ ncio_create(const char *path, int ioflags, if(f != NULL) { /* do not overwrite */ (void)fclose(f); return EEXIST; - } + } } f = fopen(path, oflags); @@ -651,8 +655,8 @@ ncio_open(const char *path, } -/* - * Get file size in bytes. +/* + * Get file size in bytes. * Is use of fstatus = fseek() really necessary, or could we use standard fstat() call * and get st_size member? */ @@ -672,7 +676,7 @@ ncio_filesize(ncio *nciop, off_t *filesizep) status = fseek(f, 0, SEEK_END); /* get size */ if(ferror(f)) return EIO; *filesizep = ftell(f); - status = fseek(f, current, SEEK_SET); /* reset */ + status = fseek(f, current, SEEK_SET); /* reset */ if(ferror(f)) return EIO; return NC_NOERR; } @@ -710,7 +714,7 @@ ncio_pad_length(ncio *nciop, off_t length) } -int +int ncio_close(ncio *nciop, int doUnlink) { int status = NC_NOERR; @@ -726,7 +730,7 @@ ncio_close(ncio *nciop, int doUnlink) (void) fclose(f); descriptors[nciop->fd] = NULL; - + if(doUnlink) (void) unlink(nciop->path); diff --git a/libsrc4/nc4attr.c b/libsrc4/nc4attr.c index 5f5188b08a..3648d15697 100644 --- a/libsrc4/nc4attr.c +++ b/libsrc4/nc4attr.c @@ -55,6 +55,18 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name, if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK)))) BAIL(NC_EBADGRPID); + /* Check varid */ + if (varid != NC_GLOBAL) { + if (varid < 0 || varid >= grp->vars.nelems) + return NC_ENOTVAR; + if (grp->vars.value[varid] == NULL) + return NC_ENOTVAR; + assert(grp->vars.value[varid]->varid == varid); + } + + if (name == NULL) + BAIL(NC_EBADNAME); + /* Normalize name. */ if ((retval = nc4_normalize_name(name, norm_name))) BAIL(retval); @@ -242,19 +254,6 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name, if (h5->no_write) return NC_EPERM; - /* Check and normalize the name. */ - if ((retval = nc4_check_name(name, norm_name))) - return retval; - - 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 */ - } - } - } - /* Find att, if it exists. */ if (varid == NC_GLOBAL) attlist = &grp->att; @@ -268,10 +267,34 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name, assert(var->varid == varid); } + if (!name) + return NC_EBADNAME; + + /* Check and normalize the name. */ + if ((retval = nc4_check_name(name, norm_name))) + return retval; + + 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 */ + } + } + } + for (att = *attlist; att; att = att->l.next) if (!strcmp(att->name, norm_name)) break; + /* If len is not zero, then there must be some data. */ + if (len && !data) + return NC_EINVAL; + + LOG((1, "nc4_put_att: ncid 0x%x varid %d name %s " + "file_type %d mem_type %d len %d", ncid, varid, + name, file_type, mem_type, len)); + if (!att) { /* If this is a new att, require define mode. */ @@ -821,12 +844,6 @@ nc4_put_att_tc(int ncid, int varid, const char *name, nc_type file_type, NC *nc; NC_HDF5_FILE_INFO_T *h5; - if (!name || strlen(name) > NC_MAX_NAME) - return NC_EBADNAME; - - LOG((3, "nc4_put_att_tc: ncid 0x%x varid %d name %s file_type %d " - "mem_type %d len %d", ncid, varid, name, file_type, mem_type, len)); - /* The length needs to be positive (cast needed for braindead systems with signed size_t). */ if((unsigned long) len > X_INT_MAX) @@ -840,6 +857,26 @@ nc4_put_att_tc(int ncid, int varid, const char *name, nc_type file_type, h5 = NC4_DATA(nc); assert(h5); + /* Check varid */ + if (varid != NC_GLOBAL) { + /* Find info for this file and group, and set pointer to each. */ + NC_GRP_INFO_T *grp; + if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK)))) + return NC_EBADGRPID; + + if (varid < 0 || varid >= grp->vars.nelems) + return NC_ENOTVAR; + if (grp->vars.value[varid] == NULL) + return NC_ENOTVAR; + assert(grp->vars.value[varid]->varid == varid); + } + + if (!name || strlen(name) > NC_MAX_NAME) + return NC_EBADNAME; + + LOG((3, "nc4_put_att_tc: ncid 0x%x varid %d name %s file_type %d " + "mem_type %d len %d", ncid, varid, name, file_type, mem_type, len)); + if(nc->ext_ncid == ncid && varid == NC_GLOBAL) { const char** reserved = NC_RESERVED_ATT_LIST; for(;*reserved;reserved++) { diff --git a/libsrc4/nc4hdf.c b/libsrc4/nc4hdf.c index 5040bfcd18..53e5f12459 100644 --- a/libsrc4/nc4hdf.c +++ b/libsrc4/nc4hdf.c @@ -632,8 +632,12 @@ nc4_put_vara(NC *nc, int ncid, int varid, const size_t *startp, assert(dim && dim->dimid == var->dimids[d2]); if (!dim->unlimited) { +#ifdef RELAX_COORD_BOUND if (start[d2] > (hssize_t)fdims[d2] || (start[d2] == (hssize_t)fdims[d2] && count[d2] > 0)) +#else + if (start[d2] >= (hssize_t)fdims[d2]) +#endif BAIL_QUIET(NC_EINVALCOORDS); if (start[d2] + count[d2] > fdims[d2]) BAIL_QUIET(NC_EEDGE); @@ -965,8 +969,12 @@ nc4_get_vara(NC *nc, int ncid, int varid, const size_t *startp, BAIL(retval); /* Check for out of bound requests. */ +#ifdef RELAX_COORD_BOUND if (start[d2] > (hssize_t)ulen || (start[d2] == (hssize_t)ulen && count[d2] > 0)) +#else + if (start[d2] >= (hssize_t)ulen && ulen > 0) +#endif BAIL_QUIET(NC_EINVALCOORDS); if (start[d2] + count[d2] > ulen) BAIL_QUIET(NC_EEDGE); @@ -989,8 +997,12 @@ nc4_get_vara(NC *nc, int ncid, int varid, const size_t *startp, else { /* Check for out of bound requests. */ +#ifdef RELAX_COORD_BOUND if (start[d2] > (hssize_t)fdims[d2] || (start[d2] == (hssize_t)fdims[d2] && count[d2] > 0)) +#else + if (start[d2] >= (hssize_t)fdims[d2]) +#endif BAIL_QUIET(NC_EINVALCOORDS); if (start[d2] + count[d2] > fdims[d2]) BAIL_QUIET(NC_EEDGE); diff --git a/libsrcp/ncpdispatch.c b/libsrcp/ncpdispatch.c index a4e8c3ef27..19b2d31a2a 100644 --- a/libsrcp/ncpdispatch.c +++ b/libsrcp/ncpdispatch.c @@ -189,7 +189,7 @@ NCP__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t assert(nc5); /* causes implicitly defined warning; may be because of old installed pnetcdf? */ -#if 0 +#if 1 /* In PnetCDF ncmpi__enddef() is only implemented in v1.5.0 and later */ status = ncmpi__enddef(nc->int_ncid, mpi_h_minfree, mpi_v_align, mpi_v_minfree, mpi_r_align); @@ -441,6 +441,7 @@ NCP_get_att( if(status != NC_NOERR) return status; status = NCP_inq_att(ncid,varid,name,&xtype,NULL); + if(status != NC_NOERR) return status; if(memtype == NC_NAT) memtype = xtype; @@ -487,6 +488,14 @@ NCP_put_att( int status; MPI_Offset mpilen; + /* check if ncid is valid */ + status = NC_check_id(ncid, &nc); + if(status != NC_NOERR) return status; + + /* check if varid is valid */ + status = ncmpi_inq_varnatts(nc->int_ncid, varid, NULL); + if (status != NC_NOERR) return status; + if (!name || (strlen(name) > NC_MAX_NAME)) return NC_EBADNAME; @@ -495,9 +504,6 @@ NCP_put_att( if(((unsigned long) len) > X_INT_MAX) return NC_EINVAL; - status = NC_check_id(ncid, &nc); - if(status != NC_NOERR) return status; - mpilen = len; switch (memtype) { diff --git a/nc_test/CMakeLists.txt b/nc_test/CMakeLists.txt index caf1f6856e..14f59379f4 100644 --- a/nc_test/CMakeLists.txt +++ b/nc_test/CMakeLists.txt @@ -8,7 +8,7 @@ add_definitions(-D"TOPBINDIR=${CMAKE_BINARY_DIR}") INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include) -SET (nc_test_m4_SOURCES test_get test_put) +SET (nc_test_m4_SOURCES test_get test_put test_read test_write) FOREACH (F ${nc_test_m4_SOURCES}) GEN_m4(${F}) ENDFOREACH() @@ -102,5 +102,5 @@ ENDIF() ## Specify files to be distributed by 'make dist' FILE(GLOB CUR_EXTRA_DIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.sh) SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} CMakeLists.txt Makefile.am) -SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} test_get.m4 test_put.m4 ref_tst_diskless2.cdl) +SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} test_get.m4 test_put.m4 test_read.m4 test_write.m4 ref_tst_diskless2.cdl) ADD_EXTRA_DIST("${CUR_EXTRA_DIST}") diff --git a/nc_test/Makefile.am b/nc_test/Makefile.am index d56f619599..5d327dde2e 100644 --- a/nc_test/Makefile.am +++ b/nc_test/Makefile.am @@ -97,7 +97,8 @@ endif # USE_VALGRIND_TESTS # Distribute the .c files so that m4 isn't required on the users # machine. EXTRA_DIST = test_get.m4 test_put.m4 run_valgrind_tests.sh \ -run_diskless.sh run_diskless2.sh run_mmap.sh run_pnetcdf_test.sh +run_diskless.sh run_diskless2.sh run_mmap.sh run_pnetcdf_test.sh \ +test_read.m4 test_write.m4 # ref_tst_diskless2.cdl is for diff comparison and to produce tst_diskless2.c EXTRA_DIST += ref_tst_diskless2.cdl CMakeLists.txt diff --git a/nc_test/error.c b/nc_test/error.c index e9668de7d0..2d502ca0e5 100644 --- a/nc_test/error.c +++ b/nc_test/error.c @@ -59,7 +59,7 @@ ifFail(const int expr, const int line, const char *file) * "architecture" of this program. */ void -print_n_size_t(size_t nelems, const size_t *array) +print_n_size_t(int nelems, const size_t *array) { fprintf(stderr, "["); while(nelems-- > 0) diff --git a/nc_test/error.h b/nc_test/error.h index 7ed8fdfcd0..f8ccf3b062 100644 --- a/nc_test/error.h +++ b/nc_test/error.h @@ -24,10 +24,11 @@ __attribute__ ((format (printf, 1, 2))) extern int ifFail(const int expr, const int line, const char *file); extern void -print_n_size_t(size_t nelems, const size_t *array); +print_n_size_t(int nelems, const size_t *array); #ifdef __cplusplus } #endif #define IF(EXPR) if (ifFail(EXPR, __LINE__, __FILE__)) +#define ELSE_NOK else {nok++;} diff --git a/nc_test/nc_test.c b/nc_test/nc_test.c index 5e779e3bbd..f4c27e4ac1 100644 --- a/nc_test/nc_test.c +++ b/nc_test/nc_test.c @@ -35,11 +35,11 @@ char dim_name[NDIMS][3]; size_t dim_len[NDIMS]; char var_name[NVARS][2+MAX_RANK]; nc_type var_type[NVARS]; -size_t var_rank[NVARS]; +int var_rank[NVARS]; int var_dimid[NVARS][MAX_RANK]; size_t var_shape[NVARS][MAX_RANK]; size_t var_nels[NVARS]; -size_t var_natts[NVARS]; +int var_natts[NVARS]; char att_name[NVARS][MAX_NATTS][2]; char gatt_name[NGATTS][3]; nc_type att_type[NVARS][NGATTS]; @@ -156,7 +156,7 @@ main(int argc, char *argv[]) /* Initialize global variables defining test file */ init_gvars(); - /* Write the test file, needed for the read-only tests below. */ + /* Write the test file, needed for the read-only tests below. */ write_file(testfile); /* delete any existing scratch netCDF file */ @@ -355,6 +355,8 @@ main(int argc, char *argv[]) NC_TEST(nc_copy_att); NC_TEST(nc_rename_att); NC_TEST(nc_del_att); + NC_TEST(nc_against_pnetcdf); + /* keep below the last test, as it changes the default file format */ NC_TEST(nc_set_default_format); } diff --git a/nc_test/test_get.m4 b/nc_test/test_get.m4 index 5b792be125..1e81e56677 100644 --- a/nc_test/test_get.m4 +++ b/nc_test/test_get.m4 @@ -1,18 +1,71 @@ dnl This is m4 source. dnl Process using m4 to produce 'C' language file. dnl +dnl This file is supposed to be the same as PnetCDF's test_get.m4 +dnl dnl If you see this line, you can ignore the next one. /* Do not edit this file. It is produced from the corresponding .m4 source */ dnl -/********************************************************************* - * Copyright 1996, UCAR/Unidata - * See netcdf/COPYRIGHT file for copying and redistribution conditions. - * $Id: test_get.m4 2785 2014-10-26 05:21:20Z wkliao $ - *********************************************************************/ - -#ifdef USE_PARALLEL -#include +/* + * Copyright (C) 2003, Northwestern University and Argonne National Laboratory + * See COPYRIGHT notice in top-level directory. + */ +/* $Id: test_get.m4 2672 2016-12-03 19:23:53Z wkliao $ */ + +dnl +dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF +dnl in terms of function prefix names (ncmpi_ vs. nc_), integer data types +dnl (MPI_Offset vs. size_t), and function name substrings for external data +dnl types. +dnl + +#include "tests.h" + +ifdef(`PNETCDF',,`dnl +#ifdef USE_PNETCDF +#include +#ifndef PNETCDF_VERSION_MAJOR +#error("PNETCDF_VERSION_MAJOR is not defined in pnetcdf.h") +#endif +#ifndef PNETCDF_VERSION_MINOR +#error("PNETCDF_VERSION_MAJOR is not defined in pnetcdf.h") #endif +#endif') + +define(`EXPECT_ERR',`error("expecting $1 but got %s",nc_err_code_name($2));')dnl + +define(`IntType', `ifdef(`PNETCDF',`MPI_Offset',`size_t')')dnl +define(`PTRDType',`ifdef(`PNETCDF',`MPI_Offset',`ptrdiff_t')')dnl +define(`TestFunc',`ifdef(`PNETCDF',`test_ncmpi_get_$1',`test_nc_get_$1')')dnl +define(`APIFunc',` ifdef(`PNETCDF',`ncmpi_$1',`nc_$1')')dnl + +define(`FileOpen', `ifdef(`PNETCDF',`ncmpi_open(comm, $1, $2, info, &ncid)', `file_open($1, $2, &ncid)')')dnl + +define(`VarArgs', `ifdef(`PNETCDF',`int numVars',`void')')dnl +define(`AttVarArgs',`ifdef(`PNETCDF',`int numGatts,int numVars',`void')')dnl + +define(`GetVar1',`ifdef(`PNETCDF',`ncmpi_get_var1_$1_all',`nc_get_var1_$1')')dnl +define(`GetVar', `ifdef(`PNETCDF',`ncmpi_get_var_$1_all', `nc_get_var_$1')')dnl +define(`GetVara',`ifdef(`PNETCDF',`ncmpi_get_vara_$1_all',`nc_get_vara_$1')')dnl +define(`GetVars',`ifdef(`PNETCDF',`ncmpi_get_vars_$1_all',`nc_get_vars_$1')')dnl +define(`GetVarm',`ifdef(`PNETCDF',`ncmpi_get_varm_$1_all',`nc_get_varm_$1')')dnl +define(`GetAtt', `ifdef(`PNETCDF',`ncmpi_get_att_$1',`nc_get_att_$1')')dnl + +define(`PNETCDF_CHECK_ERANGE',`dnl +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,` +`#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>=8)')', + `$1',`schar',`ifdef(`PNETCDF',,` +`#'if defined(USE_PNETCDF) && PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR<7 + else if (cdf_format < NC_FORMAT_CDF5) { +`#'else')') + else { +ifelse(`$1',`schar',`ifdef(`PNETCDF',,``#'endif')') + IF (err != NC_ERANGE) + EXPECT_ERR(NC_ERANGE, err) + ELSE_NOK + } +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')')' +)dnl undefine(`index')dnl dnl dnl dnl @@ -33,94 +86,146 @@ dnl define(`NCT_ITYPE', ``NCT_'Upcase($1)')dnl dnl -#include "tests.h" +define(`CheckText', `ifelse(`$1',`text', , `== (NCT_ITYPE($1) == NCT_TEXT)')')dnl +define(`CheckRange',`ifelse(`$1',`text', `1', `($2 >= $1_min && $2 <= $1_max)')')dnl +define(`IfCheckTextChar', `ifelse(`$1',`text', `if ($2 != NC_CHAR)')')dnl +define(`CheckNumRange',`ifelse(`$1',`text', `1',`inRange3(cdf_format, $2,$3,NCT_ITYPE($1)) && ($2 >= $1_min && $2 <= $1_max)')')dnl dnl TEST_NC_GET_VAR1(TYPE) dnl define(`TEST_NC_GET_VAR1',dnl `dnl -void -test_nc_get_var1_$1(void) +int +TestFunc(var1)_$1(VarArgs) { - int ncid; - int i; - int j; - int err; - int nok = 0; /* count of valid comparisons */ - size_t index[MAX_RANK]; - double expect; + int i, err, ncid, cdf_format; + int nok = 0; /* count of valid comparisons */ int canConvert; /* Both text or both numeric */ - $1 value; + IntType j, index[MAX_RANK]; + double expect; + $1 value[1]; + + err = FileOpen(testfile, NC_NOWRITE); + IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) error("inq_format: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = GetVar1($1)(BAD_ID, 0, NULL, NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = GetVar1($1)(ncid, BAD_VARID, NULL, NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); - for (j = 0; j < var_rank[i]; j++) - index[j] = 0; - err = nc_get_var1_$1(BAD_ID, i, index, &value); + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + /* check if can detect a bad file ID */ + err = GetVar1($1)(BAD_ID, i, NULL, value); IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_var1_$1(ncid, BAD_VARID, index, &value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - index[j] = var_shape[i][j]; - err = nc_get_var1_$1(ncid, i, index, &value); - if(!canConvert) { - IF(err != NC_ECHAR) - error("conversion: status = %d", err); - } else IF (err != NC_EINVALCOORDS) - error("bad index: status = %d", err); - index[j] = 0; - } - for (j = 0; j < var_nels[i]; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase 1"); - expect = hash4( var_type[i], var_rank[i], index, NCT_ITYPE($1) ); - if (var_rank[i] == 0 && i%2 ) - err = nc_get_var1_$1(ncid, i, NULL, &value); - else - err = nc_get_var1_$1(ncid, i, index, &value); + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = GetVar1($1)(ncid, i, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err) + } + else if (var_rank[i] == 0) { + index[0] = 0; + expect = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect, var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect)) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>7)')') + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')') + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK +')dnl + + /* test NC_EINVALCOORDS */ + for (j = 0; j < var_rank[i]; j++) index[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + index[j] = var_shape[i][j]; /* out of boundary check */ + err = GetVar1($1)(ncid, i, index, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } else IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + index[j] = 0; + } + + /* check if the contents are supposed to be */ + for (j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + /* when file is created the variable contents are generated by + * hash functions */ + expect = hash4(cdf_format, var_type[i], var_rank[i], index, + NCT_ITYPE($1)); + err = GetVar1($1)(ncid, i, index, value); if (canConvert) { - if (inRange3(expect,var_type[i], NCT_ITYPE($1))) { - if (expect >= $1_min && expect <= $1_max) { - IF (err) { - error("%s", nc_strerror(err)); - } else { - IF (!equal(value,expect,var_type[i],NCT_ITYPE($1))) { - error("expected: %G, got: %G", expect, - (double) value); - } else { - nok++; - } - } - } else { - IF (err != NC_ERANGE) - error("Range error: status = %d", err); - } + if (inRange3(cdf_format, expect,var_type[i], NCT_ITYPE($1))) { + if (CheckRange($1, expect)) { + IF (err != NC_NOERR) { + EXPECT_ERR(NC_NOERR, err) + } else { + ifelse(`$1', `uchar', ` + /* in put_vars(), API _put_vara_double() is used to + * write the NC_BYTE variables to files. In this + * case, NC_BYTE variables are treated as signed + * for CDF-1 and 2 formats. Thus, we must skip the + * equal test below for uchar. + */ + if (cdf_format < NC_FORMAT_CDF5 && var_type[i] == NC_BYTE && expect > schar_max) continue;') + IF (!equal((double)value[0], expect, var_type[i], NCT_ITYPE($1))) { + error("expected: %G, got: %G", expect, (double)value[0]); + } + ELSE_NOK + } + } + PNETCDF_CHECK_ERANGE($1) } else { - IF (err != 0 && err != NC_ERANGE) - error("OK or Range error: status = %d", err); - } - } else { - IF (err != NC_ECHAR) - error("wrong type: status = %d", err); - } - } + IF (err != NC_NOERR && err != NC_ERANGE) + EXPECT_ERR(NC_NOERR or NC_ERANGE, err) + } + } else { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } + } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; } ')dnl TEST_NC_GET_VAR1(text) -TEST_NC_GET_VAR1(uchar) TEST_NC_GET_VAR1(schar) +TEST_NC_GET_VAR1(uchar) TEST_NC_GET_VAR1(short) TEST_NC_GET_VAR1(int) TEST_NC_GET_VAR1(long) @@ -136,94 +241,107 @@ dnl TEST_NC_GET_VAR(TYPE) dnl define(`TEST_NC_GET_VAR',dnl `dnl -void -test_nc_get_var_$1(void) +int +TestFunc(var)_$1(VarArgs) { - int ncid; - int i; - int j; - int err; - int allInExtRange; /* all values within external range? */ - int allInIntRange; /* all values within internal range? */ - int nels; - int nok = 0; /* count of valid comparisons */ - size_t index[MAX_RANK]; + int i, err, ncid, cdf_format; + int allInExtRange; /* all values within range of external data type */ + int allInIntRange; /* all values within range of internal data type */ + int nok = 0; /* count of valid comparisons */ int canConvert; /* Both text or both numeric */ - $1 value[MAX_NELS]; + IntType j, index[MAX_RANK]; double expect[MAX_NELS]; + $1 value[MAX_NELS]; + + err = FileOpen(testfile, NC_NOWRITE); + IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) error("inq_format: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = GetVar($1)(BAD_ID, 0, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = GetVar($1)(ncid, BAD_VARID, value); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); assert(var_rank[i] <= MAX_RANK); assert(var_nels[i] <= MAX_NELS); - err = nc_get_var_$1(BAD_ID, i, value); + + /* check if can detect a bad file ID */ + err = GetVar($1)(BAD_ID, i, value); IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_var_$1(ncid, BAD_VARID, value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - - nels = 1; - for (j = 0; j < var_rank[i]; j++) { - nels *= var_shape[i][j]; - } - allInExtRange = allInIntRange = 1; - for (j = 0; j < nels; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase 1"); - expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ITYPE($1)); - if (inRange3(expect[j],var_type[i], NCT_ITYPE($1))) { - allInIntRange = allInIntRange && expect[j] >= $1_min - && expect[j] <= $1_max; - } else { - allInExtRange = 0; - } - } - err = nc_get_var_$1(ncid, i, value); - if (canConvert) { - if (allInExtRange) { - if (allInIntRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) - error("Range error: status = %d", err); - } - } else { - IF (err != 0 && err != NC_ERANGE) - error("OK or Range error: status = %d", err); - } - for (j = 0; j < nels; j++) { - if (inRange3(expect[j],var_type[i],NCT_ITYPE($1)) - && expect[j] >= $1_min && expect[j] <= $1_max) { - IF (!equal(value[j],expect[j],var_type[i],NCT_ITYPE($1))){ - error("value read not that expected"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("var_name: %s, ", var_name[i]); - error("element number: %d ", j); - error("expect: %g", expect[j]); - error("got: %g", (double) value[j]); - } - } else { - nok++; - } - } - } - } else { - IF (nels > 0 && err != NC_ECHAR) - error("wrong type: status = %d", err); - } + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + + allInExtRange = allInIntRange = 1; + for (j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + expect[j] = hash4(cdf_format, var_type[i], var_rank[i], index, + NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[j],var_type[i], NCT_ITYPE($1))) { + IfCheckTextChar($1, var_type[i]) + allInIntRange &= CheckRange($1,expect[j]); + } else + allInExtRange = 0; + } + err = GetVar($1)(ncid, i, value); + if (canConvert) { + if (allInExtRange) { + if (allInIntRange) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + } + PNETCDF_CHECK_ERANGE($1) + } else { + IF (err != NC_NOERR && err != NC_ERANGE) + EXPECT_ERR(NC_NOERR or NC_ERANGE, err) + } + for (j = 0; j < var_nels[i]; j++) { + if (CheckNumRange($1, expect[j], var_type[i])) { + ifelse(`$1', `uchar', ` + /* in put_vars(), API _put_vara_double() is used to + * write the NC_BYTE variables to files. In this + * case, NC_BYTE variables are treated as signed + * for CDF-1 and 2 formats. Thus, we must skip the + * equal test below for uchar. + */ + if (cdf_format < NC_FORMAT_CDF5 && var_type[i] == NC_BYTE && expect[j] > schar_max) continue;') + IF (!equal((double)value[j],expect[j],var_type[i],NCT_ITYPE($1))){ + error("value read not that expected"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("var_name: %s, ", var_name[i]); + error("var_type: %s, ", s_nc_type(var_type[i])); + error("element number: %d, ", j); + error("expect: %g, ", expect[j]); + error("got: %g", (double) value[j]); + } + } + ELSE_NOK + } + } + } else { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; } ')dnl @@ -245,160 +363,245 @@ dnl TEST_NC_GET_VARA(TYPE) dnl define(`TEST_NC_GET_VARA',dnl `dnl -void -test_nc_get_vara_$1(void) +int +TestFunc(vara)_$1(VarArgs) { - int ncid; - int d; - int i; - int j; - int k; - int err; - int allInExtRange; /* all values within external range? */ - int allInIntRange; /* all values within internal range? */ - int nels; - int nslabs; - int nok = 0; /* count of valid comparisons */ - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t mid[MAX_RANK]; + int i, k, err, nslabs, ncid, cdf_format; + int allInExtRange; /* all values within external range? */ + int allInIntRange; /* all values within internal range? */ + int nok = 0; /* count of valid comparisons */ int canConvert; /* Both text or both numeric */ - $1 value[MAX_NELS]; + IntType j; + IntType start[MAX_RANK], edge[MAX_RANK], index[MAX_RANK], mid[MAX_RANK]; double expect[MAX_NELS]; + $1 value[MAX_NELS]; + + err = FileOpen(testfile, NC_NOWRITE); + IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) error("inq_format: %s", APIFunc(strerror)(err)); + + err = GetVara($1)(BAD_ID, 0, NULL, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + err = GetVara($1)(ncid, BAD_VARID, NULL, NULL, value); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); assert(var_rank[i] <= MAX_RANK); assert(var_nels[i] <= MAX_NELS); - for (j = 0; j < var_rank[i]; j++) { - start[j] = 0; - edge[j] = 1; - } - err = nc_get_vara_$1(BAD_ID, i, start, edge, value); + + /* check if can detect a bad file ID */ + err = GetVara($1)(BAD_ID, i, NULL, NULL, value); IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_vara_$1(ncid, BAD_VARID, start, edge, value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - start[j] = var_shape[i][j]; - err = nc_get_vara_$1(ncid, i, start, edge, value); - IF (canConvert && err != NC_EINVALCOORDS) - error("bad index: status = %d", err); - start[j] = 0; - edge[j] = var_shape[i][j] + 1; - err = nc_get_vara_$1(ncid, i, start, edge, value); - IF (canConvert && err != NC_EEDGE) - error("bad edge: status = %d", err); - edge[j] = 1; - } - /* Check non-scalars for correct error returned even when */ - /* there is nothing to get (edge[j]==0) */ - if(var_rank[i] > 0) { - for (j = 0; j < var_rank[i]; j++) { - edge[j] = 0; - } - err = nc_get_vara_$1(BAD_ID, i, start, edge, value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_vara_$1(ncid, BAD_VARID, start, edge, value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - err = nc_get_vara_$1(ncid, i, start, edge, value); - if (canConvert) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ECHAR) - error("wrong type: status = %d", err); - } - for (j = 0; j < var_rank[i]; j++) { - edge[j] = 1; - } - } /* Choose a random point dividing each dim into 2 parts */ - /* get 2^rank (nslabs) slabs so defined */ + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + + for (j = 0; j < var_rank[i]; j++) { + start[j] = 0; + edge[j] = 1; + } + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = GetVara($1)(ncid, i, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } + else if (var_rank[i] == 0) { + index[0] = 0; + expect[0] = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[0], var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect[0])) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>7)')') + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')') + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + + /* for non-scalar variables, argument count cannot be NULL */ + err = GetVara($1)(ncid, i, start, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } + else if (var_rank[i] == 0) { + index[0] = 0; + expect[0] = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[0], var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect[0])) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) + } + else IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDGE, err) + ELSE_NOK +')dnl + + /* first test when edge[*] > 0 */ + for (j = 0; j < var_rank[i]; j++) { + start[j] = var_shape[i][j]; /* causes NC_EINVALCOORDS */ + err = GetVara($1)(ncid, i, start, edge, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + start[j] = 0; + continue; + } + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + start[j] = 0; + edge[j] = var_shape[i][j] + 1; /* causes NC_EEDGE */ + err = GetVara($1)(ncid, i, start, edge, value); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDGE, err) + edge[j] = 1; + } + /* Check non-scalars for correct error returned even when there is + * nothing to get (edge[*]==0) */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_rank[i] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = GetVara($1)(ncid, i, start, edge, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + start[j] = 0; + continue; + } +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + start[j] = var_shape[i][j]+1; /* should cause NC_EINVALCOORDS */ + err = GetVara($1)(ncid, i, start, edge, value); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + start[j] = 0; + } + + err = GetVara($1)(ncid, i, start, edge, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + } else if (var_rank[i] == 0) { + expect[0] = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[0], var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect[0])) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>7)')') + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')') + } else { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + /* Choose a random point dividing each dim into 2 parts */ + /* get 2^rank (nslabs) slabs so defined */ nslabs = 1; for (j = 0; j < var_rank[i]; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } - /* bits of k determine whether to get lower or upper part of dim */ + /* bits of k determine whether to get lower or upper part of dim */ for (k = 0; k < nslabs; k++) { - nels = 1; + IntType nels = 1; for (j = 0; j < var_rank[i]; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; - }else{ + } else { start[j] = mid[j]; edge[j] = var_shape[i][j] - mid[j]; } nels *= edge[j]; } - allInExtRange = allInIntRange = 1; + allInExtRange = allInIntRange = 1; for (j = 0; j < nels; j++) { + int d; err = toMixedBase(j, var_rank[i], edge, index); - IF (err) - error("error in toMixedBase 1"); + IF (err != 0) error("error in toMixedBase"); for (d = 0; d < var_rank[i]; d++) index[d] += start[d]; - expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ITYPE($1)); - if (inRange3(expect[j],var_type[i], NCT_ITYPE($1))) { - allInIntRange = allInIntRange && expect[j] >= $1_min - && expect[j] <= $1_max; - } else { - allInExtRange = 0; - } - } - if (var_rank[i] == 0 && i%2) - err = nc_get_vara_$1(ncid, i, NULL, NULL, value); - else - err = nc_get_vara_$1(ncid, i, start, edge, value); + expect[j] = hash4(cdf_format, var_type[i], var_rank[i], index, + NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[j],var_type[i],NCT_ITYPE($1))) { + IfCheckTextChar($1, var_type[i]) + allInIntRange &= CheckRange($1,expect[j]); + } else + allInExtRange = 0; + } + err = GetVara($1)(ncid, i, start, edge, value); if (canConvert) { - if (allInExtRange) { - if (allInIntRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) - error("Range error: status = %d", err); - } - } else { - IF (err != 0 && err != NC_ERANGE) - error("OK or Range error: status = %d", err); - } - for (j = 0; j < nels; j++) { - if (inRange3(expect[j],var_type[i],NCT_ITYPE($1)) - && expect[j] >= $1_min && expect[j] <= $1_max) { - IF (!equal(value[j],expect[j],var_type[i],NCT_ITYPE($1))){ - error("value read not that expected"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("var_name: %s, ", var_name[i]); - error("element number: %d ", j); - error("expect: %g", expect[j]); - error("got: %g", (double) value[j]); - } - } else { - nok++; - } - } - } + if (allInExtRange) { + if (allInIntRange) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + } + PNETCDF_CHECK_ERANGE($1) + } else { + IF (err != NC_NOERR && err != NC_ERANGE) + EXPECT_ERR(NC_NOERR or NC_ERANGE, err) + } + for (j = 0; j < nels; j++) { + if (CheckNumRange($1, expect[j], var_type[i])) { + ifelse(`$1', `uchar', ` + /* in put_vars(), API _put_vara_double() is used to + * write the NC_BYTE variables to files. In this + * case, NC_BYTE variables are treated as signed + * for CDF-1 and 2 formats. Thus, we must skip the + * equal test below for uchar. + */ + if (cdf_format < NC_FORMAT_CDF5 && var_type[i] == NC_BYTE && expect[j] > schar_max) continue;') + IF (!equal((double)value[j],expect[j],var_type[i],NCT_ITYPE($1))){ + error("value read not that expected"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("var_name: %s, ", var_name[i]); + error("var_type: %s, ", s_nc_type(var_type[i])); + error("element number: %d, ", j); + error("expect: %g, ", expect[j]); + error("got: %g", (double) value[j]); + } + } + ELSE_NOK + } + } } else { - IF (nels > 0 && err != NC_ECHAR) - error("wrong type: status = %d", err); + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) } } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; } ')dnl @@ -420,178 +623,283 @@ dnl TEST_NC_GET_VARS(TYPE) dnl define(`TEST_NC_GET_VARS',dnl `dnl -void -test_nc_get_vars_$1(void) +int +TestFunc(vars)_$1(VarArgs) { - int ncid; - int d; - int i; - int j; - int k; - int m; - int err; - int allInExtRange; /* all values within external range? */ - int allInIntRange; /* all values within internal range? */ - int nels; - int nslabs; - int nstarts; /* number of different starts */ - int nok = 0; /* count of valid comparisons */ - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t index2[MAX_RANK]; - size_t mid[MAX_RANK]; - size_t count[MAX_RANK]; - size_t sstride[MAX_RANK]; - ptrdiff_t stride[MAX_RANK]; + int i, k, d, err, nslabs, ncid, cdf_format; + int allInExtRange; /* all values within external range? */ + int allInIntRange; /* all values within internal range? */ + PTRDType nstarts; /* number of different starts */ + int nok = 0; /* count of valid comparisons */ int canConvert; /* Both text or both numeric */ - $1 value[MAX_NELS]; + IntType j, m, nels; + IntType start[MAX_RANK], edge[MAX_RANK], index[MAX_RANK]; + IntType index2[MAX_RANK], mid[MAX_RANK], count[MAX_RANK]; + IntType sstride[MAX_RANK]; + PTRDType stride[MAX_RANK]; double expect[MAX_NELS]; + $1 value[MAX_NELS]; + + err = FileOpen(testfile, NC_NOWRITE); + IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) error("inq_format: %s", APIFunc(strerror)(err)); + + err = GetVars($1)(BAD_ID, 0, NULL, NULL, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + err = GetVars($1)(ncid, BAD_VARID, NULL, NULL, NULL, value); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); assert(var_rank[i] <= MAX_RANK); assert(var_nels[i] <= MAX_NELS); + + /* check if can detect a bad file ID */ + err = GetVars($1)(BAD_ID, i, NULL, NULL, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + for (j = 0; j < var_rank[i]; j++) { start[j] = 0; edge[j] = 1; stride[j] = 1; } - err = nc_get_vars_$1(BAD_ID, i, start, edge, stride, value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_vars_$1(ncid, BAD_VARID, start, edge, stride, value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = GetVars($1)(ncid, i, NULL, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } + else if (var_rank[i] == 0) { + index[0] = 0; + expect[0] = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[0], var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect[0])) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + + /* for non-scalar variables, argument count cannot be NULL */ + err = GetVars($1)(ncid, i, start, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } + else if (var_rank[i] == 0) { + index[0] = 0; + expect[0] = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[0], var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect[0])) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) + } + else IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDGE, err) + ELSE_NOK +')dnl + + /* first test when edge[*] > 0 */ for (j = 0; j < var_rank[i]; j++) { start[j] = var_shape[i][j]; - err = nc_get_vars_$1(ncid, i, start, edge, stride, value); - if(!canConvert) { - IF (err != NC_ECHAR) - error("conversion: status = %d", err); - } else { + err = GetVars($1)(ncid, i, start, edge, stride, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + start[j] = 0; + continue; + } IF (err != NC_EINVALCOORDS) - error("bad index: status = %d", err); + EXPECT_ERR(NC_EINVALCOORDS, err) start[j] = 0; edge[j] = var_shape[i][j] + 1; - err = nc_get_vars_$1(ncid, i, start, edge, stride, value); + err = GetVars($1)(ncid, i, start, edge, stride, value); IF (err != NC_EEDGE) - error("bad edge: status = %d", err); + EXPECT_ERR(NC_EEDGE, err) edge[j] = 1; stride[j] = 0; - err = nc_get_vars_$1(ncid, i, start, edge, stride, value); + err = GetVars($1)(ncid, i, start, edge, stride, value); + IF (err != NC_ESTRIDE) + EXPECT_ERR(NC_ESTRIDE, err) + stride[j] = 1; + } + + /* Check non-scalars for correct error returned even when there is + * nothing to get (edge[j]==0) */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = GetVars($1)(ncid, i, start, edge, stride, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + start[j] = 0; + continue; + } +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + start[j] = var_shape[i][j]+1; /* should cause NC_EINVALCOORDS */ + err = GetVars($1)(ncid, i, start, edge, stride, value); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + start[j] = 0; +ifdef(`PNETCDF',,``#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>=7)') + stride[j] = 0; + err = GetVars($1)(ncid, i, start, edge, stride, value); IF (err != NC_ESTRIDE) - error("bad stride: status = %d", err); + EXPECT_ERR(NC_ESTRIDE, err) stride[j] = 1; - } +ifdef(`PNETCDF',,``#'endif') } - /* Choose a random point dividing each dim into 2 parts */ - /* get 2^rank (nslabs) slabs so defined */ + + err = GetVars($1)(ncid, i, start, edge, stride, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + } else if (var_rank[i] == 0) { + expect[0] = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[0], var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect[0])) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>7)')') + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')') + } else { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + /* Choose a random point dividing each dim into 2 parts */ + /* get 2^rank (nslabs) slabs so defined */ nslabs = 1; for (j = 0; j < var_rank[i]; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } - /* bits of k determine whether to get lower or upper part of dim */ - /* choose random stride from 1 to edge */ + /* bits of k determine whether to get lower or upper part of dim */ + /* choose random stride from 1 to edge */ for (k = 0; k < nslabs; k++) { nstarts = 1; for (j = 0; j < var_rank[i]; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; - }else{ + } else { start[j] = mid[j]; edge[j] = var_shape[i][j] - mid[j]; } - sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + stride[j] = (PTRDType)sstride[j]; nstarts *= stride[j]; } for (m = 0; m < nstarts; m++) { err = toMixedBase(m, var_rank[i], sstride, index); - IF (err) - error("error in toMixedBase"); + IF (err != 0) error("error in toMixedBase"); nels = 1; for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / stride[j]; + count[j] = 1 + (edge[j]-index[j]-1) / (IntType)stride[j]; nels *= count[j]; index[j] += start[j]; } - /* Random choice of forward or backward */ + /* Random choice of forward or backward */ /* TODO if ( roll(2) ) { for (j = 0; j < var_rank[i]; j++) { - index[j] += (count[j] - 1) * stride[j]; + index[j] += (count[j] - 1) * (IntType)stride[j]; stride[j] = -stride[j]; } } */ - allInExtRange = allInIntRange = 1; - for (j = 0; j < nels; j++) { - err = toMixedBase(j, var_rank[i], count, index2); - IF (err) - error("error in toMixedBase 1"); - for (d = 0; d < var_rank[i]; d++) - index2[d] = index[d] + index2[d] * stride[d]; - expect[j] = hash4(var_type[i], var_rank[i], index2, - NCT_ITYPE($1)); - if (inRange3(expect[j],var_type[i],NCT_ITYPE($1))) { - allInIntRange = allInIntRange && expect[j] >= $1_min - && expect[j] <= $1_max; - } else { - allInExtRange = 0; - } - } - if (var_rank[i] == 0 && i%2 ) - err = nc_get_vars_$1(ncid, i, NULL, NULL, NULL, value); - else - err = nc_get_vars_$1(ncid, i, index, count, stride, value); - if (canConvert) { - if (allInExtRange) { - if (allInIntRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) - error("Range error: status = %d", err); - } - } else { - IF (err != 0 && err != NC_ERANGE) - error("OK or Range error: status = %d", err); - } - for (j = 0; j < nels; j++) { - if (inRange3(expect[j],var_type[i],NCT_ITYPE($1)) - && expect[j] >= $1_min && expect[j] <= $1_max) { - IF (!equal(value[j],expect[j],var_type[i], NCT_ITYPE($1))){ - error("value read not that expected"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("var_name: %s, ", var_name[i]); - error("element number: %d ", j); + allInExtRange = allInIntRange = 1; + for (j = 0; j < nels; j++) { + err = toMixedBase(j, var_rank[i], count, index2); + IF (err != 0) error("error in toMixedBase"); + for (d = 0; d < var_rank[i]; d++) + index2[d] = index[d] + index2[d] * (IntType)stride[d]; + expect[j] = hash4(cdf_format, var_type[i], var_rank[i], + index2, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[j],var_type[i],NCT_ITYPE($1))) { + IfCheckTextChar($1, var_type[i]) + allInIntRange &= CheckRange($1,expect[j]); + } else + allInExtRange = 0; + } + err = GetVars($1)(ncid, i, index, count, stride, value); + if (canConvert) { + if (allInExtRange) { + if (allInIntRange) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + } + PNETCDF_CHECK_ERANGE($1) + } else { + IF (err != NC_NOERR && err != NC_ERANGE) + EXPECT_ERR(NC_NOERR or NC_ERANGE, err) + } + for (j = 0; j < nels; j++) { + if (CheckNumRange($1, expect[j], var_type[i])) { + ifelse(`$1', `uchar', ` + /* in put_vars(), API _put_vara_double() is used to + * write the NC_BYTE variables to files. In this + * case, NC_BYTE variables are treated as signed + * for CDF-1 and 2 formats. Thus, we must skip the + * equal test below for uchar. + */ + if (cdf_format < NC_FORMAT_CDF5 && var_type[i] == NC_BYTE && expect[j] > schar_max) continue;') + IF (!equal((double)value[j],expect[j],var_type[i], NCT_ITYPE($1))){ + error("value read not that expected"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("var_name: %s, ", var_name[i]); + error("var_type: %s, ", s_nc_type(var_type[i])); + error("element number: %d, ", j); error("expect: %g, ", expect[j]); - error("got: %g", (double) value[j]); - } - } else { - nok++; - } - } - } - } else { - IF (nels > 0 && err != NC_ECHAR) - error("wrong type: status = %d", err); - } - } - } + error("got: %g", (double) value[j]); + } + } + ELSE_NOK + } + } + } else { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + } + } + } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; } ')dnl @@ -613,186 +921,288 @@ dnl TEST_NC_GET_VARM(TYPE) dnl define(`TEST_NC_GET_VARM',dnl `dnl -void -test_nc_get_varm_$1(void) +int +TestFunc(varm)_$1(VarArgs) { - int ncid; - int d; - int i; - int j; - int k; - int m; - int err; - int allInExtRange; /* all values within external range? */ - int allInIntRange; /* all values within internal range? */ - int nels; - int nslabs; - int nstarts; /* number of different starts */ - int nok = 0; /* count of valid comparisons */ - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t index2[MAX_RANK]; - size_t mid[MAX_RANK]; - size_t count[MAX_RANK]; - size_t sstride[MAX_RANK]; - ptrdiff_t stride[MAX_RANK]; - ptrdiff_t imap[MAX_RANK]; + int i, k, d, err, nslabs, ncid, cdf_format; + int allInExtRange; /* all values within external range? */ + int allInIntRange; /* all values within internal range? */ + PTRDType nstarts; /* number of different starts */ + int nok = 0; /* count of valid comparisons */ int canConvert; /* Both text or both numeric */ - $1 value[MAX_NELS]; + IntType j, m, nels; + IntType start[MAX_RANK], edge[MAX_RANK], index[MAX_RANK]; + IntType index2[MAX_RANK], mid[MAX_RANK], count[MAX_RANK]; + IntType sstride[MAX_RANK]; + PTRDType stride[MAX_RANK], imap[MAX_RANK]; double expect[MAX_NELS]; + $1 value[MAX_NELS]; + + err = FileOpen(testfile, NC_NOWRITE); + IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) error("inq_format: %s", APIFunc(strerror)(err)); + + err = GetVarm($1)(BAD_ID, 0, NULL, NULL, NULL, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + err = GetVarm($1)(ncid, BAD_VARID, NULL, NULL, NULL, NULL, value); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); assert(var_rank[i] <= MAX_RANK); assert(var_nels[i] <= MAX_NELS); + + /* check if can detect a bad file ID */ + err = GetVars($1)(BAD_ID, i, NULL, NULL, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + for (j = 0; j < var_rank[i]; j++) { start[j] = 0; edge[j] = 1; stride[j] = 1; imap[j] = 1; } - err = nc_get_varm_$1(BAD_ID, i, start, edge, stride, imap, value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_varm_$1(ncid, BAD_VARID, start, edge, stride, imap, value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = GetVarm($1)(ncid, i, NULL, NULL, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } + else if (var_rank[i] == 0) { + index[0] = 0; + expect[0] = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[0], var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect[0])) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + + /* for non-scalar variables, argument count cannot be NULL */ + err = GetVarm($1)(ncid, i, start, NULL, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } + else if (var_rank[i] == 0) { + index[0] = 0; + expect[0] = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[0], var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect[0])) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) + } + else IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDGE, err) + ELSE_NOK +')dnl + + /* first test when edge[*] > 0 */ for (j = 0; j < var_rank[i]; j++) { start[j] = var_shape[i][j]; - err = nc_get_varm_$1(ncid, i, start, edge, stride, imap, value); - if(!canConvert) { - IF (err != NC_ECHAR) - error("conversion: status = %d", err); - } else { - IF (err != NC_EINVALCOORDS) - error("bad index: status = %d", err); + err = GetVarm($1)(ncid, i, start, edge, stride, imap, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + continue; + } + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) start[j] = 0; edge[j] = var_shape[i][j] + 1; - err = nc_get_varm_$1(ncid, i, start, edge, stride, imap, value); + err = GetVarm($1)(ncid, i, start, edge, stride, imap, value); IF (err != NC_EEDGE) - error("bad edge: status = %d", err); + EXPECT_ERR(NC_EEDGE, err) edge[j] = 1; stride[j] = 0; - err = nc_get_varm_$1(ncid, i, start, edge, stride, imap, value); + err = GetVarm($1)(ncid, i, start, edge, stride, imap, value); + IF (err != NC_ESTRIDE) + EXPECT_ERR(NC_ESTRIDE, err) + stride[j] = 1; + } + + /* Check non-scalars for correct error returned even when there is + * nothing to get (edge[j]==0) */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = GetVarm($1)(ncid, i, start, edge, stride, imap, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + start[j] = 0; + continue; + } +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + start[j] = var_shape[i][j]+1; /* should cause NC_EINVALCOORDS */ + err = GetVarm($1)(ncid, i, start, edge, stride, imap, value); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + start[j] = 0; +ifdef(`PNETCDF',,``#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>=7)') + stride[j] = 0; + err = GetVarm($1)(ncid, i, start, edge, stride, imap, value); IF (err != NC_ESTRIDE) - error("bad stride: status = %d", err); + EXPECT_ERR(NC_ESTRIDE, err) stride[j] = 1; - } +ifdef(`PNETCDF',,``#'endif') + } + + err = GetVarm($1)(ncid, i, start, edge, stride, imap, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + } else if (var_rank[i] == 0) { + expect[0] = hash4(cdf_format, var_type[i], 0, index, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[0], var_type[i], NCT_ITYPE($1)) && + CheckRange($1, expect[0])) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>7)')') + else IF (err != NC_ERANGE) EXPECT_ERR(NC_ERANGE, err) +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')') + } else { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) } - /* Choose a random point dividing each dim into 2 parts */ - /* get 2^rank (nslabs) slabs so defined */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + /* Choose a random point dividing each dim into 2 parts */ + /* get 2^rank (nslabs) slabs so defined */ nslabs = 1; for (j = 0; j < var_rank[i]; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } - /* bits of k determine whether to get lower or upper part of dim */ - /* choose random stride from 1 to edge */ + /* bits of k determine whether to get lower or upper part of dim */ + /* choose random stride from 1 to edge */ for (k = 0; k < nslabs; k++) { nstarts = 1; for (j = 0; j < var_rank[i]; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; - }else{ + } else { start[j] = mid[j]; edge[j] = var_shape[i][j] - mid[j]; } - sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + stride[j] = (PTRDType)sstride[j]; nstarts *= stride[j]; } for (m = 0; m < nstarts; m++) { err = toMixedBase(m, var_rank[i], sstride, index); - IF (err) - error("error in toMixedBase"); + IF (err != 0) error("error in toMixedBase"); nels = 1; for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / stride[j]; + count[j] = 1 + (edge[j]-index[j]-1) / (IntType)stride[j]; nels *= count[j]; index[j] += start[j]; } - /* Random choice of forward or backward */ + /* Random choice of forward or backward */ /* TODO - if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { - index[j] += (count[j] - 1) * stride[j]; - stride[j] = -stride[j]; - } - } + if ( roll(2) ) { + for (j = 0; j < var_rank[i]; j++) { + index[j] += (count[j] - 1) * (IntType)stride[j]; + stride[j] = -stride[j]; + } + } */ - if (var_rank[i] > 0) { - j = var_rank[i] - 1; - imap[j] = 1; - for (; j > 0; j--) - imap[j-1] = imap[j] * count[j]; - } + if (var_rank[i] > 0) { + int jj = var_rank[i] - 1; + imap[jj] = 1; + for (; jj > 0; jj--) + imap[jj-1] = imap[jj] * (PTRDType)count[jj]; + } allInExtRange = allInIntRange = 1; for (j = 0; j < nels; j++) { err = toMixedBase(j, var_rank[i], count, index2); - IF (err) - error("error in toMixedBase 1"); + IF (err != 0) error("error in toMixedBase"); for (d = 0; d < var_rank[i]; d++) - index2[d] = index[d] + index2[d] * stride[d]; - expect[j] = hash4(var_type[i], var_rank[i], index2, - NCT_ITYPE($1)); - if (inRange3(expect[j],var_type[i],NCT_ITYPE($1))) { - allInIntRange = allInIntRange && expect[j] >= $1_min - && expect[j] <= $1_max; - } else { + index2[d] = index[d] + index2[d] * (IntType)stride[d]; + expect[j] = hash4(cdf_format, var_type[i], var_rank[i], + index2, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[j],var_type[i],NCT_ITYPE($1))) { + IfCheckTextChar($1, var_type[i]) + allInIntRange &= CheckRange($1,expect[j]); + } else allInExtRange = 0; - } } - if (var_rank[i] == 0 && i%2 ) - err = nc_get_varm_$1(ncid,i,NULL,NULL,NULL,NULL,value); - else - err = nc_get_varm_$1(ncid,i,index,count,stride,imap,value); + err = GetVarm($1)(ncid,i,index,count,stride,imap,value); if (canConvert) { if (allInExtRange) { if (allInIntRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) - error("Range error: status = %d", err); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) } + PNETCDF_CHECK_ERANGE($1) } else { - IF (err != 0 && err != NC_ERANGE) - error("OK or Range error: status = %d", err); + IF (err != NC_NOERR && err != NC_ERANGE) + EXPECT_ERR(NC_NOERR or NC_ERANGE, err) } for (j = 0; j < nels; j++) { - if (inRange3(expect[j],var_type[i],NCT_ITYPE($1)) - && expect[j] >= $1_min - && expect[j] <= $1_max) { - IF (!equal(value[j],expect[j],var_type[i], NCT_ITYPE($1))){ + if (CheckNumRange($1, expect[j], var_type[i])) { + ifelse(`$1', `uchar', ` + /* in put_vars(), API _put_vara_double() is used to + * write the NC_BYTE variables to files. In this + * case, NC_BYTE variables are treated as signed + * for CDF-1 and 2 formats. Thus, we must skip the + * equal test below for uchar. + */ + if (cdf_format < NC_FORMAT_CDF5 && var_type[i] == NC_BYTE && expect[j] > schar_max) continue;') + IF (!equal((double)value[j],expect[j],var_type[i], NCT_ITYPE($1))){ error("value read not that expected"); if (verbose) { error("\n"); error("varid: %d, ", i); error("var_name: %s, ", var_name[i]); - error("element number: %d ", j); + error("var_type: %s, ", s_nc_type(var_type[i])); + error("element number: %d, ", j); error("expect: %g, ", expect[j]); error("got: %g", (double) value[j]); } - } else { - nok++; } + ELSE_NOK } } } else { - IF (nels > 0 && err != NC_ECHAR) - error("wrong type: status = %d", err); + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) } } } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; } ')dnl @@ -814,90 +1224,130 @@ dnl TEST_NC_GET_ATT(TYPE) dnl define(`TEST_NC_GET_ATT',dnl `dnl -void -test_nc_get_att_$1(void) +int +TestFunc(att)_$1(AttVarArgs) { - int ncid; - int i; - int j; - size_t k; - int err; + int i, j, err, ncid, cdf_format; + IntType k, ndx[1]; int allInExtRange; int allInIntRange; int canConvert; /* Both text or both numeric */ - $1 value[MAX_NELS]; + int nok = 0; /* count of valid comparisons */ double expect[MAX_NELS]; - int nok = 0; /* count of valid comparisons */ + $1 value[MAX_NELS]; + + err = FileOpen(testfile, NC_NOWRITE); + IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) error("inq_format: %s", APIFunc(strerror)(err)); - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); + err = GetAtt($1)(BAD_ID, 0, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + err = GetAtt($1)(ncid, BAD_VARID, NULL, value); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK for (i = -1; i < numVars; i++) { for (j = 0; j < NATTS(i); j++) { - canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); - err = nc_get_att_$1(BAD_ID, i, ATT_NAME(i,j), value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_att_$1(ncid, BAD_VARID, ATT_NAME(i,j), value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - err = nc_get_att_$1(ncid, i, "noSuch", value); - IF (err != NC_ENOTATT) - error("Bad attribute name: status = %d", err); - allInExtRange = allInIntRange = 1; + canConvert = (ATT_TYPE(i,j) == NC_CHAR) CheckText($1); + + err = GetAtt($1)(ncid, BAD_VARID, ATT_NAME(i,j), value); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK + +ifdef(`PNETCDF',,``#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>7)') + /* check if can detect a bad name */ + err = GetAtt($1)(ncid, i, NULL, NULL); + IF (err != NC_EBADNAME) + EXPECT_ERR(NC_EBADNAME, err) + ELSE_NOK +ifdef(`PNETCDF',,``#'endif') + + err = GetAtt($1)(ncid, i, "noSuch", value); + IF (err != NC_ENOTATT) + EXPECT_ERR(NC_ENOTATT, err) + ELSE_NOK + + allInExtRange = allInIntRange = 1; for (k = 0; k < ATT_LEN(i,j); k++) { - expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_ITYPE($1)); - if (inRange3(expect[k],ATT_TYPE(i,j),NCT_ITYPE($1))) { - allInIntRange = allInIntRange && expect[k] >= $1_min - && expect[k] <= $1_max; + ndx[0] = k; + expect[k] = hash4(cdf_format, ATT_TYPE(i,j), -1, ndx, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[k],ATT_TYPE(i,j),NCT_ITYPE($1))) { + /* netCDF specification make a special case for type + * conversion between uchar and scahr: do not check for + * range error. See + * http://www.unidata.ucar.edu/software/netcdf/docs/data_type.html#type_conversion + */ + IfCheckTextChar($1, ATT_TYPE(i,j)) + ifelse(`$1',`uchar', `if (cdf_format > NC_FORMAT_64BIT_OFFSET || (cdf_format < NC_FORMAT_CDF5 && ATT_TYPE(i,j) != NC_BYTE))') + allInIntRange &= CheckRange($1,expect[k]); } else { allInExtRange = 0; } - } - err = nc_get_att_$1(ncid, i, ATT_NAME(i,j), value); + } + err = GetAtt($1)(ncid, i, ATT_NAME(i,j), value); if (canConvert || ATT_LEN(i,j) == 0) { if (allInExtRange) { if (allInIntRange) { - IF (err) - error("%s", nc_strerror(err)); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>7)')') } else { IF (err != NC_ERANGE) - error("Range error: status = %d", err); + EXPECT_ERR(NC_ERANGE, err) +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')') } } else { - IF (err != 0 && err != NC_ERANGE) - error("OK or Range error: status = %d", err); + IF (err != NC_NOERR && err != NC_ERANGE) + EXPECT_ERR(NC_NOERR or NC_ERANGE, err) } - for (k = 0; k < ATT_LEN(i,j); k++) { - if (inRange3(expect[k],ATT_TYPE(i,j),NCT_ITYPE($1)) - && expect[k] >= $1_min && expect[k] <= $1_max) { - IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_ITYPE($1))){ - error("value read not that expected"); + for (k = 0; k < ATT_LEN(i,j); k++) { + if (CheckNumRange($1, expect[k], ATT_TYPE(i,j))) { + ifelse(`$1', `uchar', ` + /* in put_vars(), API _put_vara_double() is used to + * write the NC_BYTE variables to files. In this + * case, NC_BYTE variables are treated as signed + * for CDF-1 and 2 formats. Thus, we must skip the + * equal test below for uchar. + */ + if (cdf_format < NC_FORMAT_CDF5 && ATT_TYPE(i,j) == NC_BYTE && expect[k] > schar_max) continue;') + IF (!equal((double)value[k],expect[k],ATT_TYPE(i,j), NCT_ITYPE($1))){ + error("value read not that expected"); if (verbose) { error("\n"); error("varid: %d, ", i); + if (i == -1) + error("var_type: GLOBAL, "); + else + error("var_name: %s var_type: %s, ", var_name[i],s_nc_type(var_type[i])); error("att_name: %s, ", ATT_NAME(i,j)); - error("element number: %d ", k); - error("expect: %g", expect[k]); + error("att_type: %s, ", s_nc_type(ATT_TYPE(i,j))); + error("element number: %d, ", k); + error("expect: %g, ", expect[k]); error("got: %g", (double) value[k]); } - } else { - nok++; + } else { + nok++; } - } - } - } else { - IF (err != NC_ECHAR) - error("wrong type: status = %d", err); - } - } + } + } + } else { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + } + } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; } ')dnl diff --git a/nc_test/test_get_p5.m4 b/nc_test/test_get_p5.m4 index 91b09e9a1a..dd2066daa8 100644 --- a/nc_test/test_get_p5.m4 +++ b/nc_test/test_get_p5.m4 @@ -82,7 +82,7 @@ test_nc_get_var1_$1(void) err = toMixedBase(j, var_rank[i], var_shape[i], index); IF (err) error("error in toMixedBase 1"); - expect = hash4( var_type[i], var_rank[i], index, NCT_ITYPE($1) ); + expect = hash4(cdf_format, var_type[i], var_rank[i], index, NCT_ITYPE($1)); if (var_rank[i] == 0 && i%2 ) err = nc_get_var1_$1(ncid, i, NULL, &value); else @@ -182,7 +182,7 @@ test_nc_get_var_$1(void) err = toMixedBase(j, var_rank[i], var_shape[i], index); IF (err) error("error in toMixedBase 1"); - expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ITYPE($1)); + expect[j] = hash4(cdf_format,var_type[i], var_rank[i], index, NCT_ITYPE($1)); if (inRange3(expect[j],var_type[i], NCT_ITYPE($1))) { allInIntRange = allInIntRange && expect[j] >= $1_min && expect[j] <= $1_max; @@ -366,7 +366,7 @@ test_nc_get_vara_$1(void) error("error in toMixedBase 1"); for (d = 0; d < var_rank[i]; d++) index[d] += start[d]; - expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ITYPE($1)); + expect[j] = hash4(cdf_format,var_type[i], var_rank[i], index, NCT_ITYPE($1)); if (inRange3(expect[j],var_type[i], NCT_ITYPE($1))) { allInIntRange = allInIntRange && expect[j] >= $1_min && expect[j] <= $1_max; @@ -560,7 +560,7 @@ test_nc_get_vars_$1(void) error("error in toMixedBase 1"); for (d = 0; d < var_rank[i]; d++) index2[d] = index[d] + index2[d] * stride[d]; - expect[j] = hash4(var_type[i], var_rank[i], index2, + expect[j] = hash4(cdf_format,var_type[i], var_rank[i], index2, NCT_ITYPE($1)); if (inRange3(expect[j],var_type[i],NCT_ITYPE($1))) { allInIntRange = allInIntRange && expect[j] >= $1_min @@ -766,7 +766,7 @@ test_nc_get_varm_$1(void) error("error in toMixedBase 1"); for (d = 0; d < var_rank[i]; d++) index2[d] = index[d] + index2[d] * stride[d]; - expect[j] = hash4(var_type[i], var_rank[i], index2, + expect[j] = hash4(cdf_format,var_type[i], var_rank[i], index2, NCT_ITYPE($1)); if (inRange3(expect[j],var_type[i],NCT_ITYPE($1))) { allInIntRange = allInIntRange && expect[j] >= $1_min @@ -881,7 +881,7 @@ test_nc_get_att_$1(void) error("Bad attribute name: status = %d", err); allInExtRange = allInIntRange = 1; for (k = 0; k < ATT_LEN(i,j); k++) { - expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_ITYPE($1)); + expect[k] = hash4(cdf_format,ATT_TYPE(i,j), -1, &k, NCT_ITYPE($1)); if (inRange3(expect[k],ATT_TYPE(i,j),NCT_ITYPE($1))) { allInIntRange = allInIntRange && expect[k] >= $1_min && expect[k] <= $1_max; diff --git a/nc_test/test_put.m4 b/nc_test/test_put.m4 index 32601f5aa0..d586b91758 100644 --- a/nc_test/test_put.m4 +++ b/nc_test/test_put.m4 @@ -1,18 +1,75 @@ dnl This is m4 source. dnl Process using m4 to produce 'C' language file. dnl +dnl This file is supposed to be the same as PnetCDF's test_put.m4 +dnl dnl If you see this line, you can ignore the next one. /* Do not edit this file. It is produced from the corresponding .m4 source */ dnl -/********************************************************************* - * Copyright 1996, UCAR/Unidata - * See netcdf/COPYRIGHT file for copying and redistribution conditions. - * $Id: test_put.m4 2785 2014-10-26 05:21:20Z wkliao $ - *********************************************************************/ - -#ifdef USE_PARALLEL -#include +/* + * Copyright (C) 2003, Northwestern University and Argonne National Laboratory + * See COPYRIGHT notice in top-level directory. + */ +/* $Id: test_put.m4 2672 2016-12-03 19:23:53Z wkliao $ */ + +dnl +dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF +dnl in terms of function prefix names (ncmpi_ vs. nc_), integer data types +dnl (MPI_Offset vs. size_t), and function name substrings for external data +dnl types. +dnl + +#include "tests.h" + +ifdef(`PNETCDF',,`dnl +#ifdef USE_PNETCDF +#include +#ifndef PNETCDF_VERSION_MAJOR +#error("PNETCDF_VERSION_MAJOR is not defined in pnetcdf.h") +#endif +#ifndef PNETCDF_VERSION_MINOR +#error("PNETCDF_VERSION_MAJOR is not defined in pnetcdf.h") #endif +#endif') + +define(`EXPECT_ERR',`error("expecting $1 but got %s",nc_err_code_name($2));')dnl + +define(`IntType', `ifdef(`PNETCDF',`MPI_Offset',`size_t')')dnl +define(`PTRDType',`ifdef(`PNETCDF',`MPI_Offset',`ptrdiff_t')')dnl +define(`TestFunc',`ifdef(`PNETCDF',`test_ncmpi_put_$1',`test_nc_put_$1')')dnl +define(`APIFunc',` ifdef(`PNETCDF',`ncmpi_$1',`nc_$1')')dnl + +define(`FileOpen', `ifdef(`PNETCDF',`ncmpi_open(comm, $1, $2, info, &ncid)', `file_open($1, $2, &ncid)')')dnl +define(`FileCreate',`ifdef(`PNETCDF',`ncmpi_create(comm, $1, $2, info, &ncid)', `file_create($1, $2, &ncid)')')dnl +define(`FileDelete',`ifdef(`PNETCDF',`ncmpi_delete($1,$2)',`nc_delete($1)')')dnl + +define(`VarArgs', `ifdef(`PNETCDF',`int numVars',`void')')dnl +define(`AttVarArgs',`ifdef(`PNETCDF',`int numGatts,int numVars',`void')')dnl + +define(`PutVar1',`ifdef(`PNETCDF',`ncmpi_put_var1_$1_all',`nc_put_var1_$1')')dnl +define(`PutVar', `ifdef(`PNETCDF',`ncmpi_put_var_$1_all', `nc_put_var_$1')')dnl +define(`PutVara',`ifdef(`PNETCDF',`ncmpi_put_vara_$1_all',`nc_put_vara_$1')')dnl +define(`PutVars',`ifdef(`PNETCDF',`ncmpi_put_vars_$1_all',`nc_put_vars_$1')')dnl +define(`PutVarm',`ifdef(`PNETCDF',`ncmpi_put_varm_$1_all',`nc_put_varm_$1')')dnl +define(`PutAtt', `ifdef(`PNETCDF',`ncmpi_put_att_$1',`nc_put_att_$1')')dnl +define(`GetVar1',`ifdef(`PNETCDF',`ncmpi_get_var1_$1_all',`nc_get_var1_$1')')dnl +define(`DefVars',`ifdef(`PNETCDF',`def_vars($1,$2)',`def_vars($1)')')dnl + +define(`PNETCDF_CHECK_ERANGE',`dnl +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,` +`#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>=8)')', + `$1',`schar',`ifdef(`PNETCDF',,` +`#'if defined(USE_PNETCDF) && PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR<7 + else if (cdf_format < NC_FORMAT_CDF5) { +`#'else')') + else { +ifelse(`$1',`schar',`ifdef(`PNETCDF',,``#'endif')') + IF (err != NC_ERANGE) + EXPECT_ERR(NC_ERANGE, err) + ELSE_NOK + } +ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')')' +)dnl undefine(`index')dnl dnl dnl dnl @@ -30,10 +87,22 @@ dnl dnl dnl dnl dnl NCT_ITYPE(type) dnl -define(`NCT_ITYPE', ``NCT_'Upcase($1)')dnl +define(`NCT_ITYPE', ``NCT_'Upcase($1)')dnl +define(`NC_TYPE', ``NC_'Upcase($1)')dnl +define(`X_MIN', ``X_'Upcase($1)_MIN')dnl +define(`X_MAX', ``X_'Upcase($1)_MAX')dnl dnl -#include "tests.h" +define(`CheckText', `ifelse(`$1',`text', , `== (NCT_ITYPE($1) == NCT_TEXT)')')dnl +define(`IfCheckTextChar', `ifelse(`$1',`text', `if ($2 != NC_CHAR)')')dnl +define(`CheckNumRange', + `ifelse(`$1',`text', `1', + `inRange3(cdf_format, (double)$2,$3,NCT_ITYPE($1)) && ($2 >= $1_min && $2 <= $1_max)')')dnl +define(`CheckRange', + `ifelse(`$1',`text', `0', `($2 >= $1_min && $2 <= $1_max)')')dnl +define(`CheckRange3', + `ifelse(`$1',`text', `1', + `inRange3(cdf_format, (double)$2,$3,NCT_ITYPE($1))')')dnl dnl HASH(TYPE) dnl @@ -42,18 +111,20 @@ define(`HASH',dnl /* * ensure hash value within range for internal TYPE */ -static -double -hash_$1( - const nc_type type, - const int rank, - const size_t *index, - const nct_itype itype) +$1 +hash_$1(const int cdf_format, + const nc_type type, + const int rank, + const IntType *index, + const nct_itype itype) { - const double min = $1_min; - const double max = $1_max; + double value; - return MAX(min, MIN(max, hash4( type, rank, index, itype))); + value = hash4(cdf_format, type, rank, index, itype); + ifelse(`$1',`text',`return (text)value;',` + if (value > $1_max) return $1_max; + else if (value < $1_min) return $1_min; + else return ($1)value;') } ')dnl @@ -75,88 +146,92 @@ dnl CHECK_VARS(TYPE) dnl define(`CHECK_VARS',dnl `dnl -/* +/* * check all vars in file which are (text/numeric) compatible with TYPE */ -static -void -check_vars_$1(const char *filename) +int +check_vars_$1(const char *filename, int numVars) { - int ncid; /* netCDF id */ - size_t index[MAX_RANK]; - int err; /* status */ - int d; - int i; - size_t j; - $1 value; - nc_type datatype; - int ndims; + int i, d, err, ncid, cdf_format, ndims; + int canConvert; /* Both text or both numeric */ + int nok = 0; /* count of valid comparisons */ int dimids[MAX_RANK]; - double expect; + nc_type datatype; char name[NC_MAX_NAME]; - size_t length; - int canConvert; /* Both text or both numeric */ - int nok = 0; /* count of valid comparisons */ + IntType j, length, index[MAX_RANK]; + double expect; + $1 value; + + err = FileOpen(filename, NC_NOWRITE); + IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); - err = file_open(filename, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) error("inq_format: %s", APIFunc(strerror)(err)); for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); - if (canConvert) { - err = nc_inq_var(ncid, i, name, &datatype, &ndims, dimids, NULL); - IF (err) - error("nc_inq_var: %s", nc_strerror(err)); - IF (strcmp(name, var_name[i]) != 0) - error("Unexpected var_name"); - IF (datatype != var_type[i]) - error("Unexpected type"); - IF (ndims != var_rank[i]) - error("Unexpected rank"); - for (j = 0; j < ndims; j++) { - err = nc_inq_dim(ncid, dimids[j], 0, &length); - IF (err) - error("nc_inq_dim: %s", nc_strerror(err)); - IF (length != var_shape[i][j]) - error("Unexpected shape"); - } - for (j = 0; j < var_nels[i]; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase 2"); - expect = hash4( var_type[i], var_rank[i], index, NCT_ITYPE($1)); - err = nc_get_var1_$1(ncid, i, index, &value); - if (inRange3(expect,datatype,NCT_ITYPE($1))) { - if (expect >= $1_min && expect <= $1_max) { - IF (err) { - error("nc_get_var1_$1: %s", nc_strerror(err)); - } else { - IF (!equal(value,expect,var_type[i],NCT_ITYPE($1))) { - error("Var value read not that expected"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("var_name: %s, ", var_name[i]); - error("index:"); - for (d = 0; d < var_rank[i]; d++) - error(" %d", index[d]); - error(", expect: %g, ", expect); - error("got: %g", (double) value); - } - } else { - ++nok; - } - } - } - } - } - } + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + if (!canConvert) continue; + + err = APIFunc(inq_var)(ncid, i, name, &datatype, &ndims, dimids, NULL); + IF (err != NC_NOERR) + error("inq_var: %s", APIFunc(strerror)(err)); + IF (strcmp(name, var_name[i]) != 0) + error("Unexpected var_name"); + IF (datatype != var_type[i]) + error("Unexpected type"); + IF (ndims != var_rank[i]) + error("Unexpected rank"); + for (j = 0; j < ndims; j++) { + err = APIFunc(inq_dim)(ncid, dimids[j], 0, &length); + IF (err != NC_NOERR) + error("inq_dim: %s", APIFunc(strerror)(err)); + IF (length != var_shape[i][j]) + error("Unexpected shape"); + } + for (j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + expect = hash4(cdf_format, var_type[i], var_rank[i], index, + NCT_ITYPE($1)); + err = GetVar1($1)(ncid, i, index, &value); + if (CheckNumRange($1, expect, datatype)) { + IF (err != NC_NOERR) { + error("GetVar1($1): %s", APIFunc(strerror)(err)); + } else { + ifelse(`$1', `uchar', ` + /* In put_vars(), PutVara(double)() is used to write + * variables of type NC_BYTE to files. For uchar APIs, + * NC_BYTE variables are treated as unsigned for CDF-1 and 2 + * formats. Thus, we skip the equal test for out-of-bound + * values below for uchar APIs. + */ + if (cdf_format < NC_FORMAT_CDF5 && + var_type[i] == NC_BYTE && expect > schar_max) + continue;') + IF (!equal((double)value,expect,var_type[i],NCT_ITYPE($1))){ + error("Var value read not that expected"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("var_name: %s, ", var_name[i]); + error("var_type: %s, ", s_nc_type(var_type[i])); + error("index:"); + for (d = 0; d < var_rank[i]; d++) + error(" %d", index[d]); + error(", expect: %g, ", expect); + error("got: %g", (double) value); + } + } else { + ++nok; + } + } + } + } } - err = nc_close (ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; } ')dnl @@ -174,83 +249,97 @@ CHECK_VARS(longlong) CHECK_VARS(ulonglong) -dnl CHECK_ATTS(TYPE) numeric only +dnl CHECK_ATTS(TYPE) dnl define(`CHECK_ATTS',dnl `dnl -/* - * check all attributes in file which are (text/numeric) compatible with TYPE - * ignore any attributes containing values outside range of TYPE +/* + * for _text tests, check all attributes in file which are of text type + * Note no NC_ERANGE check for text attributes as text is not convertible to + * any other numerical data types (i.e. NC_ECHAR) + * + * for other tests, check all numerical attributes in file against values + * outside range of type $1 */ -static -void -check_atts_$1(int ncid) +int +check_atts_$1(int ncid, int numGatts, int numVars) { - int err; /* status */ - int i; - int j; - size_t k; - $1 value[MAX_NELS]; + int i, j, cdf_format, err; + int canConvert; /* Both text or both numeric */ + int nok = 0; /* count of valid comparisons */ + IntType k, length, ndx[1]; nc_type datatype; + IntType nInExtRange; /* number values within external range */ + IntType nInIntRange; /* number values within internal range */ double expect[MAX_NELS]; - size_t length; - size_t nInExtRange; /* number values within external range */ - size_t nInIntRange; /* number values within internal range */ - int canConvert; /* Both text or both numeric */ - int nok = 0; /* count of valid comparisons */ + $1 value[MAX_NELS]; + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) + error("inq_format: %s", APIFunc(strerror)(err)); for (i = -1; i < numVars; i++) { for (j = 0; j < NATTS(i); j++) { - canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); - if (canConvert) { - err = nc_inq_att(ncid, i, ATT_NAME(i,j), &datatype, &length); - IF (err) - error("nc_inq_att: %s", nc_strerror(err)); - IF (datatype != ATT_TYPE(i,j)) - error("nc_inq_att: unexpected type"); - IF (length != ATT_LEN(i,j)) - error("nc_inq_att: unexpected length"); - assert(length <= MAX_NELS); - nInIntRange = nInExtRange = 0; - for (k = 0; k < length; k++) { - expect[k] = hash4( datatype, -1, &k, NCT_ITYPE($1)); - if (inRange3(expect[k], datatype, NCT_ITYPE($1))) { - ++nInExtRange; - if (expect[k] >= $1_min && expect[k] <= $1_max) - ++nInIntRange; - } - } - err = nc_get_att_$1(ncid, i, ATT_NAME(i,j), value); - if (nInExtRange == length && nInIntRange == length) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != 0 && err != NC_ERANGE) - error("OK or Range error: status = %d", err); + canConvert = (ATT_TYPE(i,j) == NC_CHAR) CheckText($1); + if (!canConvert) continue; + + err = APIFunc(inq_att)(ncid, i, ATT_NAME(i,j), &datatype, &length); + IF (err != NC_NOERR) + error("inq_att: %s", APIFunc(strerror)(err)); + IF (datatype != ATT_TYPE(i,j)) + error("inq_att: unexpected type"); + IF (length != ATT_LEN(i,j)) + error("inq_att: unexpected length"); + assert(length <= MAX_NELS); + nInIntRange = nInExtRange = 0; + for (k = 0; k < length; k++) { + ndx[0] = k; + expect[k] = hash4(cdf_format, datatype, -1, ndx, NCT_ITYPE($1)); + if (inRange3(cdf_format, expect[k], datatype, NCT_ITYPE($1))) { + ++nInExtRange; + if (CheckRange($1, expect[k])) + ++nInIntRange; } - for (k = 0; k < length; k++) { - if (inRange3(expect[k],datatype,NCT_ITYPE($1)) - && expect[k] >= $1_min && expect[k] <= $1_max) { - IF (!equal(value[k],expect[k],datatype,NCT_ITYPE($1))) { - error("att. value read not that expected"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("att_name: %s, ", ATT_NAME(i,j)); - error("element number: %d ", k); - error("expect: %g, ", expect[k]); - error("got: %g", (double) value[k]); - } - } else { - nok++; + } + err = APIFunc(get_att_$1)(ncid, i, ATT_NAME(i,j), value); + if (nInExtRange == length && nInIntRange == length) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + } else { + IF (err != NC_NOERR && err != NC_ERANGE) + EXPECT_ERR(NC_NOERR or NC_ERANGE, err) + } + for (k = 0; k < length; k++) { + if (CheckNumRange($1, expect[k], datatype)) { + ifelse(`$1', `uchar', ` + /* In put_vars(), PutVara(double)() is used to write + * variables of type NC_BYTE to files. For uchar APIs, + * NC_BYTE variables are treated as unsigned for CDF-1 and 2 + * formats. Thus, we skip the equal test for out-of-bound + * values below for uchar APIs. + */ + if (cdf_format < NC_FORMAT_CDF5 && + ATT_TYPE(i,j) == NC_BYTE && expect[k] > schar_max) + continue;') + IF (!equal((double)value[k],expect[k],datatype,NCT_ITYPE($1))) { + error("att. value read not that expected"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("att_name: %s, ", ATT_NAME(i,j)); + error("att_type: %s, ", s_nc_type(ATT_TYPE(i,j))); + error("element number: %d ", k); + error("expect: %g, ", expect[k]); + error("got: %g", (double) value[k]); } + } else { + nok++; } } - } + } } } - - print_nok(nok); + return nok; } ')dnl @@ -272,98 +361,123 @@ dnl TEST_NC_PUT_VAR1(TYPE) dnl define(`TEST_NC_PUT_VAR1',dnl `dnl -void -test_nc_put_var1_$1(void) +int +TestFunc(var1)_$1(VarArgs) { - int ncid; - int i; - int j; - int err; - size_t index[MAX_RANK]; - int canConvert; /* Both text or both numeric */ - $1 value = 5; /* any value would do - only for error cases */ - - err = file_create(scratch, NC_CLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; + int i, err, ncid, cdf_format, nok=0; + int canConvert; /* Both text or both numeric */ + IntType j, index[MAX_RANK]; + $1 value[1]; + + err = FileCreate(scratch, NC_CLOBBER); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; } + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) + error("inq_format: %s", APIFunc(strerror)(err)); + def_dims(ncid); - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); + DefVars(ncid, numVars); -#ifdef USE_PNETCDF - { - int format; - nc_inq_format_extended(ncid, &format, NULL); - if (format == NC_FORMATX_PNETCDF) { - for (i = 0; i < numVars; i++) { - err = nc_var_par_access(ncid, i, NC_COLLECTIVE); - IF (err) - error("nc_var_par_access: %s", nc_strerror(err)); - } - } - } -#endif + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = PutVar1($1)(BAD_ID, 0, NULL, NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutVar1($1)(ncid, BAD_VARID, NULL, NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); - for (j = 0; j < var_rank[i]; j++) - index[j] = 0; - err = nc_put_var1_$1(BAD_ID, i, index, &value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_var1_$1(ncid, BAD_VARID, index, &value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + value[0] = 5; /* reset to a value within bounds */ + + /* check if can detect a bad file ID */ + err = PutVar1($1)(BAD_ID, i, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = PutVar1($1)(ncid, i, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err) + } + else if (var_rank[i] == 0) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK +')dnl + + /* test NC_EINVALCOORDS */ + for (j = 0; j < var_rank[i]; j++) index[j] = 0; + for (j = 0; j < var_rank[i]; j++) { - if (var_dimid[i][j] > 0) { /* skip record dim */ - index[j] = var_shape[i][j]; - err = nc_put_var1_$1(ncid, i, index, &value); - IF (canConvert && err != NC_EINVALCOORDS) - error("bad index: status = %d", err); - index[j] = 0; - } + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + index[j] = var_shape[i][j]; /* out of boundary check */ + err = PutVar1($1)(ncid, i, index, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + index[j] = 0; + continue; + } + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + index[j] = 0; } + for (j = 0; j < var_nels[i]; j++) { err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase 1"); - value = hash_$1( var_type[i], var_rank[i], index, NCT_ITYPE($1)); - if (var_rank[i] == 0 && i%2 == 0) - err = nc_put_var1_$1(ncid, i, NULL, &value); - else - err = nc_put_var1_$1(ncid, i, index, &value); - if (canConvert) { - if (inRange3(value, var_type[i],NCT_ITYPE($1))) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) { - error("Range error: status = %d", err); - error("\n\t\tfor type %s value %.17e %ld", - s_nc_type(var_type[i]), - (double)value, (long)value); - } - } - } else { - IF (err != NC_ECHAR) - error("wrong type: status = %d", err); + IF (err != 0) error("error in toMixedBase"); + value[0] = hash_$1(cdf_format, var_type[i], var_rank[i], index, + NCT_ITYPE($1)); + err = PutVar1($1)(ncid, i, index, value); + if (canConvert) { + if (CheckRange3($1, value[0], var_type[i])) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + } + PNETCDF_CHECK_ERANGE($1) + } else { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK } } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); - check_vars_$1(scratch); + nok += check_vars_$1(scratch, numVars); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("delete file %s failed", scratch); + return nok; } ')dnl @@ -385,141 +499,139 @@ dnl TEST_NC_PUT_VAR(TYPE) dnl define(`TEST_NC_PUT_VAR',dnl `dnl -void -test_nc_put_var_$1(void) +int +TestFunc(var)_$1(VarArgs) { - int ncid; - int varid; - int i; - int j; - int err; - int nels; - size_t index[MAX_RANK]; - int canConvert; /* Both text or both numeric */ - int allInExtRange; /* all values within external range? */ + int i, err, ncid, varid, cdf_format, nok=0; + int canConvert; /* Both text or both numeric */ + int allInExtRange; /* all values within external range? */ + IntType j, index[MAX_RANK]; $1 value[MAX_NELS]; - err = file_create(scratch, NC_CLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; + err = FileCreate(scratch, NC_CLOBBER); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; } + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) + error("inq_format: %s", APIFunc(strerror)(err)); + def_dims(ncid); - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); + DefVars(ncid, numVars); -#ifdef USE_PNETCDF - { - int format; - nc_inq_format_extended(ncid, &format, NULL); - if (format == NC_FORMATX_PNETCDF) { - for (i = 0; i < numVars; i++) { - err = nc_var_par_access(ncid, i, NC_COLLECTIVE); - IF (err) - error("nc_var_par_access: %s", nc_strerror(err)); - } - } - } -#endif + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = PutVar($1)(BAD_ID, 0, NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutVar($1)(ncid, BAD_VARID, NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); assert(var_rank[i] <= MAX_RANK); assert(var_nels[i] <= MAX_NELS); - err = nc_put_var_$1(BAD_ID, i, value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_var_$1(ncid, BAD_VARID, value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - - nels = 1; - for (j = 0; j < var_rank[i]; j++) { - nels *= var_shape[i][j]; - } - for (allInExtRange = 1, j = 0; j < nels; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase 1"); - value[j]= hash_$1(var_type[i], var_rank[i], index, NCT_ITYPE($1)); - allInExtRange = allInExtRange - && inRange3(value[j], var_type[i], NCT_ITYPE($1)); - } - err = nc_put_var_$1(ncid, i, value); - if (canConvert) { - if (allInExtRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE && var_dimid[i][0] != RECDIM) - error("range error: status = %d", err); - } - } else { /* should flag wrong type even if nothing to write */ - IF (nels > 0 && err != NC_ECHAR) - error("wrong type: status = %d", err); - } + + if (var_dimid[i][0] == RECDIM) continue; /* fixed-size variables only */ + + value[0] = 5; /* reset to a value within bounds */ + + /* check if can detect a bad file ID */ + err = PutVar($1)(BAD_ID, i, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + + for (allInExtRange = 1, j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + value[j]= hash_$1(cdf_format,var_type[i], var_rank[i], index, + NCT_ITYPE($1)); + IfCheckTextChar($1, var_type[i]) + allInExtRange &= inRange3(cdf_format, (double)value[j], + var_type[i], NCT_ITYPE($1)); + } + err = PutVar($1)(ncid, i, value); + if (canConvert) { + if (allInExtRange) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + } + PNETCDF_CHECK_ERANGE($1) + } else { /* should flag wrong type even if nothing to write */ + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } } - /* Preceding has written nothing for record variables, now try */ - /* again with more than 0 records */ + /* Preceding has written nothing for record variables, now try */ + /* again with more than 0 records */ - /* Write record number NRECS to force writing of preceding records */ - /* Assumes variable cr is char vector with UNLIMITED dimension */ - err = nc_inq_varid(ncid, "cr", &varid); - IF (err) - error("nc_inq_varid: %s", nc_strerror(err)); + /* Write record number NRECS to force writing of preceding records */ + /* Assumes variable cr is char vector with UNLIMITED dimension */ + err = APIFunc(inq_varid)(ncid, "cr", &varid); + IF (err != NC_NOERR) + error("inq_varid: %s", APIFunc(strerror)(err)); index[0] = NRECS-1; - err = nc_put_var1_text(ncid, varid, index, "x"); - IF (err) - error("nc_put_var1_text: %s", nc_strerror(err)); + err = PutVar1(text)(ncid, varid, index, "x"); + IF (err != NC_NOERR) + error("put_var1_text: %s", APIFunc(strerror)(err)); for (i = 0; i < numVars; i++) { - if (var_dimid[i][0] == RECDIM) { /* only test record variables here */ - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); - assert(var_rank[i] <= MAX_RANK); - assert(var_nels[i] <= MAX_NELS); - err = nc_put_var_$1(BAD_ID, i, value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - nels = 1; - for (j = 0; j < var_rank[i]; j++) { - nels *= var_shape[i][j]; - } - for (allInExtRange = 1, j = 0; j < nels; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase 1"); - value[j]= hash_$1(var_type[i], var_rank[i], index, NCT_ITYPE($1)); - allInExtRange = allInExtRange - && inRange3(value[j], var_type[i], NCT_ITYPE($1)); - } - err = nc_put_var_$1(ncid, i, value); - if (canConvert) { - if (allInExtRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) - error("range error: status = %d", err); - } - } else { - IF (nels > 0 && err != NC_ECHAR) - error("wrong type: status = %d", err); - } + if (var_dimid[i][0] != RECDIM) continue; /* only record variables here */ + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + + for (allInExtRange = 1, j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + value[j]= hash_$1(cdf_format,var_type[i], var_rank[i], index, + NCT_ITYPE($1)); + IfCheckTextChar($1, var_type[i]) + allInExtRange &= inRange3(cdf_format, (double)value[j], + var_type[i], NCT_ITYPE($1)); + } + err = PutVar($1)(ncid, i, value); + if (canConvert) { + if (allInExtRange) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + } else { + IF (err != NC_ERANGE) + EXPECT_ERR(NC_ERANGE, err) + ELSE_NOK + } + } else { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); - check_vars_$1(scratch); + nok += check_vars_$1(scratch, numVars); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("delete file %s failed", scratch); + return nok; } ')dnl @@ -541,155 +653,206 @@ dnl TEST_NC_PUT_VARA(TYPE) dnl define(`TEST_NC_PUT_VARA',dnl `dnl -void -test_nc_put_vara_$1(void) +int +TestFunc(vara)_$1(VarArgs) { - int ncid; - int d; - int i; - int j; - int k; - int err; - int nslabs; - int nels; - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t mid[MAX_RANK]; - size_t index[MAX_RANK]; - int canConvert; /* Both text or both numeric */ - int allInExtRange; /* all values within external range? */ + int i, k, d, err, nslabs, ncid, cdf_format, nok=0; + int canConvert; /* Both text or both numeric */ + int allInExtRange; /* all values within external range? */ + IntType j, nels; + IntType start[MAX_RANK], edge[MAX_RANK]; + IntType mid[MAX_RANK], index[MAX_RANK]; $1 value[MAX_NELS]; - err = file_create(scratch, NC_CLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; + err = FileCreate(scratch, NC_CLOBBER); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; } + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) + error("inq_format: %s", APIFunc(strerror)(err)); + def_dims(ncid); - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); + DefVars(ncid, numVars); -#ifdef USE_PNETCDF - { - int format; - nc_inq_format_extended(ncid, &format, NULL); - if (format == NC_FORMATX_PNETCDF) { - for (i = 0; i < numVars; i++) { - err = nc_var_par_access(ncid, i, NC_COLLECTIVE); - IF (err) - error("nc_var_par_access: %s", nc_strerror(err)); - } - } - } -#endif + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = PutVara($1)(BAD_ID, 0, NULL, NULL, NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutVara($1)(ncid, BAD_VARID, NULL, NULL, NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK - value[0] = 0; for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); assert(var_rank[i] <= MAX_RANK); assert(var_nels[i] <= MAX_NELS); + + value[0] = 5; /* reset to a value within bounds */ + + /* check if can detect a bad file ID */ + err = PutVara($1)(BAD_ID, i, NULL, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + for (j = 0; j < var_rank[i]; j++) { start[j] = 0; edge[j] = 1; - } - err = nc_put_vara_$1(BAD_ID, i, start, edge, value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_vara_$1(ncid, BAD_VARID, start, edge, value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - if (var_dimid[i][j] > 0) { /* skip record dim */ - start[j] = var_shape[i][j]; - err = nc_put_vara_$1(ncid, i, start, edge, value); - IF (canConvert && err != NC_EINVALCOORDS) - error("bad start: status = %d", err); - start[j] = 0; - edge[j] = var_shape[i][j] + 1; - err = nc_put_vara_$1(ncid, i, start, edge, value); - IF (canConvert && err != NC_EEDGE) - error("bad edge: status = %d", err); - edge[j] = 1; - } } -/* wkliao: this test below of put_vara is redundant and incorrectly uses the - value[] set from the previously iteration. There is no such test - in put_vars and put_varm. - - err = nc_put_vara_$1(ncid, i, start, edge, value); - if (canConvert) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ECHAR) - error("wrong type: status = %d", err); +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = PutVara($1)(ncid, i, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err) } -*/ + else if (var_rank[i] == 0) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + + /* for non-scalar variables, argument count cannot be NULL */ + err = PutVara($1)(ncid, i, start, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err) + } + else if (var_rank[i] == 0) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EEDGE) { + EXPECT_ERR(NC_EEDGE, err) + } + ELSE_NOK +')dnl + + /* first test when edge[*] > 0 */ for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVara($1)(ncid, i, start, edge, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + start[j] = 0; + continue; + } + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + edge[j] = var_shape[i][j] + 1; + err = PutVara($1)(ncid, i, start, edge, value); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDG, err) + ELSE_NOK edge[j] = 1; - } + } - /* Choose a random point dividing each dim into 2 parts */ - /* Put 2^rank (nslabs) slabs so defined */ - nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + /* Check correct error returned when nothing to put, when edge[*]==0 */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVara($1)(ncid, i, start, edge, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + start[j] = 0; + continue; + } +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + ELSE_NOK + start[j] = var_shape[i][j]+1; /* out of boundary check */ + err = PutVara($1)(ncid, i, start, edge, value); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + /* Choose a random point dividing each dim into 2 parts */ + /* Put 2^rank (nslabs) slabs so defined */ + nslabs = 1; + for (j = 0; j < var_rank[i]; j++) { mid[j] = roll( var_shape[i][j] ); - nslabs *= 2; - } - /* bits of k determine whether to put lower or upper part of dim */ - for (k = 0; k < nslabs; k++) { - nels = 1; - for (j = 0; j < var_rank[i]; j++) { - if ((k >> j) & 1) { - start[j] = 0; - edge[j] = mid[j]; - }else{ - start[j] = mid[j]; - edge[j] = var_shape[i][j] - mid[j]; - } - nels *= edge[j]; - } + nslabs *= 2; + } + /* bits of k determine whether to put lower or upper part of dim */ + for (k = 0; k < nslabs; k++) { + nels = 1; + for (j = 0; j < var_rank[i]; j++) { + if ((k >> j) & 1) { + start[j] = 0; + edge[j] = mid[j]; + } else { + start[j] = mid[j]; + edge[j] = var_shape[i][j] - mid[j]; + } + nels *= edge[j]; + } + for (allInExtRange = 1, j = 0; j < nels; j++) { - err = toMixedBase(j, var_rank[i], edge, index); - IF (err) - error("error in toMixedBase 1"); - for (d = 0; d < var_rank[i]; d++) - index[d] += start[d]; - value[j]= hash_$1(var_type[i], var_rank[i], index, NCT_ITYPE($1)); - allInExtRange = allInExtRange - && inRange3(value[j], var_type[i], NCT_ITYPE($1)); - } - if (var_rank[i] == 0 && i%2 == 0) - err = nc_put_vara_$1(ncid, i, NULL, NULL, value); - else - err = nc_put_vara_$1(ncid, i, start, edge, value); - if (canConvert) { - if (allInExtRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) - error("range error: status = %d", err); - } - } else { - IF (nels > 0 && err != NC_ECHAR) - error("wrong type: status = %d", err); + err = toMixedBase(j, var_rank[i], edge, index); + IF (err != 0) error("error in toMixedBase"); + for (d = 0; d < var_rank[i]; d++) + index[d] += start[d]; + value[j]= hash_$1(cdf_format,var_type[i], var_rank[i], index, + NCT_ITYPE($1)); + IfCheckTextChar($1, var_type[i]) + allInExtRange &= inRange3(cdf_format, (double)value[j], + var_type[i], NCT_ITYPE($1)); + } + err = PutVara($1)(ncid, i, start, edge, value); + if (canConvert) { + if (allInExtRange) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + } + PNETCDF_CHECK_ERANGE($1) + } else { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK } } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); - check_vars_$1(scratch); + nok += check_vars_$1(scratch, numVars); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("delete file %s failed", scratch); + return nok; } ')dnl @@ -711,176 +874,235 @@ dnl TEST_NC_PUT_VARS(TYPE) dnl define(`TEST_NC_PUT_VARS',dnl `dnl -void -test_nc_put_vars_$1(void) +int +TestFunc(vars)_$1(VarArgs) { - int ncid; - int d; - int i; - int j; - int k; - int m; - int err; - int nels; - int nslabs; - int nstarts; /* number of different starts */ - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t index2[MAX_RANK]; - size_t mid[MAX_RANK]; - size_t count[MAX_RANK]; - size_t sstride[MAX_RANK]; - ptrdiff_t stride[MAX_RANK]; - int canConvert; /* Both text or both numeric */ - int allInExtRange; /* all values within external range? */ + int i, k, d, err, nslabs, ncid, cdf_format, nok=0; + int canConvert; /* Both text or both numeric */ + int allInExtRange; /* all values within external range? */ + IntType j, m, nels; + IntType start[MAX_RANK], edge[MAX_RANK], index[MAX_RANK]; + IntType index2[MAX_RANK], mid[MAX_RANK], count[MAX_RANK]; + IntType sstride[MAX_RANK]; + PTRDType nstarts; /* number of different starts */ + PTRDType stride[MAX_RANK]; $1 value[MAX_NELS]; - err = file_create(scratch, NC_CLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; + err = FileCreate(scratch, NC_CLOBBER); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; } + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) + error("inq_format: %s", APIFunc(strerror)(err)); + def_dims(ncid); - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); + DefVars(ncid, numVars); -#ifdef USE_PNETCDF - { - int format; - nc_inq_format_extended(ncid, &format, NULL); - if (format == NC_FORMATX_PNETCDF) { - for (i = 0; i < numVars; i++) { - err = nc_var_par_access(ncid, i, NC_COLLECTIVE); - IF (err) - error("nc_var_par_access: %s", nc_strerror(err)); + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = PutVars($1)(BAD_ID, 0, NULL, NULL, NULL, NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutVars($1)(ncid, BAD_VARID, NULL, NULL, NULL, NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + value[0] = 5; /* reset to a value within bounds */ + + /* check if can detect a bad file ID */ + err = PutVars($1)(BAD_ID, i, NULL, NULL, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + + for (j = 0; j < var_rank[i]; j++) { + start[j] = 0; + edge[j] = 1; + stride[j] = 1; } - } - } +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = PutVars($1)(ncid, i, NULL, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err) + } + else if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + + /* for non-scalar variables, argument count cannot be NULL */ + err = PutVars($1)(ncid, i, start, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err) + } + else if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EEDGE) { + EXPECT_ERR(NC_EEDGE, err) + } + ELSE_NOK +')dnl + + /* first test when edge[*] > 0 */ + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; /* out of boundary check */ + err = PutVars($1)(ncid, i, start, edge, stride, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + start[j] = 0; + continue; + } + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + edge[j] = var_shape[i][j] + 1; + err = PutVars($1)(ncid, i, start, edge, stride, value); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDGE, err) + ELSE_NOK + edge[j] = 1; + stride[j] = 0; + err = PutVars($1)(ncid, i, start, edge, stride, value); + IF (err != NC_ESTRIDE) + EXPECT_ERR(NC_ESTRIDE, err) + ELSE_NOK + stride[j] = 1; + } + /* Check correct error returned even when nothing to put */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVars($1)(ncid, i, start, edge, stride, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + start[j] = 0; + continue; + } +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) #endif + ELSE_NOK + start[j] = var_shape[i][j]+1; /* out of boundary check */ + err = PutVars($1)(ncid, i, start, edge, stride, value); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; - for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); - assert(var_rank[i] <= MAX_RANK); - assert(var_nels[i] <= MAX_NELS); - for (j = 0; j < var_rank[i]; j++) { - start[j] = 0; - edge[j] = 1; - stride[j] = 1; - } - err = nc_put_vars_$1(BAD_ID, i, start, edge, stride, value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_vars_$1(ncid, BAD_VARID, start, edge, stride, value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - if (var_dimid[i][j] > 0) { /* skip record dim */ - start[j] = var_shape[i][j] + 1; - err = nc_put_vars_$1(ncid, i, start, edge, stride, value); - if(!canConvert) { - IF(err != NC_ECHAR) - error("conversion: status = %d", err); - } else { - IF(err != NC_EINVALCOORDS) - error("bad start: status = %d", err); - start[j] = 0; - edge[j] = var_shape[i][j] + 1; - err = nc_put_vars_$1(ncid, i, start, edge, stride, value); - IF (err != NC_EEDGE) - error("bad edge: status = %d", err); - edge[j] = 1; - stride[j] = 0; - err = nc_put_vars_$1(ncid, i, start, edge, stride, value); - IF (err != NC_ESTRIDE) - error("bad stride: status = %d", err); - stride[j] = 1; - } - } - } - /* Choose a random point dividing each dim into 2 parts */ - /* Put 2^rank (nslabs) slabs so defined */ - nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { - mid[j] = roll( var_shape[i][j] ); - nslabs *= 2; - } - /* bits of k determine whether to put lower or upper part of dim */ - /* choose random stride from 1 to edge */ - for (k = 0; k < nslabs; k++) { - nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { - if ((k >> j) & 1) { - start[j] = 0; - edge[j] = mid[j]; - }else{ - start[j] = mid[j]; - edge[j] = var_shape[i][j] - mid[j]; - } - sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; - nstarts *= stride[j]; - } - for (m = 0; m < nstarts; m++) { - err = toMixedBase(m, var_rank[i], sstride, index); - IF (err) - error("error in toMixedBase"); - nels = 1; - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / stride[j]; - nels *= count[j]; - index[j] += start[j]; - } - /* Random choice of forward or backward */ + /* Choose a random point dividing each dim into 2 parts */ + /* Put 2^rank (nslabs) slabs so defined */ + nslabs = 1; + for (j = 0; j < var_rank[i]; j++) { + mid[j] = roll( var_shape[i][j] ); + nslabs *= 2; + } + /* bits of k determine whether to put lower or upper part of dim */ + /* choose random stride from 1 to edge */ + for (k = 0; k < nslabs; k++) { + nstarts = 1; + for (j = 0; j < var_rank[i]; j++) { + if ((k >> j) & 1) { + start[j] = 0; + edge[j] = mid[j]; + } else { + start[j] = mid[j]; + edge[j] = var_shape[i][j] - mid[j]; + } + sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + stride[j] = (PTRDType)sstride[j]; + nstarts *= stride[j]; + } + for (m = 0; m < nstarts; m++) { + err = toMixedBase(m, var_rank[i], sstride, index); + IF (err != 0) error("error in toMixedBase"); + nels = 1; + for (j = 0; j < var_rank[i]; j++) { + count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + nels *= count[j]; + index[j] += start[j]; + } + /* Random choice of forward or backward */ /* TODO - if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { - index[j] += (count[j] - 1) * stride[j]; - stride[j] = -stride[j]; - } - } + if ( roll(2) ) { + for (j = 0; j < var_rank[i]; j++) { + index[j] += (count[j] - 1) * (IntType)stride[j]; + stride[j] = -stride[j]; + } + } */ - for (allInExtRange = 1, j = 0; j < nels; j++) { - err = toMixedBase(j, var_rank[i], count, index2); - IF (err) - error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) - index2[d] = index[d] + index2[d] * stride[d]; - value[j] = hash_$1(var_type[i], var_rank[i], index2, - NCT_ITYPE($1)); - allInExtRange = allInExtRange - && inRange3(value[j], var_type[i], NCT_ITYPE($1)); - } - if (var_rank[i] == 0 && i%2 == 0) - err = nc_put_vars_$1(ncid, i, NULL, NULL, stride, value); - else - err = nc_put_vars_$1(ncid, i, index, count, stride, value); - if (canConvert) { - if (allInExtRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) - error("range error: status = %d", err); - } - } else { - IF (nels > 0 && err != NC_ECHAR) - error("wrong type: status = %d", err); - } - } - } + for (allInExtRange = 1, j = 0; j < nels; j++) { + err = toMixedBase(j, var_rank[i], count, index2); + IF (err != 0) error("error in toMixedBase"); + for (d = 0; d < var_rank[i]; d++) + index2[d] = index[d] + index2[d] * (IntType)stride[d]; + value[j] = hash_$1(cdf_format,var_type[i], var_rank[i], + index2, NCT_ITYPE($1)); + IfCheckTextChar($1, var_type[i]) + allInExtRange &= inRange3(cdf_format, (double)value[j], + var_type[i], NCT_ITYPE($1)); + } + err = PutVars($1)(ncid, i, index, count, stride, value); + if (canConvert) { + if (allInExtRange) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + } + PNETCDF_CHECK_ERANGE($1) + } else { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } + } + } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); - check_vars_$1(scratch); + nok += check_vars_$1(scratch, numVars); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("delete file %s failed", scratch); + return nok; } ')dnl @@ -902,184 +1124,243 @@ dnl TEST_NC_PUT_VARM(TYPE) dnl define(`TEST_NC_PUT_VARM',dnl `dnl -void -test_nc_put_varm_$1(void) +int +TestFunc(varm)_$1(VarArgs) { - int ncid; - int d; - int i; - int j; - int k; - int m; - int err; - int nels; - int nslabs; - int nstarts; /* number of different starts */ - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t index2[MAX_RANK]; - size_t mid[MAX_RANK]; - size_t count[MAX_RANK]; - size_t sstride[MAX_RANK]; - ptrdiff_t stride[MAX_RANK]; - ptrdiff_t imap[MAX_RANK]; - int canConvert; /* Both text or both numeric */ - int allInExtRange; /* all values within external range? */ + int i, k, d, err, nslabs, ncid, cdf_format, nok=0; + int canConvert; /* Both text or both numeric */ + int allInExtRange; /* all values within external range? */ + IntType j, m, nels; + IntType start[MAX_RANK], edge[MAX_RANK], index[MAX_RANK]; + IntType index2[MAX_RANK], mid[MAX_RANK], count[MAX_RANK]; + IntType sstride[MAX_RANK]; + PTRDType nstarts; /* number of different starts */ + PTRDType stride[MAX_RANK], imap[MAX_RANK]; $1 value[MAX_NELS]; - err = file_create(scratch, NC_CLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; + err = FileCreate(scratch, NC_CLOBBER); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; } + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) + error("inq_format: %s", APIFunc(strerror)(err)); + def_dims(ncid); - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); + DefVars(ncid, numVars); -#ifdef USE_PNETCDF - { - int format; - nc_inq_format_extended(ncid, &format, NULL); - if (format == NC_FORMATX_PNETCDF) { - for (i = 0; i < numVars; i++) { - err = nc_var_par_access(ncid, i, NC_COLLECTIVE); - IF (err) - error("nc_var_par_access: %s", nc_strerror(err)); + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = PutVarm($1)(BAD_ID, 0, NULL, NULL, NULL, NULL, NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutVarm($1)(ncid, BAD_VARID, NULL, NULL, NULL, NULL, NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + value[0] = 5; /* reset to a value within bounds */ + + /* check if can detect a bad file ID */ + err = PutVarm($1)(BAD_ID, i, NULL, NULL, NULL, NULL, value); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + canConvert = (var_type[i] == NC_CHAR) CheckText($1); + + for (j = 0; j < var_rank[i]; j++) { + start[j] = 0; + edge[j] = 1; + stride[j] = 1; + imap[j] = 1; } - } - } + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = PutVarm($1)(ncid, i, NULL, NULL, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err) + } + else if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + + /* for non-scalar variables, argument count cannot be NULL */ + err = PutVarm($1)(ncid, i, start, NULL, NULL, NULL, value); + if (!canConvert) { + IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err) + } + else if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EEDGE) { + EXPECT_ERR(NC_EEDGE, err) + } + ELSE_NOK +')dnl + + /* first test when edge[*] > 0 */ + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; /* out of boundary check */ + err = PutVarm($1)(ncid, i, start, edge, stride, imap, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + start[j] = 0; + continue; + } + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + edge[j] = var_shape[i][j] + 1; + err = PutVarm($1)(ncid, i, start, edge, stride, imap, value); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDGE, err) + ELSE_NOK + edge[j] = 1; + stride[j] = 0; + err = PutVarm($1)(ncid, i, start, edge, stride, imap, value); + IF (err != NC_ESTRIDE) + EXPECT_ERR(NC_ESTRIDE, err) + ELSE_NOK + stride[j] = 1; + } + /* Check correct error returned when nothing to put, i.e. edge[*]==0 */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVarm($1)(ncid, i, start, edge, stride, imap, value); + if (!canConvert) { + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + start[j] = 0; + continue; + } +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) #endif + ELSE_NOK + start[j] = var_shape[i][j]+1; /* out of boundary check */ + err = PutVarm($1)(ncid, i, start, edge, stride, imap, value); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; - for (i = 0; i < numVars; i++) { - canConvert = (var_type[i] == NC_CHAR) == (NCT_ITYPE($1) == NCT_TEXT); - assert(var_rank[i] <= MAX_RANK); - assert(var_nels[i] <= MAX_NELS); - for (j = 0; j < var_rank[i]; j++) { - start[j] = 0; - edge[j] = 1; - stride[j] = 1; - imap[j] = 1; - } - err = nc_put_varm_$1(BAD_ID, i, start, edge, stride, imap, value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_varm_$1(ncid, BAD_VARID, start, edge, stride, imap, value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - if (var_dimid[i][j] > 0) { /* skip record dim */ - start[j] = var_shape[i][j] + 1; - err = nc_put_varm_$1(ncid, i, start, edge, stride, imap, value); - if (!canConvert) { - IF(err != NC_ECHAR) - error("conversion: status = %d", err); - } else { - IF (err != NC_EINVALCOORDS) - error("bad start: status = %d", err); - start[j] = 0; - edge[j] = var_shape[i][j] + 1; - err = nc_put_varm_$1(ncid, i, start, edge, stride, imap, value); - IF (err != NC_EEDGE) - error("bad edge: status = %d", err); - edge[j] = 1; - stride[j] = 0; - err = nc_put_varm_$1(ncid, i, start, edge, stride, imap, value); - IF (err != NC_ESTRIDE) - error("bad stride: status = %d", err); - stride[j] = 1; - } - } - } - /* Choose a random point dividing each dim into 2 parts */ - /* Put 2^rank (nslabs) slabs so defined */ - nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { - mid[j] = roll( var_shape[i][j] ); - nslabs *= 2; - } - /* bits of k determine whether to put lower or upper part of dim */ - /* choose random stride from 1 to edge */ - for (k = 0; k < nslabs; k++) { - nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { - if ((k >> j) & 1) { - start[j] = 0; - edge[j] = mid[j]; - }else{ - start[j] = mid[j]; - edge[j] = var_shape[i][j] - mid[j]; - } - sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; - nstarts *= stride[j]; - } + /* Choose a random point dividing each dim into 2 parts */ + /* Put 2^rank (nslabs) slabs so defined */ + nslabs = 1; + for (j = 0; j < var_rank[i]; j++) { + mid[j] = roll( var_shape[i][j] ); + nslabs *= 2; + } + /* bits of k determine whether to put lower or upper part of dim */ + /* choose random stride from 1 to edge */ + for (k = 0; k < nslabs; k++) { + nstarts = 1; + for (j = 0; j < var_rank[i]; j++) { + if ((k >> j) & 1) { + start[j] = 0; + edge[j] = mid[j]; + } else { + start[j] = mid[j]; + edge[j] = var_shape[i][j] - mid[j]; + } + sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + stride[j] = (PTRDType)sstride[j]; + nstarts *= stride[j]; + } for (m = 0; m < nstarts; m++) { err = toMixedBase(m, var_rank[i], sstride, index); - IF (err) - error("error in toMixedBase"); + IF (err != 0) error("error in toMixedBase"); nels = 1; for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / stride[j]; + count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; nels *= count[j]; index[j] += start[j]; } - /* Random choice of forward or backward */ + /* Random choice of forward or backward */ /* TODO if ( roll(2) ) { for (j = 0; j < var_rank[i]; j++) { - index[j] += (count[j] - 1) * stride[j]; + index[j] += (count[j] - 1) * (IntType)stride[j]; stride[j] = -stride[j]; } } */ if (var_rank[i] > 0) { - j = var_rank[i] - 1; - imap[j] = 1; - for (; j > 0; j--) - imap[j-1] = imap[j] * count[j]; + int jj = var_rank[i] - 1; + imap[jj] = 1; + for (; jj > 0; jj--) + imap[jj-1] = imap[jj] * (PTRDType)count[jj]; } for (allInExtRange = 1, j = 0; j < nels; j++) { err = toMixedBase(j, var_rank[i], count, index2); - IF (err) - error("error in toMixedBase"); + IF (err != 0) error("error in toMixedBase"); for (d = 0; d < var_rank[i]; d++) - index2[d] = index[d] + index2[d] * stride[d]; - value[j] = hash_$1(var_type[i], var_rank[i], index2, - NCT_ITYPE($1)); - allInExtRange = allInExtRange - && inRange3(value[j], var_type[i], NCT_ITYPE($1)); + index2[d] = index[d] + index2[d] * (IntType)stride[d]; + value[j] = hash_$1(cdf_format,var_type[i], var_rank[i], + index2, NCT_ITYPE($1)); + IfCheckTextChar($1, var_type[i]) + allInExtRange &= inRange3(cdf_format, (double)value[j], + var_type[i], NCT_ITYPE($1)); } - if (var_rank[i] == 0 && i%2 == 0) - err = nc_put_varm_$1(ncid,i,NULL,NULL,NULL,NULL,value); - else - err = nc_put_varm_$1(ncid,i,index,count,stride,imap,value); + err = PutVarm($1)(ncid,i,index,count,stride,imap,value); if (canConvert) { if (allInExtRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) - error("range error: status = %d", err); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK } + PNETCDF_CHECK_ERANGE($1) } else { - IF (nels > 0 && err != NC_ECHAR) - error("wrong type: status = %d", err); - } - } - } + IF (err != NC_ECHAR) + EXPECT_ERR(NC_ECHAR, err) + ELSE_NOK + } + } + } } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); - check_vars_$1(scratch); + nok += check_vars_$1(scratch, numVars); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("delete file %s failed", scratch); + return nok; } ')dnl @@ -1097,64 +1378,74 @@ TEST_NC_PUT_VARM(longlong) TEST_NC_PUT_VARM(ulonglong) -void -test_nc_put_att_text(void) +int +TestFunc(att)_text(AttVarArgs) { - int ncid; - int i; - int j; - size_t k; - int err; + int i, j, err, ncid, nok=0; + IntType k, ndx[1]; text value[MAX_NELS]; - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; + err = FileCreate(scratch, NC_NOCLOBBER); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; } def_dims(ncid); - def_vars(ncid); + DefVars(ncid, numVars); + + /* check if can detect a bad file ID */ + err = PutAtt(text)(BAD_ID, 0, NULL, 0, NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutAtt(text)(ncid, BAD_VARID, NULL, 0, NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK { - const char *const tval = "value for bad name"; - const size_t tval_len = strlen(tval); - - err = nc_put_att_text(ncid, 0, "", tval_len, tval); - IF (err != NC_EBADNAME) - error("should be NC_EBADNAME: status = %d", err); + const char *const tval = "value for bad name"; + const IntType tval_len = (IntType)strlen(tval); + + err = PutAtt(text)(ncid, 0, "", tval_len, tval); + IF (err != NC_EBADNAME) + EXPECT_ERR(NC_EBADNAME, err) + ELSE_NOK } for (i = -1; i < numVars; i++) { for (j = 0; j < NATTS(i); j++) { if (ATT_TYPE(i,j) == NC_CHAR) { - assert(ATT_LEN(i,j) <= MAX_NELS); - err = nc_put_att_text(BAD_ID, i, ATT_NAME(i,j), ATT_LEN(i,j), - value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_att_text(ncid, BAD_VARID, ATT_NAME(i,j), - ATT_LEN(i,j), value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (k = 0; k < ATT_LEN(i,j); k++) { - value[k] = hash(ATT_TYPE(i,j), -1, &k); - } - err = nc_put_att_text(ncid, i, ATT_NAME(i,j), - ATT_LEN(i,j), value); - IF (err) { - error("%s", nc_strerror(err)); - } - } + assert(ATT_LEN(i,j) <= MAX_NELS); + + err = PutAtt(text)(ncid, BAD_VARID, ATT_NAME(i,j), ATT_LEN(i,j), value); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK + + for (k = 0; k < ATT_LEN(i,j); k++) { + ndx[0] = k; + double dtmp = hash(ATT_TYPE(i,j), -1, ndx); + value[k] = (text)dtmp; + } + err = PutAtt(text)(ncid, i, ATT_NAME(i,j), ATT_LEN(i,j), value); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + } } } - check_atts_text(ncid); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); + nok += check_atts_text(ncid, numGatts, numVars); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("delete file %s failed", scratch); + return nok; } @@ -1162,67 +1453,86 @@ dnl TEST_NC_PUT_ATT(TYPE) numeric only dnl define(`TEST_NC_PUT_ATT',dnl `dnl -void -test_nc_put_att_$1(void) +int +TestFunc(att)_$1(AttVarArgs) { - int ncid; - int i; - int j; - size_t k; - int err; - $1 value[MAX_NELS]; + int i, j, err, ncid, cdf_format, nok=0; int allInExtRange; /* all values within external range? */ + IntType k, ndx[1]; + $1 value[MAX_NELS]; - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; + err = FileCreate(scratch, NC_NOCLOBBER); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; } + + err = APIFunc(inq_format)(ncid, &cdf_format); + IF (err != NC_NOERR) + error("inq_format: %s", APIFunc(strerror)(err)); + def_dims(ncid); - def_vars(ncid); + DefVars(ncid, numVars); + + /* check if can detect a bad file ID */ + err = PutAtt($1)(BAD_ID, 0, NULL, 0, 0, NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutAtt($1)(ncid, BAD_VARID, NULL, 0, 0, NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK for (i = -1; i < numVars; i++) { for (j = 0; j < NATTS(i); j++) { if (!(ATT_TYPE(i,j) == NC_CHAR)) { - assert(ATT_LEN(i,j) <= MAX_NELS); - err = nc_put_att_$1(BAD_ID, i, ATT_NAME(i,j), ATT_TYPE(i,j), - ATT_LEN(i,j), value); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_att_$1(ncid, BAD_VARID, ATT_NAME(i,j), - ATT_TYPE(i,j), ATT_LEN(i,j), value); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - err = nc_put_att_$1(ncid, i, ATT_NAME(i,j), BAD_TYPE, - ATT_LEN(i,j), value); - IF (err != NC_EBADTYPE) - error("bad type: status = %d", err); - for (allInExtRange = 1, k = 0; k < ATT_LEN(i,j); k++) { - value[k] = hash_$1(ATT_TYPE(i,j), -1, &k, NCT_ITYPE($1)); - allInExtRange = allInExtRange - && inRange3(value[k], ATT_TYPE(i,j), NCT_ITYPE($1)); - } - err = nc_put_att_$1(ncid, i, ATT_NAME(i,j), ATT_TYPE(i,j), - ATT_LEN(i,j), value); - if (allInExtRange) { - IF (err) - error("%s", nc_strerror(err)); - } else { - IF (err != NC_ERANGE) - error("range error: status = %d", err); - } - } + assert(ATT_LEN(i,j) <= MAX_NELS); + + err = PutAtt($1)(ncid, BAD_VARID, ATT_NAME(i,j), ATT_TYPE(i,j), ATT_LEN(i,j), value); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK + + /* check if can detect a bad name */ + err = PutAtt($1)(ncid, i, NULL, 0, 0, NULL); + IF (err != NC_EBADNAME) + EXPECT_ERR(NC_EBADNAME, err) + ELSE_NOK + + err = PutAtt($1)(ncid, i, ATT_NAME(i,j), BAD_TYPE, ATT_LEN(i,j), value); + IF (err != NC_EBADTYPE) + EXPECT_ERR(NC_EBADTYPE, err) + ELSE_NOK + + for (allInExtRange = 1, k = 0; k < ATT_LEN(i,j); k++) { + ndx[0] = k; + value[k] = hash_$1(cdf_format,ATT_TYPE(i,j), -1, ndx, NCT_ITYPE($1)); + IfCheckTextChar($1, ATT_TYPE(i,j)) + allInExtRange &= inRange3(cdf_format, (double)value[k], ATT_TYPE(i,j), NCT_ITYPE($1)); + } + err = PutAtt($1)(ncid, i, ATT_NAME(i,j), ATT_TYPE(i,j), ATT_LEN(i,j), value); + if (allInExtRange) { + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + } + PNETCDF_CHECK_ERANGE($1) + } } } - check_atts_$1(ncid); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); + nok += check_atts_$1(ncid, numGatts, numVars); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("delete file %s failed", scratch); + return nok; } ')dnl diff --git a/nc_test/test_read.c b/nc_test/test_read.c deleted file mode 100644 index 96edad9589..0000000000 --- a/nc_test/test_read.c +++ /dev/null @@ -1,1613 +0,0 @@ -/********************************************************************* - * Copyright 1996, UCAR/Unidata - * See netcdf/COPYRIGHT file for copying and redistribution conditions. - * $Id: test_read.c 2792 2014-10-27 06:02:59Z wkliao $ - *********************************************************************/ - -#include "tests.h" - -/* - * Test nc_strerror. - * Try on a bad error status. - * Test for each defined error status. - */ -void -test_nc_strerror(void) -{ - int i; - const char *message; - - static const struct { - int status; - const char *msg; - } ncerrs[] = { - {NC_NOERR, "No error"}, - {NC_EBADID, "NetCDF: Not a valid ID"}, - {NC_ENFILE, "NetCDF: Too many files open"}, - {NC_EEXIST, "NetCDF: File exists && NC_NOCLOBBER"}, - {NC_EINVAL, "NetCDF: Invalid argument"}, - {NC_EPERM, "NetCDF: Write to read only"}, - {NC_ENOTINDEFINE, "NetCDF: Operation not allowed in data mode"}, - {NC_EINDEFINE, "NetCDF: Operation not allowed in define mode"}, - {NC_EINVALCOORDS, "NetCDF: Index exceeds dimension bound"}, - {NC_EMAXDIMS, "NetCDF: NC_MAX_DIMS exceeded"}, - {NC_ENAMEINUSE, "NetCDF: String match to name in use"}, - {NC_ENOTATT, "NetCDF: Attribute not found"}, - {NC_EMAXATTS, "NetCDF: NC_MAX_ATTRS exceeded"}, - {NC_EBADTYPE, "NetCDF: Not a valid data type or _FillValue type mismatch"}, - {NC_EBADDIM, "NetCDF: Invalid dimension ID or name"}, - {NC_EUNLIMPOS, "NetCDF: NC_UNLIMITED in the wrong index"}, - {NC_EMAXVARS, "NetCDF: NC_MAX_VARS exceeded"}, - {NC_ENOTVAR, "NetCDF: Variable not found"}, - {NC_EGLOBAL, "NetCDF: Action prohibited on NC_GLOBAL varid"}, - {NC_ENOTNC, "NetCDF: Unknown file format"}, - {NC_ESTS, "NetCDF: In Fortran, string too short"}, - {NC_EMAXNAME, "NetCDF: NC_MAX_NAME exceeded"}, - {NC_EUNLIMIT, "NetCDF: NC_UNLIMITED size already in use"}, - {NC_ENORECVARS, "NetCDF: nc_rec op when there are no record vars"}, - {NC_ECHAR, "NetCDF: Attempt to convert between text & numbers"}, - {NC_EEDGE, "NetCDF: Start+count exceeds dimension bound"}, - {NC_ESTRIDE, "NetCDF: Illegal stride"}, - {NC_EBADNAME, "NetCDF: Name contains illegal characters"}, - {NC_ERANGE, "NetCDF: Numeric conversion not representable"}, - {NC_ENOMEM, "NetCDF: Memory allocation (malloc) failure"}, - {NC_EVARSIZE, "NetCDF: One or more variable sizes violate format constraints"}, - {NC_EDIMSIZE, "NetCDF: Invalid dimension size"} - }; - - /* Try on a bad error status */ - /* Dmh: allow trailing extra info */ - message = nc_strerror(-666);/* should fail */ - IF (strncmp(message, "Unknown Error", strlen("Unknown Error")) != 0) - error("nc_strerror on bad error status returned: %s", message); - - /* Try on each legitimate error status */ - /* Dmh: allow trailing extra info */ - for (i=0; i> j) & 1) { - start[j] = 0; - edge[j] = mid[j]; - }else{ - start[j] = mid[j]; - edge[j] = var_shape[i][j] - mid[j]; - } - nels *= edge[j]; - } - if (var_rank[i] == 0 && i%2 ) - err = nc_get_vara(ncid, i, NULL, NULL, buf); - else - err = nc_get_vara(ncid, i, start, edge, buf); - IF (err) { - error("%s", nc_strerror(err)); - } else { - for (j = 0; j < nels; j++) { - p = (char *) buf; - p += j * nctypelen(var_type[i]); - err = nc2dbl( var_type[i], p, & got ); - IF (err) - error("error in nc2dbl"); - err = toMixedBase(j, var_rank[i], edge, index); - IF (err) - error("error in toMixedBase 1"); - for (d = 0; d < var_rank[i]; d++) - index[d] += start[d]; - expect = hash(var_type[i], var_rank[i], index); - if (inRange(expect,var_type[i])) { - IF (!equal(got,expect,var_type[i],NCT_DOUBLE)) { - error("value read not that expected"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("var_name: %s, ", var_name[i]); - error("element number: %d ", j); - error("expect: %g", expect); - error("got: %g", got); - } - } else { - nok++; - } - } - } - } - } - } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); -} - - -/* - * Test nc_get_vars - * Choose a random point dividing each dim into 2 parts - * Get 2^rank (nslabs) slabs so defined - * Each get overwrites buffer, so check after each get. - */ -void -test_nc_get_vars(void) -{ - int ncid; - int d; - int i; - int j; - int k; - int m; - int err; - int nels; - int nslabs; - int nstarts; /* number of different starts */ - int nok = 0; /* total count of valid comparisons */ - int n; /* count of valid comparisons within var */ - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t index2[MAX_RANK]; - size_t mid[MAX_RANK]; - size_t count[MAX_RANK]; - size_t sstride[MAX_RANK]; - ptrdiff_t stride[MAX_RANK]; - double buf[MAX_NELS]; /* (void *) buffer */ - char *p; /* (void *) pointer */ - double expect; - double got; - - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - for (i = 0; i < numVars; i++) { - assert(var_rank[i] <= MAX_RANK); - assert(var_nels[i] <= MAX_NELS); - for (j = 0; j < var_rank[i]; j++) { - start[j] = 0; - edge[j] = 1; - stride[j] = 1; - } - err = nc_get_vars(BAD_ID, i, start, edge, stride, buf); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_vars(ncid, BAD_VARID, start, edge, stride, buf); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - start[j] = var_shape[i][j]; - err = nc_get_vars(ncid, i, start, edge, stride, buf); - IF (err != NC_EINVALCOORDS) - error("bad index: status = %d", err); - start[j] = 0; - edge[j] = var_shape[i][j] + 1; - err = nc_get_vars(ncid, i, start, edge, stride, buf); - IF (err != NC_EEDGE) - error("bad edge: status = %d", err); - edge[j] = 1; - stride[j] = 0; - err = nc_get_vars(ncid, i, start, edge, stride, buf); - IF (err != NC_ESTRIDE) - error("bad stride: status = %d", err); - stride[j] = 1; - } - /* Choose a random point dividing each dim into 2 parts */ - /* get 2^rank (nslabs) slabs so defined */ - nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { - mid[j] = roll( var_shape[i][j] ); - nslabs *= 2; - } - /* bits of k determine whether to get lower or upper part of dim */ - /* choose random stride from 1 to edge */ - n = 0; - for (k = 0; k < nslabs; k++) { - nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { - if ((k >> j) & 1) { - start[j] = 0; - edge[j] = mid[j]; - }else{ - start[j] = mid[j]; - edge[j] = var_shape[i][j] - mid[j]; - } - sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; - nstarts *= stride[j]; - } - for (m = 0; m < nstarts; m++) { - err = toMixedBase(m, var_rank[i], sstride, index); - IF (err) - error("error in toMixedBase"); - nels = 1; - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / stride[j]; - nels *= count[j]; - index[j] += start[j]; - } - /* Random choice of forward or backward */ -/* TODO - if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { - index[j] += (count[j] - 1) * stride[j]; - stride[j] = -stride[j]; - } - } - */ - if (var_rank[i] == 0 && i%2 ) - err = nc_get_vars(ncid, i, NULL, NULL, NULL, buf); - else - err = nc_get_vars(ncid, i, index, count, stride, buf); - IF (err) { - error("%s", nc_strerror(err)); - } else { - for (j = 0; j < nels; j++) { - p = (char *) buf; - p += j * nctypelen(var_type[i]); - err = nc2dbl( var_type[i], p, & got ); - IF (err) - error("error in nc2dbl"); - err = toMixedBase(j, var_rank[i], count, index2); - IF (err) - error("error in toMixedBase 1"); - for (d = 0; d < var_rank[i]; d++) - index2[d] = index[d] + index2[d] * stride[d]; - expect = hash(var_type[i], var_rank[i], index2); - if (inRange(expect,var_type[i])) { - IF (!equal(got,expect,var_type[i],NCT_DOUBLE)) { - error("value read not that expected"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("var_name: %s, ", var_name[i]); - error("element number: %d ", j); - error("expect: %g, ", expect); - error("got: %g ", got); - } - } else { - nok++; - } - } - n++; - } - } - } - } - IF (n != var_nels[i]) { - error("count != nels"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("var_name: %s, ", var_name[i]); - error("count: %d, ", n); - error("nels: %d ", var_nels[i]); - } - } - } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); -} - - -/* - * Test nc_get_varm - * Choose a random point dividing each dim into 2 parts - * Get 2^rank (nslabs) slabs so defined - * Choose random stride from 1 to edge - * Buffer should end up being bit image of external variable. - * So all gets for a variable store in different elements of buffer - */ -void -test_nc_get_varm(void) -{ - int ncid; - int i; - int j; - int k; - int m; - int err; - int nslabs; - int nstarts; /* number of different starts */ - int nok = 0; /* total count of valid comparisons */ - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t mid[MAX_RANK]; - size_t count[MAX_RANK]; - size_t sstride[MAX_RANK]; - ptrdiff_t stride[MAX_RANK]; - ptrdiff_t imap[MAX_RANK]; - ptrdiff_t imap2[MAX_RANK]; - double buf[MAX_NELS]; /* (void *) buffer */ - char *p; /* (void *) pointer */ - double expect; - double got; - - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - for (i = 0; i < numVars; i++) { - assert(var_rank[i] <= MAX_RANK); - assert(var_nels[i] <= MAX_NELS); - for (j = 0; j < var_rank[i]; j++) { - start[j] = 0; - edge[j] = 1; - stride[j] = 1; - } - if (var_rank[i] > 0) { - j = var_rank[i] - 1; - /* imap[j] = nctypelen(var_type[i]); in bytes */ - imap[j] = 1; /* in numbers of elements */ - for (; j > 0; j--) - imap[j-1] = imap[j] * var_shape[i][j]; - } - err = nc_get_varm(BAD_ID, i, start, edge, stride, imap, buf); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_varm(ncid, BAD_VARID, start, edge, stride, imap, buf); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - start[j] = var_shape[i][j]; - err = nc_get_varm(ncid, i, start, edge, stride, imap, buf); - IF (err != NC_EINVALCOORDS) - error("bad index: status = %d", err); - start[j] = 0; - edge[j] = var_shape[i][j] + 1; - err = nc_get_varm(ncid, i, start, edge, stride, imap, buf); - IF (err != NC_EEDGE) - error("bad edge: status = %d", err); - edge[j] = 1; - stride[j] = 0; - err = nc_get_varm(ncid, i, start, edge, stride, imap, buf); - IF (err != NC_ESTRIDE) - error("bad stride: status = %d", err); - stride[j] = 1; - } - /* Choose a random point dividing each dim into 2 parts */ - /* get 2^rank (nslabs) slabs so defined */ - nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { - mid[j] = roll( var_shape[i][j] ); - nslabs *= 2; - } - /* bits of k determine whether to get lower or upper part of dim */ - /* choose random stride from 1 to edge */ - for (k = 0; k < nslabs; k++) { - nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { - if ((k >> j) & 1) { - start[j] = 0; - edge[j] = mid[j]; - }else{ - start[j] = mid[j]; - edge[j] = var_shape[i][j] - mid[j]; - } - sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; - imap2[j] = imap[j] * sstride[j]; - nstarts *= stride[j]; - } - for (m = 0; m < nstarts; m++) { - if (var_rank[i] == 0 && i%2 ) { - err = nc_get_varm(ncid, i, NULL, NULL, NULL, NULL, buf); - } else { - err = toMixedBase(m, var_rank[i], sstride, index); - IF (err) - error("error in toMixedBase"); - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / stride[j]; - index[j] += start[j]; - } - /* Random choice of forward or backward */ -/* TODO - if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { - index[j] += (count[j] - 1) * stride[j]; - stride[j] = -stride[j]; - } - } - */ - j = fromMixedBase(var_rank[i], index, var_shape[i]); - p = (char *) buf + j * nctypelen(var_type[i]); - err = nc_get_varm(ncid, i, index, count, stride, imap2, p); - } - IF (err) - error("%s", nc_strerror(err)); - } - } - p = (char *) buf; - for (j = 0; j < var_nels[i]; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase"); - expect = hash( var_type[i], var_rank[i], index); - err = nc2dbl( var_type[i], p, & got ); - IF (err) - error("error in nc2dbl"); - if (inRange(expect,var_type[i])) { - IF (!equal(got,expect,var_type[i],NCT_DOUBLE)) { - error("value read not that expected"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("var_name: %s, ", var_name[i]); - error("element number: %d ", j); - error("expect: %g, ", expect); - error("got: %g ", got); - } - } else { - nok++; - } - } - p += nctypelen(var_type[i]); - } - } - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); -} - - -void -test_nc_get_att(void) -{ - int ncid; - int i; - int j; - size_t k; - int err; - double buf[MAX_NELS]; /* (void *) buffer */ - signed char *p; /* (void *) pointer */ - double expect; - double got; - int nok = 0; /* count of valid comparisons */ - - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - - for (i = -1; i < numVars; i++) { - for (j = 0; j < NATTS(i); j++) { - err = nc_get_att(BAD_ID, i, ATT_NAME(i,j), buf); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_get_att(ncid, BAD_VARID, ATT_NAME(i,j), buf); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - err = nc_get_att(ncid, i, "noSuch", buf); - IF (err != NC_ENOTATT) - error("Bad attribute name: status = %d", err); - err = nc_get_att(ncid, i, ATT_NAME(i,j), buf); - IF (err) { - error("%s", nc_strerror(err)); - } else { - for (k = 0; k < ATT_LEN(i,j); k++) { - expect = hash(ATT_TYPE(i,j), -1, &k ); - p = (signed char *) buf; - p += k * nctypelen(ATT_TYPE(i,j)); - err = nc2dbl( ATT_TYPE(i,j), p, &got ); - IF (err) - error("error in nc2dbl"); - if (inRange(expect,ATT_TYPE(i,j))) { - IF (!equal(got,expect,ATT_TYPE(i,j),NCT_DOUBLE)) { - error("value read not that expected"); - if (verbose) { - error("\n"); - error("varid: %d, ", i); - error("var_name: %s, ", - i >= 0 ? var_name[i] : "Global"); - error("att_name: %s, ", ATT_NAME(i,j)); - error("element number: %d\n", k); - error("expect: %-23.16e\n", expect); - error(" got: %-23.16e", got); - } - } else { - nok++; - } - } - } - } - } - } - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - print_nok(nok); -} - - -void -test_nc_inq_att(void) -{ - int ncid; - int i; - int j; - int err; - nc_type t; - size_t n; - - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - - for (i = -1; i < numVars; i++) { - for (j = 0; j < NATTS(i); j++) { - err = nc_inq_att(BAD_ID, i, ATT_NAME(i,j), &t, &n); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_inq_att(ncid, BAD_VARID, ATT_NAME(i,j), &t, &n); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - err = nc_inq_att(ncid, i, "noSuch", &t, &n); - IF (err != NC_ENOTATT) - error("Bad attribute name: status = %d", err); - err = nc_inq_att(ncid, i, ATT_NAME(i,j), &t, &n); - IF (err) { - error("%s", nc_strerror(err)); - } else { - IF (t != ATT_TYPE(i,j)) - error("type not that expected"); - IF (n != ATT_LEN(i,j)) - error("length not that expected"); - } - } - } - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); -} - - -void -test_nc_inq_attlen(void) -{ - int ncid; - int i; - int j; - int err; - size_t len; - - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - - for (i = -1; i < numVars; i++) { - err = nc_inq_attlen(ncid, i, "noSuch", &len); - IF (err != NC_ENOTATT) - error("Bad attribute name: status = %d", err); - for (j = 0; j < NATTS(i); j++) { - err = nc_inq_attlen(BAD_ID, i, ATT_NAME(i,j), &len); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_inq_attlen(ncid, BAD_VARID, ATT_NAME(i,j), &len); - IF (err != NC_ENOTVAR) - error("bad varid: status = %d", err); - err = nc_inq_attlen(ncid, i, ATT_NAME(i,j), &len); - IF (err) { - error("%s", nc_strerror(err)); - } else { - IF (len != ATT_LEN(i,j)) - error("len not that expected"); - } - } - } - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); -} - - -void -test_nc_inq_atttype(void) -{ - int ncid; - int i; - int j; - int err; - nc_type datatype; - - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - - for (i = -1; i < numVars; i++) { - err = nc_inq_atttype(ncid, i, "noSuch", &datatype); - IF (err != NC_ENOTATT) - error("Bad attribute name: status = %d", err); - for (j = 0; j < NATTS(i); j++) { - err = nc_inq_atttype(BAD_ID, i, ATT_NAME(i,j), &datatype); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_inq_atttype(ncid, BAD_VARID, ATT_NAME(i,j), &datatype); - IF (err != NC_ENOTVAR) - error("bad varid: status = %d", err); - err = nc_inq_atttype(ncid, i, ATT_NAME(i,j), &datatype); - IF (err) { - error("%s", nc_strerror(err)); - } else { - IF (datatype != ATT_TYPE(i,j)) - error("type not that expected"); - } - } - } - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); -} - - -void -test_nc_inq_attname(void) -{ - int ncid; - int i; - int j; - int err; - char name[NC_MAX_NAME]; - - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - - for (i = -1; i < numVars; i++) { - err = nc_inq_attname(ncid, i, BAD_ATTNUM, name); - IF (err != NC_ENOTATT) - error("Bad attribute number: status = %d", err); - err = nc_inq_attname(ncid, i, NATTS(i), name); - IF (err != NC_ENOTATT) - error("Bad attribute number: status = %d", err); - for (j = 0; j < NATTS(i); j++) { - err = nc_inq_attname(BAD_ID, i, j, name); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_inq_attname(ncid, BAD_VARID, j, name); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - err = nc_inq_attname(ncid, i, j, name); - IF (err) { - error("%s", nc_strerror(err)); - } else { - IF (strcmp(ATT_NAME(i,j), name) != 0) - error("name not that expected"); - } - } - } - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); -} - - -void -test_nc_inq_attid(void) -{ - int ncid; - int i; - int j; - int err; - int attnum; - - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - - for (i = -1; i < numVars; i++) { - err = nc_inq_attid(ncid, i, "noSuch", &attnum); - IF (err != NC_ENOTATT) - error("Bad attribute name: status = %d", err); - for (j = 0; j < NATTS(i); j++) { - err = nc_inq_attid(BAD_ID, i, ATT_NAME(i,j), &attnum); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_inq_attid(ncid, BAD_VARID, ATT_NAME(i,j), &attnum); - IF (err != NC_ENOTVAR) - error("bad varid: status = %d", err); - err = nc_inq_attid(ncid, i, ATT_NAME(i,j), &attnum); - IF (err) { - error("%s", nc_strerror(err)); - } else { - IF (attnum != j) - error("attnum not that expected"); - } - } - } - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); -} diff --git a/nc_test/test_read.m4 b/nc_test/test_read.m4 new file mode 100644 index 0000000000..a091b3fe7e --- /dev/null +++ b/nc_test/test_read.m4 @@ -0,0 +1,2054 @@ +dnl This is m4 source. +dnl Process using m4 to produce 'C' language file. +dnl +dnl This file is supposed to be the same as PnetCDF's test_read.m4 +dnl +dnl If you see this line, you can ignore the next one. +/* Do not edit this file. It is produced from the corresponding .m4 source */ +dnl +/* + * Copyright (C) 2003, Northwestern University and Argonne National Laboratory + * See COPYRIGHT notice in top-level directory. + */ +/* $Id: test_read.m4 2861 2017-02-09 19:38:02Z wkliao $ */ + +dnl +dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF +dnl in terms of function prefix names (ncmpi_ vs. nc_), integer data types +dnl (MPI_Offset vs. size_t), and function name substrings for external data +dnl types. +dnl + +#if defined (_WIN32) || defined (_WIN64) +#include +#endif + +#include /* open() */ +#include /* open() */ +#include /* open() */ +#ifdef _MSC_VER +#include +#else +#include /* unlink(), write() */ +#endif +#include /* errno, strerror() */ + +#include "tests.h" + +define(`EXPECT_ERR',`error("expecting $1 but got %s",nc_err_code_name($2));')dnl + +define(`IntType', `ifdef(`PNETCDF',`MPI_Offset',`size_t')')dnl +define(`PTRDType',`ifdef(`PNETCDF',`MPI_Offset',`ptrdiff_t')')dnl +define(`TestFunc',`ifdef(`PNETCDF',`test_ncmpi_$1',`test_nc_$1')')dnl +define(`APIFunc',` ifdef(`PNETCDF',`ncmpi_$1',`nc_$1')')dnl + +define(`FileOpen', `ifdef(`PNETCDF',`ncmpi_open(comm, $1, $2, info, $3)', `file_open($1, $2, $3)')')dnl +define(`FileCreate',`ifdef(`PNETCDF',`ncmpi_create(comm, $1, $2, info, $3)', `file_create($1, $2, $3)')')dnl +define(`FileDelete',`ifdef(`PNETCDF',`ncmpi_delete($1,$2)',`nc_delete($1)')')dnl + +define(`VarArgs', `ifdef(`PNETCDF',`int numVars',`void')')dnl +define(`AttArgs', `ifdef(`PNETCDF',`int numGatts',`void')')dnl +define(`AttVarArgs',`ifdef(`PNETCDF',`int numGatts, int numVars',`void')')dnl + +define(`GetVar1', `ifdef(`PNETCDF',`ncmpi_get_var1_all($1,$2,$3,$4,$5,$6)', `nc_get_var1($1,$2,$3,$4)')')dnl +define(`GetVar', `ifdef(`PNETCDF',`ncmpi_get_var_all( $1,$2,$3,$4,$5)', `nc_get_var( $1,$2,$3)')')dnl +define(`GetVara', `ifdef(`PNETCDF',`ncmpi_get_vara_all($1,$2,$3,$4,$5,$6,$7)', `nc_get_vara($1,$2,$3,$4,$5)')')dnl +define(`GetVars', `ifdef(`PNETCDF',`ncmpi_get_vars_all($1,$2,$3,$4,$5,$6,$7,$8)', `nc_get_vars($1,$2,$3,$4,$5,$6)')')dnl +define(`GetVarm', `ifdef(`PNETCDF',`ncmpi_get_varm_all($1,$2,$3,$4,$5,$6,$7,$8,$9)', `nc_get_varm($1,$2,$3,$4,$5,$6,$7)')')dnl + +/* + * Test APIFunc(strerror). + * Try on a bad error status. + * Test for each defined error status. + */ +int +TestFunc(strerror)(void) +{ + int i; + const char *message, *expected_msg; + int nok=0; + + static const struct { + int status; + const char *msg; + } ncerrs[] = { + {NC_NOERR, "No error"}, + {NC_EBADID, "NetCDF: Not a valid ID"}, + {NC_ENFILE, "NetCDF: Too many files open"}, + {NC_EEXIST, "NetCDF: File exists && NC_NOCLOBBER"}, + {NC_EINVAL, "NetCDF: Invalid argument"}, + {NC_EPERM, "NetCDF: Write to read only"}, + {NC_ENOTINDEFINE, "NetCDF: Operation not allowed in data mode"}, + {NC_EINDEFINE, "NetCDF: Operation not allowed in define mode"}, + {NC_EINVALCOORDS, "NetCDF: Index exceeds dimension bound"}, + {NC_EMAXDIMS, "NetCDF: NC_MAX_DIMS exceeded"}, + {NC_ENAMEINUSE, "NetCDF: String match to name in use"}, + {NC_ENOTATT, "NetCDF: Attribute not found"}, + {NC_EMAXATTS, "NetCDF: NC_MAX_ATTRS exceeded"}, + {NC_EBADTYPE, "NetCDF: Not a valid data type or _FillValue type mismatch"}, + {NC_EBADDIM, "NetCDF: Invalid dimension ID or name"}, + {NC_EUNLIMPOS, "NetCDF: NC_UNLIMITED in the wrong index"}, + {NC_EMAXVARS, "NetCDF: NC_MAX_VARS exceeded"}, + {NC_ENOTVAR, "NetCDF: Variable not found"}, + {NC_EGLOBAL, "NetCDF: Action prohibited on NC_GLOBAL varid"}, + {NC_ENOTNC, "NetCDF: Unknown file format"}, + {NC_ESTS, "NetCDF: In Fortran, string too short"}, + {NC_EMAXNAME, "NetCDF: NC_MAX_NAME exceeded"}, + {NC_EUNLIMIT, "NetCDF: NC_UNLIMITED size already in use"}, + {NC_ENORECVARS, "NetCDF: nc_rec op when there are no record vars"}, + {NC_ECHAR, "NetCDF: Attempt to convert between text & numbers"}, + {NC_EEDGE, "NetCDF: Start+count exceeds dimension bound"}, + {NC_ESTRIDE, "NetCDF: Illegal stride"}, + {NC_EBADNAME, "NetCDF: Name contains illegal characters"}, + {NC_ERANGE, "NetCDF: Numeric conversion not representable"}, + {NC_ENOMEM, "NetCDF: Memory allocation (malloc) failure"}, + {NC_EVARSIZE, "NetCDF: One or more variable sizes violate format constraints"}, + {NC_EDIMSIZE, "NetCDF: Invalid dimension size"} + }; + + /* Try on a bad error status */ + message = APIFunc(strerror)(-666);/* should fail */ + expected_msg = "Unknown Error"; + IF (strncmp(message, expected_msg, strlen(expected_msg)) != 0) + error("APIFunc(strerror) on bad error status returned: %s", message); + ELSE_NOK + + /* Try on each legitimate error status */ + for (i=0; i= 0); + close(fd); + } + + /* Open a file that is not a netCDF file. */ + err = FileOpen(NOT_NC_FILE, NC_NOWRITE, &ncid); /* should fail */ + IF (err != NC_ENOTNC) + error("expecting NC_ENOTNC or NC_EFILE but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* delete the not-nc file */ + unlink(NOT_NC_FILE); +#endif + + /* Open a netCDF file in read-only mode, check that write fails */ + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(redef)(ncid); /* should fail */ + IF (err != NC_EPERM) + error("expecting NC_EPERM but got %s", nc_err_code_name(err)); + /* Opened OK, see if can open again and get a different netCDF ID */ + err = FileOpen(testfile, NC_NOWRITE, &ncid2); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + else { + APIFunc(close)(ncid2); + nok++; + } + IF (ncid2 == ncid) + error("netCDF IDs for first and second open calls should differ"); + + ifdef(`PNETCDF', `if (! read_only)') + { /* tests using netCDF scratch file */ + err = FileCreate(scratch, NC_NOCLOBBER, &ncid2); + IF (err != NC_NOERR) + error("create: %s", APIFunc(strerror)(err)); + else + APIFunc(close)(ncid2); + err = FileOpen(scratch, NC_WRITE, &ncid2); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + else { + APIFunc(close)(ncid2); + nok++; + } + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +/* + * Test APIFunc(close). + * Try to close a netCDF file twice, check whether second close fails. + * Try on bad handle, check error return. + * Try in define mode and data mode. + */ +int +TestFunc(close)(void) +{ + int ncid, nok=0; + int err = FileOpen(testfile, NC_NOWRITE, &ncid); + + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + /* Close a netCDF file twice, second time should fail */ + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close failed: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* Try with a bad netCDF ID */ + err = APIFunc(close)(BAD_ID);/* should fail */ + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* Close in data mode */ + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close in data mode failed: %s", APIFunc(strerror)(err)); + ELSE_NOK + + ifdef(`PNETCDF', `if (! read_only)') + { /* tests using netCDF scratch file */ + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) + error("create: %s", APIFunc(strerror)(err)); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close in define mode: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + } + return nok; +} + + +/* + * Test APIFunc(inq) + * Try on bad handle, check error return. + * Try in data mode, check returned values. + * Try asking for subsets of info. + * If in writable section of tests, + * Try in define mode, after adding an unlimited dimension, variable. + * On exit, any open netCDF files are closed. + */ +int +TestFunc(inq)(AttVarArgs) +{ + int ncid; + int ndims; /* number of dimensions */ + int nvars; /* number of variables */ + int ngatts; /* number of global attributes */ + int recdim; /* id of unlimited dimension */ + int err; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + /* Try on bad handle */ + err = APIFunc(inq)(BAD_ID, 0, 0, 0, 0); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + + err = APIFunc(inq)(ncid, &ndims, &nvars, &ngatts, &recdim); + IF (err != NC_NOERR) + error("inq: %s", APIFunc(strerror)(err)); + else IF (ndims != NDIMS) + error("inq: wrong number of dimensions returned, %d", ndims); + else IF (nvars != numVars) + error("inq: wrong number of variables returned, %d", nvars); + else IF (ngatts != numGatts) + error("inq: wrong number of global atts returned, %d", ngatts); + else IF (recdim != RECDIM) + error("inq: wrong record dimension ID returned, %d", recdim); + ELSE_NOK + + /* Inguire for no info (useless, but should still work) */ + err = APIFunc(inq)(ncid, 0, 0, 0, 0); + IF (err != NC_NOERR) + error("inq for no info failed: %s", APIFunc(strerror)(err)); + ELSE_NOK + + /* Inguire for subsets of info */ + ngatts = numGatts - 1; /* wipe out previous correct value */ + err = APIFunc(inq)(ncid, 0, 0, &ngatts, 0); + IF (err != NC_NOERR) + error("inq for one item failed: %s", APIFunc(strerror)(err)); + else IF (ngatts != numGatts) + error("inq subset: wrong number of global atts returned, %d", ngatts); + ELSE_NOK + ndims = NDIMS - 1; + nvars = numVars - 1; + err = APIFunc(inq)(ncid, &ndims, &nvars, 0, 0); + IF (err != NC_NOERR) + error("inq for two items failed: %s", APIFunc(strerror)(err)); + else IF (ndims != NDIMS) + error("inq subset: wrong number of dimensions returned, %d", ndims); + else IF (nvars != numVars) + error("inq subset: wrong number of variables returned, %d", nvars); + ELSE_NOK + + ifdef(`PNETCDF', `if (! read_only)') + { /* tests using netCDF scratch file */ + int ncid2; /* for scratch netCDF dataset */ + + err = FileCreate(scratch, NC_NOCLOBBER, &ncid2); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + } else { /* add dim, var, gatt, check inq */ + int ndims0; + int nvars0; + int ngatts0; + int recdim0; + err = APIFunc(enddef)(ncid2); /* enter data mode */ + err = APIFunc(inq)(ncid2, &ndims0, &nvars0, &ngatts0, &recdim0); + IF (err != NC_NOERR) + error("inq: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(redef)(ncid2); /* enter define mode */ + /* Check that inquire still works in define mode */ + err = APIFunc(inq)(ncid2, &ndims, &nvars, &ngatts, &recdim); + IF (err != NC_NOERR) + error("inq in define mode: %s", APIFunc(strerror)(err)); + else IF (ndims != ndims0) + error("inq in define mode: ndims wrong, %d", ndims); + else IF (nvars != nvars0) + error("inq in define mode: nvars wrong, %d", nvars); + else IF (ngatts != ngatts0) + error("inq in define mode: ngatts wrong, %d", ngatts); + else IF (recdim != recdim0) + error("inq in define mode: recdim wrong, %d", recdim); + ELSE_NOK + + { + int did, vid; + /* Add dim, var, global att */ + err = APIFunc(def_dim)(ncid2, "inqd", 1L, &did); + IF (err != NC_NOERR) + error("def_dim: %s", APIFunc(strerror)(err)); + err = APIFunc(def_var)(ncid2, "inqv", NC_FLOAT, 0, 0, &vid); + IF (err != NC_NOERR) + error("def_var: %s", APIFunc(strerror)(err)); + } + err = APIFunc(put_att_text)(ncid2, NC_GLOBAL, "inqa", 1+strlen("stuff"), + "stuff"); + IF (err != NC_NOERR) + error("put_att_text: %s", APIFunc(strerror)(err)); + + /* Make sure APIFunc(inq) sees the additions while in define mode */ + err = APIFunc(inq)(ncid2, &ndims, &nvars, &ngatts, &recdim); + IF (err != NC_NOERR) + error("inq in define mode: %s", APIFunc(strerror)(err)); + else IF (ndims != ndims0 + 1) + error("inq in define mode: ndims wrong, %d", ndims); + else IF (nvars != nvars0 + 1) + error("inq in define mode: nvars wrong, %d", nvars); + else IF (ngatts != ngatts0 + 1) + error("inq in define mode: ngatts wrong, %d", ngatts); + ELSE_NOK + err = APIFunc(enddef)(ncid2); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* Make sure APIFunc(inq) stills sees additions in data mode */ + err = APIFunc(inq)(ncid2, &ndims, &nvars, &ngatts, &recdim); + IF (err != NC_NOERR) + error("inq failed in data mode: %s", APIFunc(strerror)(err)); + else IF (ndims != ndims0 + 1) + error("inq in define mode: ndims wrong, %d", ndims); + else IF (nvars != nvars0 + 1) + error("inq in define mode: nvars wrong, %d", nvars); + else IF (ngatts != ngatts0 + 1) + error("inq in define mode: ngatts wrong, %d", ngatts); + ELSE_NOK + APIFunc(close)(ncid2); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + } + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_natts)(AttArgs) +{ + int ncid; + int ngatts; /* number of global attributes */ + int err, nok=0; + + err = APIFunc(inq_natts)(BAD_ID, &ngatts); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(inq_natts)(ncid, &ngatts); + IF (err != NC_NOERR) + error("inq_natts: %s", APIFunc(strerror)(err)); + else IF (ngatts != numGatts) + error("inq_natts: wrong number of global atts returned, %d", ngatts); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_ndims)(void) +{ + int ncid; + int ndims; + int err; + int nok=0; + + err = APIFunc(inq_ndims)(BAD_ID, &ndims); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(inq_ndims)(ncid, &ndims); + IF (err != NC_NOERR) + error("inq_ndims: %s", APIFunc(strerror)(err)); + else IF (ndims != NDIMS) + error("inq_ndims: wrong number returned, %d", ndims); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_nvars)(VarArgs) +{ + int ncid; + int nvars; + int err; + int nok=0; + + err = APIFunc(inq_nvars)(BAD_ID, &nvars); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(inq_nvars)(ncid, &nvars); + IF (err != NC_NOERR) + error("inq_nvars: %s", APIFunc(strerror)(err)); + else IF (nvars != numVars) + error("inq_nvars: wrong number returned, %d", nvars); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_unlimdim)(void) +{ + int ncid; + int unlimdim; + int err; + int nok=0; + + err = APIFunc(inq_unlimdim)(BAD_ID, &unlimdim); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(inq_unlimdim)(ncid, &unlimdim); + IF (err != NC_NOERR) + error("inq_unlimdim: %s", APIFunc(strerror)(err)); + else IF (unlimdim != RECDIM) + error("inq_unlimdim: wrong number returned, %d", unlimdim); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_dimid)(void) +{ + int ncid; + int dimid; + int i; + int err; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(inq_dimid)(ncid, "noSuch", &dimid); + IF (err != NC_EBADDIM) + error("expecting NC_EBADDIM but got %s", nc_err_code_name(err)); + ELSE_NOK + for (i = 0; i < NDIMS; i++) { + err = APIFunc(inq_dimid)(BAD_ID, dim_name[i], &dimid); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_dimid)(ncid, dim_name[i], &dimid); + IF (err != NC_NOERR) + error("inq_dimid: %s", APIFunc(strerror)(err)); + else IF (dimid != i) + error("expected %d, got %d", i, dimid); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_dim)(void) +{ + int ncid; + int i; + int err; + char name[NC_MAX_NAME]; + IntType length; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = 0; i < NDIMS; i++) { + err = APIFunc(inq_dim)(BAD_ID, i, name, &length); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_dim)(ncid, BAD_DIMID, name, &length); + IF (err != NC_EBADDIM) + error("expecting NC_EBADDIM but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_dim)(ncid, i, 0, 0); + IF (err != NC_NOERR) + error("inq_dim: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(inq_dim)(ncid, i, name, &length); + IF (err != NC_NOERR) + error("inq_dim: %s", APIFunc(strerror)(err)); + else IF (strcmp(dim_name[i],name)) + error("name expected: %s, got: %s",dim_name[i],name); + else IF (dim_len[i] != length) + error("size expected: %d, got: %d",dim_len[i],length); + ELSE_NOK + err = APIFunc(inq_dim)(ncid, i, name, 0); + IF (err != NC_NOERR) + error("inq_dim: %s", APIFunc(strerror)(err)); + else IF (strcmp(dim_name[i],name)) + error("name expected: %s, got: %s",dim_name[i],name); + ELSE_NOK + err = APIFunc(inq_dim)(ncid, i, 0, &length); + IF (err != NC_NOERR) + error("inq_dim: %s", APIFunc(strerror)(err)); + else IF (dim_len[i] != length) + error("size expected: %d, got: %d",dim_len[i],length); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_dimlen)(void) +{ + int ncid; + int i; + int err; + IntType length; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = 0; i < NDIMS; i++) { + err = APIFunc(inq_dimlen)(BAD_ID, i, &length); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_dimlen)(ncid, BAD_DIMID, &length); + IF (err != NC_EBADDIM) + error("expecting NC_EBADDIM but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_dimlen)(ncid, i, &length); + IF (err != NC_NOERR) + error("inq_dimlen: %s", APIFunc(strerror)(err)); + else IF (dim_len[i] != length) + error("size expected: %d, got: %d",dim_len[i],length); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_dimname)(void) +{ + int ncid; + int i; + int err; + char name[NC_MAX_NAME]; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = 0; i < NDIMS; i++) { + err = APIFunc(inq_dimname)(BAD_ID, i, name); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_dimname)(ncid, BAD_DIMID, name); + IF (err != NC_EBADDIM) + error("expecting NC_EBADDIM but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_dimname)(ncid, i, name); + IF (err != NC_NOERR) + error("inq_dimname: %s", APIFunc(strerror)(err)); + else IF (strcmp(dim_name[i],name)) + error("name expected: %s, got: %s",dim_name[i],name); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_varid)(VarArgs) +{ + int ncid; + int varid; + int i; + int err; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + err = APIFunc(inq_varid)(ncid, "noSuch", &varid); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + + for (i = 0; i < numVars; i++) { + err = APIFunc(inq_varid)(BAD_ID, var_name[i], &varid); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_varid)(ncid, var_name[i], &varid); + IF (err != NC_NOERR) + error("inq_varid: %s", APIFunc(strerror)(err)); + else IF (varid != i) + error("expected %d, got %d", i, varid); + ELSE_NOK + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_var)(VarArgs) +{ + int ncid; + int i; + int err; + char name[NC_MAX_NAME]; + nc_type datatype; + int ndims; + int dimids[MAX_RANK]; + int natts; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = 0; i < numVars; i++) { + err = APIFunc(inq_var)(BAD_ID, i, name, &datatype, &ndims, dimids, &natts); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_var)(ncid,BAD_VARID,name,&datatype,&ndims,dimids,&natts); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_var)(ncid, i, 0, 0, 0, 0, 0); + IF (err != NC_NOERR) + error("inq_var: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(inq_var)(ncid, i, name, &datatype, &ndims, dimids, &natts); + IF (err != NC_NOERR) + error("inq_var: %s", APIFunc(strerror)(err)); + else IF (strcmp(var_name[i],name)) + error("name expected: %s, got: %s",var_name[i],name); + else IF (var_type[i] != datatype) + error("type expected: %d, got: %d",var_type[i],datatype); + else IF (var_rank[i] != ndims) + error("ndims expected: %d, got: %d",var_rank[i],ndims); + else IF (!int_vec_eq(var_dimid[i],dimids,ndims)) + error("unexpected dimid"); + else IF (var_natts[i] != natts) + error("natts expected: %d, got: %d",var_natts[i],natts); + ELSE_NOK + err = APIFunc(inq_var)(ncid, i, name, 0, 0, 0, 0); + IF (err != NC_NOERR) + error("inq_var: %s", APIFunc(strerror)(err)); + else IF (strcmp(var_name[i],name)) + error("name expected: %s, got: %s",var_name[i],name); + ELSE_NOK + err = APIFunc(inq_var)(ncid, i, 0, &datatype, 0, 0, 0); + IF (err != NC_NOERR) + error("inq_var: %s", APIFunc(strerror)(err)); + else IF (var_type[i] != datatype) + error("type expected: %d, got: %d",var_type[i],datatype); + ELSE_NOK + err = APIFunc(inq_var)(ncid, i, 0, 0, &ndims, 0, 0); + IF (err != NC_NOERR) + error("inq_var: %s", APIFunc(strerror)(err)); + else IF (var_rank[i] != ndims) + error("ndims expected: %d, got: %d",var_rank[i],ndims); + ELSE_NOK + err = APIFunc(inq_var)(ncid, i, 0, 0, 0, dimids, 0); + IF (err != NC_NOERR) + error("inq_var: %s", APIFunc(strerror)(err)); + else IF (!int_vec_eq(var_dimid[i],dimids,ndims)) + error("unexpected dimid"); + ELSE_NOK + err = APIFunc(inq_var)(ncid, i, 0, 0, 0, 0, &natts); + IF (err != NC_NOERR) + error("inq_var: %s", APIFunc(strerror)(err)); + else IF (var_natts[i] != natts) + error("natts expected: %d, got: %d",var_natts[i],natts); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_vardimid)(VarArgs) +{ + int ncid; + int i; + int err; + int dimids[MAX_RANK]; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = 0; i < numVars; i++) { + err = APIFunc(inq_vardimid)(BAD_ID, i, dimids); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_vardimid)(ncid, BAD_VARID, dimids); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_vardimid)(ncid, i, dimids); + IF (err != NC_NOERR) + error("inq_vardimid: %s", APIFunc(strerror)(err)); + else IF (!int_vec_eq(var_dimid[i], dimids, var_rank[i])) + error("unexpected dimid"); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_varname)(VarArgs) +{ + int ncid; + int i; + int err; + char name[NC_MAX_NAME]; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = 0; i < numVars; i++) { + err = APIFunc(inq_varname)(BAD_ID, i, name); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + nok++; + err = APIFunc(inq_varname)(ncid, BAD_VARID, name); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_varname)(ncid, i, name); + IF (err != NC_NOERR) + error("inq_varname: %s", APIFunc(strerror)(err)); + else IF (strcmp(var_name[i],name)) + error("name expected: %s, got: %s",var_name[i],name); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_varnatts)(AttVarArgs) +{ + int ncid; + int i; + int err; + int natts; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = -1; i < numVars; i++) { + err = APIFunc(inq_varnatts)(BAD_ID, i, &natts); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_varnatts)(ncid, BAD_VARID, &natts); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_varnatts)(ncid, VARID(i), &natts); + IF (err != NC_NOERR) + error("inq_varnatts: %s", APIFunc(strerror)(err)); + else IF (NATTS(i) != natts) + error("natts expected: %d, got: %d",NATTS(i),natts); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_varndims)(VarArgs) +{ + int ncid; + int i; + int err; + int ndims; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = 0; i < numVars; i++) { + err = APIFunc(inq_varndims)(BAD_ID, i, &ndims); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_varndims)(ncid, BAD_VARID, &ndims); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_varndims)(ncid, i, &ndims); + IF (err != NC_NOERR) + error("inq_varndims: %s", APIFunc(strerror)(err)); + else IF (var_rank[i] != ndims) + error("ndims expected: %d, got: %d",var_rank[i],ndims); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_vartype)(VarArgs) +{ + int ncid; + int i; + int err; + nc_type datatype; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = 0; i < numVars; i++) { + err = APIFunc(inq_vartype)(BAD_ID, i, &datatype); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_vartype)(ncid, BAD_VARID, &datatype); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_vartype)(ncid, i, &datatype); + IF (err != NC_NOERR) + error("inq_vartype: %s", APIFunc(strerror)(err)); + else IF (var_type[i] != datatype) + error("type expected: %d, got: %d", var_type[i], datatype); + ELSE_NOK + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +/* + * Test GetVar1 + */ +int +TestFunc(get_var1)(VarArgs) +{ + int ncid; + int i; + int err; + double expect; + int nok = 0; /* count of valid comparisons */ + double buf[1]; /* (void *) buffer */ + double value[1]; + IntType j, index[MAX_RANK]; + ifdef(`PNETCDF', `MPI_Datatype datatype;') + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = GetVar1(BAD_ID, 0, NULL, NULL, 0, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) EXPECT_ERR(NC_EBADID, err) + + /* check if can detect a bad variable ID */ + err = GetVar1(ncid, BAD_VARID, NULL, NULL, 0, MPI_DATATYPE_NULL); + IF (err != NC_ENOTVAR) EXPECT_ERR(NC_ENOTVAR, err) + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + /* check if can detect a bad file ID */ + err = GetVar1(BAD_ID, i, NULL, value, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') + +ifdef(`PNETCDF',`dnl + err = GetVar1(ncid, i, NULL, value, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK +')dnl + + /* test NC_EINVALCOORDS */ + for (j = 0; j < var_rank[i]; j++) { + index[j] = var_shape[i][j]; + err = GetVar1(ncid, i, index, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + index[j] = 0; + } + err = GetVar1(ncid, i, index, value, 1, datatype); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + + /* check if the contents are supposed to be */ + for (j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + expect = hash( var_type[i], var_rank[i], index ); + err = GetVar1(ncid, i, index, buf, 1, datatype); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + err = nc2dbl( var_type[i], buf, &value[0]); + IF (err) + error("error in nc2dbl"); + if (inRange(expect,var_type[i])) { + IF (!equal2(value[0],expect,var_type[i])) + error("expected: %G, got: %G", expect, value[0]); + ELSE_NOK + } + } + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +/* + * Test GetVara + * Choose a random point dividing each dim into 2 parts + * Get 2^rank (nslabs) slabs so defined + * Each get overwrites buffer, so check after each get. + */ +int +TestFunc(get_vara)(VarArgs) +{ + int ncid, d, i, k, err, nslabs; + int nok = 0; /* count of valid comparisons */ + IntType j, nels; + IntType start[MAX_RANK]; + IntType edge[MAX_RANK]; + IntType index[MAX_RANK]; + IntType mid[MAX_RANK]; + ifdef(`PNETCDF', `MPI_Datatype datatype;') + double buf[MAX_NELS]; /* (void *) buffer */ + double expect; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = GetVara(BAD_ID, 0, NULL, NULL, NULL, 0, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) EXPECT_ERR(NC_EBADID, err) + + /* check if can detect a bad variable ID */ + err = GetVara(ncid, BAD_VARID, NULL, NULL, NULL, 0, MPI_DATATYPE_NULL); + IF (err != NC_ENOTVAR) EXPECT_ERR(NC_ENOTVAR, err) + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + /* check if can detect a bad file ID */ + err = GetVara(BAD_ID, i, NULL, NULL, buf, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') + + for (j = 0; j < var_rank[i]; j++) { + start[j] = 0; + edge[j] = 1; + } + +ifdef(`PNETCDF',`dnl + err = GetVara(ncid, i, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + err = GetVara(ncid, i, start, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EEDGE) { + EXPECT_ERR(NC_EEDGE, err) + } + ELSE_NOK +')dnl + + /* test NC_EINVALCOORDS, first when edge[*] > 0 */ + for (j = 0; j < var_rank[i]; j++) { + index[j] = var_shape[i][j]; + err = GetVara(ncid, i, index, edge, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + index[j] = 0; + edge[j] = var_shape[i][j] + 1; /* edge error check */ + err = GetVara(ncid, i, start, edge, buf, 1, datatype); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDGE, err) + ELSE_NOK + edge[j] = 1; + } + + /* Check non-scalars for correct error returned even when there is + * nothing to get (edge[j]==0) */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = GetVara(ncid, i, start, edge, buf, 0, datatype); +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + ELSE_NOK + start[j] = var_shape[i][j]+1; /* out of boundary check */ + err = GetVara(ncid, i, start, edge, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + err = GetVara(ncid, i, start, edge, buf, 1, datatype); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + + /* Choose a random point dividing each dim into 2 parts */ + /* get 2^rank (nslabs) slabs so defined */ + nslabs = 1; + for (j = 0; j < var_rank[i]; j++) { + mid[j] = roll( var_shape[i][j] ); + nslabs *= 2; + } + /* bits of k determine whether to get lower or upper part of dim */ + for (k = 0; k < nslabs; k++) { + nels = 1; + for (j = 0; j < var_rank[i]; j++) { + if ((k >> j) & 1) { + start[j] = 0; + edge[j] = mid[j]; + }else{ + start[j] = mid[j]; + edge[j] = var_shape[i][j] - mid[j]; + } + nels *= edge[j]; + } + err = GetVara(ncid, i, start, edge, buf, nels, datatype); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + + for (j = 0; j < nels; j++) { + double got; + char *p = (char *) buf; + p += j * (IntType)nctypelen(var_type[i]); + err = nc2dbl( var_type[i], p, & got ); + IF (err) error("error in nc2dbl"); + err = toMixedBase(j, var_rank[i], edge, index); + IF (err != 0) error("error in toMixedBase"); + for (d = 0; d < var_rank[i]; d++) + index[d] += start[d]; + expect = hash(var_type[i], var_rank[i], index); + if (inRange(expect,var_type[i])) { + IF (!equal2(got,expect,var_type[i])) { + error("buf read not that expected"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("var_name: %s, ", var_name[i]); + error("element number: %d ", j); + error("expect: %g", expect); + error("got: %g", got); + } + } + } + } + } + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +/* + * Test GetVars + * Choose a random point dividing each dim into 2 parts + * Get 2^rank (nslabs) slabs so defined + * Each get overwrites buffer, so check after each get. + */ +int +TestFunc(get_vars)(VarArgs) +{ + int ncid; + int d; + int i; + int k; + int err; + int nslabs; + PTRDType nstarts; /* number of different starts */ + int nok = 0; /* total count of valid comparisons */ + int n; /* count of valid comparisons within var */ + IntType j, m, nels; + IntType start[MAX_RANK]; + IntType edge[MAX_RANK]; + IntType index[MAX_RANK]; + IntType index2[MAX_RANK]; + IntType mid[MAX_RANK]; + IntType count[MAX_RANK]; + IntType sstride[MAX_RANK]; + PTRDType stride[MAX_RANK]; + ifdef(`PNETCDF', `MPI_Datatype datatype;') + double buf[MAX_NELS]; /* (void *) buffer */ + char *p; /* (void *) pointer */ + double expect; + double got; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = GetVars(BAD_ID, 0, NULL, NULL, NULL, NULL, 0, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) EXPECT_ERR(NC_EBADID, err) + + /* check if can detect a bad variable ID */ + err = GetVars(ncid, BAD_VARID, NULL, NULL, NULL, NULL, 0, MPI_DATATYPE_NULL); + IF (err != NC_ENOTVAR) EXPECT_ERR(NC_ENOTVAR, err) + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + /* check if can detect a bad file ID */ + err = GetVars(BAD_ID, i, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') + + for (j = 0; j < var_rank[i]; j++) { + start[j] = 0; + edge[j] = 1; + stride[j] = 1; + } + +ifdef(`PNETCDF',`dnl + err = GetVars(ncid, i, NULL, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + err = GetVars(ncid, i, start, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EEDGE) { + EXPECT_ERR(NC_EEDGE, err) + } + ELSE_NOK +')dnl + + /* test NC_EINVALCOORDS, first when edge[*] > 0 */ + for (j = 0; j < var_rank[i]; j++) { + start[j] = var_shape[i][j]; + err = GetVars(ncid, i, start, edge, stride, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + edge[j] = var_shape[i][j] + 1; + err = GetVars(ncid, i, start, edge, stride, buf, 1, datatype); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDGE, err) + ELSE_NOK + edge[j] = 1; + stride[j] = 0; + err = GetVars(ncid, i, start, edge, stride, buf, 1, datatype); + IF (err != NC_ESTRIDE) + EXPECT_ERR(NC_ESTRIDE, err) + ELSE_NOK + stride[j] = 1; + } + /* Check non-scalars for correct error returned even when there is + * nothing to get (edge[j]==0) */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = GetVars(ncid, i, start, edge, stride, buf, 0, datatype); +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + ELSE_NOK + start[j] = var_shape[i][j]+1; /* out of boundary check */ + err = GetVars(ncid, i, start, edge, stride, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + err = GetVars(ncid, i, start, edge, stride, buf, 1, datatype); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + + /* Choose a random point dividing each dim into 2 parts */ + /* get 2^rank (nslabs) slabs so defined */ + nslabs = 1; + for (j = 0; j < var_rank[i]; j++) { + mid[j] = roll( var_shape[i][j] ); + nslabs *= 2; + } + /* bits of k determine whether to get lower or upper part of dim */ + /* choose random stride from 1 to edge */ + n = 0; + for (k = 0; k < nslabs; k++) { + nstarts = 1; + for (j = 0; j < var_rank[i]; j++) { + if ((k >> j) & 1) { + start[j] = 0; + edge[j] = mid[j]; + }else{ + start[j] = mid[j]; + edge[j] = var_shape[i][j] - mid[j]; + } + sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + stride[j] = (PTRDType)sstride[j]; + nstarts *= stride[j]; + } + for (m = 0; m < nstarts; m++) { + err = toMixedBase(m, var_rank[i], sstride, index); + IF (err != 0) error("error in toMixedBase"); + nels = 1; + for (j = 0; j < var_rank[i]; j++) { + count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + nels *= count[j]; + index[j] += start[j]; + } + /* Random choice of forward or backward */ +/* TODO + if ( roll(2) ) { + for (j = 0; j < var_rank[i]; j++) { + index[j] += (count[j] - 1) * (IntType)stride[j]; + stride[j] = -stride[j]; + } + } + */ + err = GetVars(ncid, i, index, count, stride, buf, nels, datatype); + IF (err != NC_NOERR) + error("%s", APIFunc(strerror)(err)); + ELSE_NOK + + for (j = 0; j < nels; j++) { + p = (char *) buf; + p += j * (IntType)nctypelen(var_type[i]); + err = nc2dbl( var_type[i], p, & got ); + IF (err != NC_NOERR) + error("error in nc2dbl"); + err = toMixedBase(j, var_rank[i], count, index2); + IF (err != 0) error("error in toMixedBase"); + for (d = 0; d < var_rank[i]; d++) + index2[d] = index[d] + index2[d] * (IntType)stride[d]; + expect = hash(var_type[i], var_rank[i], index2); + if (inRange(expect,var_type[i])) { + IF (!equal2(got,expect,var_type[i])) { + error("buf read not that expected"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("var_name: %s, ", var_name[i]); + error("element number: %d ", j); + error("expect: %g, ", expect); + error("got: %g ", got); + } + } + ELSE_NOK + } + n++; + } + } + } + IF (n != var_nels[i]) { + error("count != nels"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("var_name: %s, ", var_name[i]); + error("count: %d, ", n); + error("nels: %d ", var_nels[i]); + } + } + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +/* + * Test GetVarm + * Choose a random point dividing each dim into 2 parts + * Get 2^rank (nslabs) slabs so defined + * Choose random stride from 1 to edge + * Buffer should end up being bit image of external variable. + * So all gets for a variable store in different elements of buffer + */ +int +TestFunc(get_varm)(VarArgs) +{ + int ncid; + int i; + int k; + int err; + int nslabs; + PTRDType nstarts; /* number of different starts */ + int nok = 0; /* total count of valid comparisons */ + IntType j, m, nels; + IntType start[MAX_RANK]; + IntType edge[MAX_RANK]; + IntType index[MAX_RANK]; + IntType mid[MAX_RANK]; + IntType count[MAX_RANK]; + IntType sstride[MAX_RANK]; + PTRDType stride[MAX_RANK]; + PTRDType imap[MAX_RANK]; + PTRDType imap2[MAX_RANK]; + ifdef(`PNETCDF', `MPI_Datatype datatype;') + double buf[MAX_NELS]; /* (void *) buffer */ + char *p; /* (void *) pointer */ + double expect; + double got; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = GetVarm(BAD_ID, 0, NULL, NULL, NULL, NULL, NULL, 0, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) EXPECT_ERR(NC_EBADID, err) + + /* check if can detect a bad variable ID */ + err = GetVarm(ncid, BAD_VARID, NULL, NULL, NULL, NULL, NULL, 0, MPI_DATATYPE_NULL); + IF (err != NC_ENOTVAR) EXPECT_ERR(NC_ENOTVAR, err) + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + /* check if can detect a bad file ID */ + err = GetVarm(BAD_ID, i, NULL, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') + + for (j = 0; j < var_rank[i]; j++) { + start[j] = 0; + edge[j] = 1; + stride[j] = 1; + imap[j] = 1; + } + +ifdef(`PNETCDF',`dnl + err = GetVarm(ncid, i, NULL, NULL, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + err = GetVarm(ncid, i, start, NULL, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EEDGE) { + EXPECT_ERR(NC_EEDGE, err) + } + ELSE_NOK +')dnl + + /* test NC_EINVALCOORDS, first when edge[*] > 0 */ + for (j = 0; j < var_rank[i]; j++) { + start[j] = var_shape[i][j]; + err = GetVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + edge[j] = var_shape[i][j] + 1; + err = GetVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDGE, err) + ELSE_NOK + edge[j] = 1; + stride[j] = 0; + err = GetVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); + IF (err != NC_ESTRIDE) + EXPECT_ERR(NC_ESTRIDE, err) + ELSE_NOK + stride[j] = 1; + } + /* Check non-scalars for correct error returned even when there is + * nothing to get (edge[j]==0) */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = GetVarm(ncid, i, start, edge, stride, imap, buf, 0, datatype); +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + ELSE_NOK + start[j] = var_shape[i][j]+1; /* out of boundary check */ + err = GetVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + err = GetVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + + if (var_rank[i] > 0) { + int jj = var_rank[i] - 1; + /* imap[jj] = nctypelen(var_type[i]); */ + imap[jj] = 1; /* in numbers of elements */ + for (; jj > 0; jj--) + imap[jj-1] = imap[jj] * (PTRDType)var_shape[i][jj]; + } + + /* Choose a random point dividing each dim into 2 parts */ + /* get 2^rank (nslabs) slabs so defined */ + nslabs = 1; + for (j = 0; j < var_rank[i]; j++) { + mid[j] = roll( var_shape[i][j] ); + nslabs *= 2; + } + /* bits of k determine whether to get lower or upper part of dim */ + /* choose random stride from 1 to edge */ + for (k = 0; k < nslabs; k++) { + nstarts = 1; + for (j = 0; j < var_rank[i]; j++) { + if ((k >> j) & 1) { + start[j] = 0; + edge[j] = mid[j]; + }else{ + start[j] = mid[j]; + edge[j] = var_shape[i][j] - mid[j]; + } + sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + stride[j] = (PTRDType)sstride[j]; + imap2[j] = imap[j] * stride[j]; + nstarts *= stride[j]; + } + for (m = 0; m < nstarts; m++) { + if (var_rank[i] == 0 && i%2 ) { + err = GetVarm(ncid, i, NULL, NULL, NULL, NULL, buf, var_nels[i], datatype); + } else { + err = toMixedBase(m, var_rank[i], sstride, index); + IF (err != 0) error("error in toMixedBase"); + nels = 1; + for (j = 0; j < var_rank[i]; j++) { + count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + index[j] += start[j]; + nels *= count[j]; + } + /* Random choice of forward or backward */ +/* TODO + if ( roll(2) ) { + for (j = 0; j < var_rank[i]; j++) { + index[j] += (count[j] - 1) * (IntType)stride[j]; + stride[j] = -stride[j]; + } + } + */ + j = fromMixedBase(var_rank[i], index, var_shape[i]); + p = (char *) buf + j * (IntType)nctypelen(var_type[i]); + err = GetVarm(ncid, i, index, count, stride, imap2, p, nels, datatype); + } + IF (err != NC_NOERR) + error("%s", APIFunc(strerror)(err)); + ELSE_NOK + } + } + p = (char *) buf; + for (j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + expect = hash( var_type[i], var_rank[i], index); + err = nc2dbl( var_type[i], p, & got ); + IF (err != NC_NOERR) + error("error in nc2dbl"); + if (inRange(expect,var_type[i])) { + IF (!equal2(got,expect,var_type[i])) { + error("buf read not that expected"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("var_name: %s, ", var_name[i]); + error("element number: %d ", j); + error("expect: %g, ", expect); + error("got: %g ", got); + } + } + ELSE_NOK + } + p += nctypelen(var_type[i]); + } + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(get_att)(AttVarArgs) +{ + int ncid; + int i; + int j; + IntType k, ndx[1]; + int err; + double buf[MAX_NELS]; /* (void *) buffer */ + char *p; /* (void *) pointer */ + double expect; + double got; + int nok = 0; /* count of valid comparisons */ + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + for (i = -1; i < numVars; i++) { + for (j = 0; j < NATTS(i); j++) { + err = APIFunc(get_att)(BAD_ID, i, ATT_NAME(i,j), buf); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(get_att)(ncid, BAD_VARID, ATT_NAME(i,j), buf); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(get_att)(ncid, i, "noSuch", buf); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(get_att)(ncid, i, ATT_NAME(i,j), buf); + IF (err != NC_NOERR) { + error("%s", APIFunc(strerror)(err)); + } else { + nok++; + for (k = 0; k < ATT_LEN(i,j); k++) { + ndx[0] = k; + expect = hash(ATT_TYPE(i,j), -1, ndx); + p = (char *) buf; + p += k * (IntType)nctypelen(ATT_TYPE(i,j)); + err = nc2dbl( ATT_TYPE(i,j), p, &got ); + IF (err != NC_NOERR) + error("error in nc2dbl"); + if (inRange(expect,ATT_TYPE(i,j))) { + IF (!equal2(got,expect,ATT_TYPE(i,j))) { + error("buf read not that expected"); + if (verbose) { + error("\n"); + error("varid: %d, ", i); + error("var_name: %s, ", + i >= 0 ? var_name[i] : "Global"); + error("att_name: %s, ", ATT_NAME(i,j)); + error("element number: %d\n", k); + error("expect: %-23.16e\n", expect); + error(" got: %-23.16e", got); + } + } + } + } + } + } + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_att)(AttVarArgs) +{ + int ncid; + int i; + int j; + int err; + nc_type t; + IntType n; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + for (i = -1; i < numVars; i++) { + for (j = 0; j < NATTS(i); j++) { + err = APIFunc(inq_att)(BAD_ID, i, ATT_NAME(i,j), &t, &n); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_att)(ncid, BAD_VARID, ATT_NAME(i,j), &t, &n); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_att)(ncid, i, "noSuch", &t, &n); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_att)(ncid, i, ATT_NAME(i,j), &t, &n); + IF (err != NC_NOERR) { + error("%s", APIFunc(strerror)(err)); + } else { + IF (t != ATT_TYPE(i,j)) + error("type not that expected"); + ELSE_NOK + IF (n != ATT_LEN(i,j)) + error("length not that expected"); + ELSE_NOK + } + } + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_attlen)(AttVarArgs) +{ + int ncid; + int i; + int j; + int err; + IntType len; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + for (i = -1; i < numVars; i++) { + err = APIFunc(inq_attlen)(ncid, i, "noSuch", &len); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + ELSE_NOK + for (j = 0; j < NATTS(i); j++) { + err = APIFunc(inq_attlen)(BAD_ID, i, ATT_NAME(i,j), &len); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_attlen)(ncid, BAD_VARID, ATT_NAME(i,j), &len); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_attlen)(ncid, i, ATT_NAME(i,j), &len); + IF (err != NC_NOERR) { + error("%s", APIFunc(strerror)(err)); + } else { + IF (len != ATT_LEN(i,j)) + error("len not that expected"); + ELSE_NOK + } + } + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_atttype)(AttVarArgs) +{ + int ncid; + int i; + int j; + int err; + nc_type datatype; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + for (i = -1; i < numVars; i++) { + err = APIFunc(inq_atttype)(ncid, i, "noSuch", &datatype); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + ELSE_NOK + for (j = 0; j < NATTS(i); j++) { + err = APIFunc(inq_atttype)(BAD_ID, i, ATT_NAME(i,j), &datatype); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_atttype)(ncid, BAD_VARID, ATT_NAME(i,j), &datatype); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_atttype)(ncid, i, ATT_NAME(i,j), &datatype); + IF (err != NC_NOERR) { + error("%s", APIFunc(strerror)(err)); + } else { + IF (datatype != ATT_TYPE(i,j)) + error("type not that expected"); + ELSE_NOK + } + } + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_attname)(AttVarArgs) +{ + int ncid; + int i; + int j; + int err; + char name[NC_MAX_NAME]; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + for (i = -1; i < numVars; i++) { + err = APIFunc(inq_attname)(ncid, i, BAD_ATTNUM, name); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_attname)(ncid, i, NATTS(i), name); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + ELSE_NOK + for (j = 0; j < NATTS(i); j++) { + err = APIFunc(inq_attname)(BAD_ID, i, j, name); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_attname)(ncid, BAD_VARID, j, name); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_attname)(ncid, i, j, name); + IF (err != NC_NOERR) { + error("%s", APIFunc(strerror)(err)); + } else { + IF (strcmp(ATT_NAME(i,j), name) != 0) + error("name not that expected"); + ELSE_NOK + } + } + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} + + +int +TestFunc(inq_attid)(AttVarArgs) +{ + int ncid; + int i; + int j; + int err; + int attnum; + int nok=0; + + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + for (i = -1; i < numVars; i++) { + err = APIFunc(inq_attid)(ncid, i, "noSuch", &attnum); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + ELSE_NOK + for (j = 0; j < NATTS(i); j++) { + err = APIFunc(inq_attid)(BAD_ID, i, ATT_NAME(i,j), &attnum); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_attid)(ncid, BAD_VARID, ATT_NAME(i,j), &attnum); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(inq_attid)(ncid, i, ATT_NAME(i,j), &attnum); + IF (err != NC_NOERR) { + error("%s", APIFunc(strerror)(err)); + } else { + IF (attnum != j) + error("attnum not that expected"); + ELSE_NOK + } + } + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + return nok; +} diff --git a/nc_test/test_write.c b/nc_test/test_write.c deleted file mode 100644 index a5fd5607e0..0000000000 --- a/nc_test/test_write.c +++ /dev/null @@ -1,2076 +0,0 @@ -/********************************************************************* - * Copyright 1996, UCAR/Unidata - * See netcdf/COPYRIGHT file for copying and redistribution conditions. - * $Id: test_write.c 2796 2014-10-28 03:40:29Z wkliao $ - *********************************************************************/ - -#include "tests.h" -#include "math.h" -#include /* For FILE stuff. */ - -/* - * Test nc_create - * For mode in NC_NOCLOBBER, NC_CLOBBER do: - * create netcdf file 'scratch.nc' with no data, close it - * test that it can be opened, do nc_inq to check nvars = 0, etc. - * Try again in NC_NOCLOBBER mode, check error return - * On exit, delete this file - */ -void -test_nc_create(void) -{ - int clobber; /* 0 for NC_NOCLOBBER, 1 for NC_CLOBBER */ - int err; - int ncid; - int ndims; /* number of dimensions */ - int nvars; /* number of variables */ - int ngatts; /* number of global attributes */ - int recdim; /* id of unlimited dimension */ - - for (clobber = 0; clobber < 2; clobber++) { - int cmode = clobber ? NC_CLOBBER : NC_NOCLOBBER; - err = file_create(scratch, cmode, &ncid); - IF (err) - error("nc_create: %s", nc_strerror(err)); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = file_open(scratch, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - err = nc_inq(ncid, &ndims, &nvars, &ngatts, &recdim); - IF (err) - error("nc_inq: %s", nc_strerror(err)); - else IF (ndims != 0) - error("nc_inq: wrong number of dimensions returned, %d", ndims); - else IF (nvars != 0) - error("nc_inq: wrong number of variables returned, %d", nvars); - else IF (ngatts != 0) - error("nc_inq: wrong number of global atts returned, %d", ngatts); - else IF (recdim != -1) - error("nc_inq: wrong record dimension ID returned, %d", recdim); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - } - - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err != NC_EEXIST) - error("attempt to overwrite file: status = %d", err); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_redef - * (In fact also tests nc_enddef - called from test_nc_enddef) - * BAD_ID - * attempt redef (error) & enddef on read-only file - * create file, define dims & vars. - * attempt put var (error) - * attempt redef (error) & enddef. - * put vars - * attempt def new dims (error) - * redef - * def new dims, vars. - * put atts - * enddef - * put vars - * close - * check file: vars & atts - * check reopening with NC_WRITE and adding new dims, atts, vars - */ -void -test_nc_redef(void) -{ - int ncid; /* netcdf id */ - /* used to force effective test of ncio->move() in redef */ - size_t sizehint = 8192; - int dimid; /* dimension id */ - int varid; /* variable id */ - int varid1; /* variable id */ - int err; - const char * title = "Not funny"; - double var; - char name[NC_MAX_NAME]; - size_t length; - int fmt_variant1, fmt_variant2; - - /* BAD_ID tests */ - err = nc_redef(BAD_ID); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_enddef(BAD_ID); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - - /* read-only tests */ - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - err = nc_redef(ncid); - IF (err != NC_EPERM) - error("nc_redef in NC_NOWRITE mode: status = %d", err); - err = nc_enddef(ncid); - IF (err != NC_ENOTINDEFINE) - error("nc_redef in NC_NOWRITE mode: status = %d", err); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - /* tests using scratch file */ - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - /* limit for ncio implementations which have infinite chunksize */ - if(sizehint > 32768) - sizehint = 16384; - def_dims(ncid); - def_vars(ncid); - put_atts(ncid); - err = nc_inq_varid(ncid, "d", &varid); - IF (err) - error("nc_inq_varid: %s", nc_strerror(err)); - var = 1.0; - err = nc_put_var1_double(ncid, varid, NULL, &var); - IF (err != NC_EINDEFINE) - error("nc_put_var... in define mode: status = %d", err); - err = nc_redef(ncid); - IF (err != NC_EINDEFINE) - error("nc_redef in define mode: status = %d", err); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - put_vars(ncid); - err = nc_def_dim(ncid, "abc", sizehint, &dimid); - IF (err != NC_ENOTINDEFINE) - error("nc_def_dim in define mode: status = %d", err); - err = nc_redef(ncid); - IF (err) - error("nc_redef: %s", nc_strerror(err)); -#if 0 - err = nc_set_fill(ncid, NC_NOFILL, NULL); - IF (err) - error("nc_set_fill: %s", nc_strerror(err)); -#endif - err = nc_def_dim(ncid, "abc", sizehint, &dimid); - IF (err) - error("nc_def_dim: %s", nc_strerror(err)); - err = nc_def_var(ncid, "abcScalar", NC_INT, 0, NULL, &varid); - IF (err) - error("nc_def_var: %s", nc_strerror(err)); - err = nc_def_var(ncid, "abc", NC_INT, 1, &dimid, &varid1); - IF (err) - error("nc_def_var: %s", nc_strerror(err)); - { - int dimids[NDIMS +1]; - int ii = 0; - for(ii = 0; ii < NDIMS; ii++) - dimids[ii] = ii; - dimids[NDIMS] = dimid; - err = nc_def_var(ncid, "abcRec", NC_INT, NDIMS, dimids, &varid1); - IF (err) - error("nc_def_var: %s", nc_strerror(err)); - } - err = nc_put_att_text(ncid, NC_GLOBAL, "title", 1+strlen(title), title); - IF (err) - error("nc_put_att_text: %s", nc_strerror(err)); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - var = 1.0; - err = nc_put_var1_double(ncid, varid, NULL, &var); - IF (err) - error("nc_put_var1_double: %s", nc_strerror(err)); - err = nc_inq_format(ncid, &fmt_variant1); - IF (err) - error("nc_inq_format: %s", nc_strerror(err)); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - /* check scratch file written as expected */ - check_file(scratch); /* checks all except "abc" stuff added above */ - - IF ((err = file_open(scratch, NC_NOWRITE, &ncid))) - error("nc_open: %s", nc_strerror(err)); - IF ((err = nc_inq_dim(ncid, dimid, name, &length))) - error("nc_inq_dim: %s", nc_strerror(err)); - IF (strcmp(name, "abc") != 0) - error("Unexpected dim name"); - IF (length != sizehint) - error("Unexpected dim length"); - IF ((err = nc_get_var1_double(ncid, varid, NULL, &var))) - error("nc_get_var1_double: %s", nc_strerror(err)); - IF (var != 1.0) - error("nc_get_var1_double: unexpected value"); - IF ((err = nc_close(ncid))) - error("nc_close: %s", nc_strerror(err)); - - /* open scratch file for writing, add another dim, var, att, then check */ - IF ((err = file_open(scratch, NC_WRITE, &ncid))) - error("nc_open: %s", nc_strerror(err)); - IF ((err = nc_redef(ncid))) - error("nc_redef: %s", nc_strerror(err)); - IF ((err = nc_def_dim(ncid, "def", sizehint, &dimid))) - error("nc_def_dim: %s", nc_strerror(err)); - IF ((err = nc_def_var(ncid, "defScalar", NC_INT, 0, NULL, &varid))) - error("nc_def_var: %s", nc_strerror(err)); - IF ((err = nc_def_var(ncid, "def", NC_INT, 1, &dimid, &varid1))) - error("nc_def_var: %s", nc_strerror(err)); - IF ((err = nc_put_att_text(ncid, NC_GLOBAL, "Credits", 1+strlen("Thanks!"), "Thanks!"))) - error("nc_put_att_text: %s", nc_strerror(err)); - IF ((err = nc_enddef(ncid))) - error("nc_enddef: %s", nc_strerror(err)); - var = 2.0; - IF ((err = nc_put_var1_double(ncid, varid, NULL, &var))) - error("nc_put_var1_double: %s", nc_strerror(err)); - IF ((err = nc_close(ncid))) - error("nc_close: %s", nc_strerror(err)); - - /* check scratch file written as expected */ - check_file(scratch); - - err = file_open(scratch, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - err = nc_inq_dim(ncid, dimid, name, &length); - IF (err) - error("nc_inq_dim: %s", nc_strerror(err)); - IF (strcmp(name, "def") != 0) - error("Unexpected dim name"); - IF (length != sizehint) - error("Unexpected dim length"); - err = nc_get_var1_double(ncid, varid, NULL, &var); - IF (err) - error("nc_get_var1_double: %s", nc_strerror(err)); - IF (var != 2.0) - error("nc_get_var1_double: unexpected value"); - /* make sure format variant hasn't changed from when created */ - err = nc_inq_format(ncid, &fmt_variant2); - IF (err) - error("nc_inq_format: %s", nc_strerror(err)); - IF (fmt_variant1 != fmt_variant2) - error("nc_enddef changed format variant"); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_enddef - * Simply calls test_nc_redef which tests both nc_redef & nc_enddef - */ -void -test_nc_enddef(void) -{ - test_nc_redef(); -} - - -/* - * Test nc_sync - * try with bad handle, check error - * try in define mode, check error - * try writing with one handle, reading with another on same netCDF - */ -void -test_nc_sync(void) -{ - int ncidw; /* netcdf id for writing */ - int ncidr; /* netcdf id for reading */ - int err; - - /* BAD_ID test */ - err = nc_sync(BAD_ID); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - - /* create scratch file & try nc_sync in define mode */ - err = file_create(scratch, NC_NOCLOBBER, &ncidw); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - err = nc_sync(ncidw); - IF (err != NC_EINDEFINE) - error("nc_sync called in define mode: status = %d", err); - - /* write using same handle */ - def_dims(ncidw); - def_vars(ncidw); - put_atts(ncidw); - err = nc_enddef(ncidw); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - put_vars(ncidw); - err = nc_sync(ncidw); - IF (err) - error("nc_sync of ncidw failed: %s", nc_strerror(err)); - - /* open another handle, nc_sync, read (check) */ - err = file_open(scratch, NC_NOWRITE, &ncidr); - IF (err) - error("nc_open: %s", nc_strerror(err)); - err = nc_sync(ncidr); - IF (err) - error("nc_sync of ncidr failed: %s", nc_strerror(err)); - check_dims(ncidr); - check_atts(ncidr); - check_vars(ncidr); - - /* close both handles */ - err = nc_close(ncidr); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = nc_close(ncidw); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_abort - * try with bad handle, check error - * try in define mode before anything written, check that file was deleted - * try after nc_enddef, nc_redef, define new dims, vars, atts - * try after writing variable - */ -void -test_nc_abort(void) -{ - int ncid; /* netcdf id */ - int err; - int ndims; - int nvars; - int ngatts; - - /* BAD_ID test */ - err = nc_abort(BAD_ID); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - - /* create scratch file & try nc_abort in define mode */ - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - def_vars(ncid); - put_atts(ncid); - err = nc_abort(ncid); - IF (err) - error("nc_abort of ncid failed: %s", nc_strerror(err)); - err = nc_close(ncid); /* should already be closed */ - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = remove(scratch); /* should already be deleted */ - IF (!err) - error("file %s should not exist", scratch); - - /* - * create scratch file - * do nc_enddef & nc_redef - * define new dims, vars, atts - * try nc_abort: should restore previous state (no dims, vars, atts) - */ - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - err = nc_redef(ncid); - IF (err) - error("nc_redef: %s", nc_strerror(err)); - def_dims(ncid); - def_vars(ncid); - put_atts(ncid); - err = nc_abort(ncid); - IF (err) - error("nc_abort of ncid failed: %s", nc_strerror(err)); - err = nc_close(ncid); /* should already be closed */ - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = file_open(scratch, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - err = nc_inq (ncid, &ndims, &nvars, &ngatts, NULL); - IF (err) - error("nc_inq: %s", nc_strerror(err)); - IF (ndims != 0) - error("ndims should be 0"); - IF (nvars != 0) - error("nvars should be 0"); - IF (ngatts != 0) - error("ngatts should be 0"); - err = nc_close (ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - /* try nc_abort in data mode - should just close */ - err = file_create(scratch, NC_CLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - def_vars(ncid); - put_atts(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - put_vars(ncid); - err = nc_abort(ncid); - IF (err) - error("nc_abort of ncid failed: %s", nc_strerror(err)); - err = nc_close(ncid); /* should already be closed */ - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - check_file(scratch); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_def_dim - * try with bad netCDF handle, check error - * try in data mode, check error - * check that returned id is one more than previous id - * try adding same dimension twice, check error - * try with illegal sizes, check error - * make sure unlimited size works, shows up in nc_inq_unlimdim - * try to define a second unlimited dimension, check error - */ -void -test_nc_def_dim(void) -{ - int ncid; - int err; /* status */ - int i; - int dimid; /* dimension id */ - size_t length; - - /* BAD_ID test */ - err = nc_def_dim(BAD_ID, "abc", 8, &dimid); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - - /* data mode test */ - err = file_create(scratch, NC_CLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - err = nc_def_dim(ncid, "abc", 8, &dimid); - IF (err != NC_ENOTINDEFINE) - error("bad ncid: status = %d", err); - - /* define-mode tests: unlimited dim */ - err = nc_redef(ncid); - IF (err) - error("nc_redef: %s", nc_strerror(err)); - err = nc_def_dim(ncid, dim_name[0], NC_UNLIMITED, &dimid); - IF (err) - error("nc_def_dim: %s", nc_strerror(err)); - IF (dimid != 0) - error("Unexpected dimid"); - err = nc_inq_unlimdim(ncid, &dimid); - IF (err) - error("nc_inq_unlimdim: %s", nc_strerror(err)); - IF (dimid != 0) - error("Unexpected recdim"); - err = nc_inq_dimlen(ncid, dimid, &length); - IF (err) - error("nc_inq_dimlen: %s", nc_strerror(err)); - IF (length != 0) - error("Unexpected length"); - err = nc_def_dim(ncid, "abc", NC_UNLIMITED, &dimid); - IF (err != NC_EUNLIMIT) - error("2nd unlimited dimension: status = %d", err); - /* define-mode tests: remaining dims */ - for (i = 1; i < NDIMS; i++) { - err = nc_def_dim(ncid, dim_name[i-1], dim_len[i], &dimid); - IF (err != NC_ENAMEINUSE) - error("duplicate name: status = %d", err); - err = nc_def_dim(ncid, BAD_NAME, dim_len[i], &dimid); - IF (err != NC_EBADNAME) - error("bad name: status = %d", err); - /* Fix: dmh 11/4/2011: works only if sizeof(long) > 4 */ - if(sizeof(long) > 4) { - err = nc_def_dim(ncid, dim_name[i], NC_UNLIMITED-1, &dimid); - IF (err != NC_EDIMSIZE) - error("bad size: status = %d", err); - } - err = nc_def_dim(ncid, dim_name[i], dim_len[i], &dimid); - IF (err) - error("nc_def_dim: %s", nc_strerror(err)); - IF (dimid != i) - error("Unexpected dimid"); - } - - /* Following just to expand unlimited dim */ - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - put_vars(ncid); - - /* Check all dims */ - check_dims(ncid); - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_rename_dim - * try with bad netCDF handle, check error - * check that proper rename worked with nc_inq_dim - * try renaming to existing dimension name, check error - * try with bad dimension handle, check error - */ -void -test_nc_rename_dim(void) -{ - int ncid; - int err; /* status */ - char name[NC_MAX_NAME]; - - /* BAD_ID test */ - err = nc_rename_dim(BAD_ID, 0, "abc"); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - - /* main tests */ - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - err = nc_rename_dim(ncid, BAD_DIMID, "abc"); - IF (err != NC_EBADDIM) - error("bad dimid: status = %d", err); - err = nc_rename_dim(ncid, 2, "abc"); - IF (err) - error("nc_rename_dim: %s", nc_strerror(err)); - err = nc_inq_dimname(ncid, 2, name); - IF (err) - error("nc_inq_dimname: %s", nc_strerror(err)); - IF (strcmp(name, "abc") != 0) - error("Unexpected name: %s", name); - err = nc_rename_dim(ncid, 0, "abc"); - IF (err != NC_ENAMEINUSE) - error("duplicate name: status = %d", err); - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_def_var - * try with bad netCDF handle, check error - * try with bad name, check error - * scalar tests: - * check that proper define worked with nc_inq_var - * try redefining an existing variable, check error - * try with bad datatype, check error - * try with bad number of dimensions, check error - * try in data mode, check error - * check that returned id is one more than previous id - * try with bad dimension ids, check error - */ -void -test_nc_def_var(void) -{ - int ncid; - int varid; - int err; /* status */ - int i; - int ndims; - int natts; - char name[NC_MAX_NAME]; - int dimids[MAX_RANK]; - nc_type datatype; - - /* BAD_ID test */ - err = nc_def_var(BAD_ID, "abc", NC_SHORT, 0, NULL, &varid); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - - /* scalar tests */ - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - err = nc_def_var(ncid, "abc", NC_SHORT, 0, NULL, &varid); - IF (err) - error("nc_def_var: %s", nc_strerror(err)); - err = nc_inq_var(ncid, varid, name, &datatype, &ndims, dimids, &natts); - IF (err) - error("nc_inq_var: %s", nc_strerror(err)); - IF (strcmp(name, "abc") != 0) - error("Unexpected name: %s", name); - IF (datatype != NC_SHORT) - error("Unexpected datatype"); - IF (ndims != 0) - error("Unexpected rank"); - err = nc_def_var(ncid, BAD_NAME, NC_SHORT, 0, NULL, &varid); - IF (err != NC_EBADNAME) - error("bad name: status = %d", err); - err = nc_def_var(ncid, "abc", NC_SHORT, 0, NULL, &varid); - IF (err != NC_ENAMEINUSE) - error("duplicate name: status = %d", err); - err = nc_def_var(ncid, "ABC", BAD_TYPE, -1, dimids, &varid); - IF (err != NC_EBADTYPE) - error("bad type: status = %d", err); - err = nc_def_var(ncid, "ABC", NC_SHORT, -1, dimids, &varid); - IF (err != NC_EINVAL) - error("bad rank: status = %d", err); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - err = nc_def_var(ncid, "ABC", NC_SHORT, 0, dimids, &varid); - IF (err != NC_ENOTINDEFINE) - error("nc_def_var called in data mode: status = %d", err); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); - - /* general tests using global vars */ - err = file_create(scratch, NC_CLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - for (i = 0; i < numVars; i++) { - err = nc_def_var(ncid, var_name[i], var_type[i], var_rank[i], - var_dimid[i], &varid); - IF (err) - error("nc_def_var: %s", nc_strerror(err)); - IF (varid != i) - error("Unexpected varid"); - } - - /* try bad dim ids */ - dimids[0] = BAD_DIMID; - err = nc_def_var(ncid, "abc", NC_SHORT, 1, dimids, &varid); - IF (err != NC_EBADDIM) - error("bad dim ids: status = %d", err); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_put_var1 - */ -void -test_nc_put_var1(void) -{ - int ncid; - int i; - int j; - int err; - size_t index[MAX_RANK]; - double value; - double buf[1]; /* (void *) buffer */ - - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - - for (i = 0; i < numVars; i++) { - for (j = 0; j < var_rank[i]; j++) - index[j] = 0; - err = nc_put_var1(BAD_ID, i, index, buf); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_var1(ncid, BAD_VARID, index, buf); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - if (var_dimid[i][j] > 0) { /* skip record dim */ - index[j] = var_shape[i][j]; - err = nc_put_var1(ncid, i, index, buf); - IF (err != NC_EINVALCOORDS) - error("bad index: status = %d", err); - index[j] = 0; - } - } - for (j = 0; j < var_nels[i]; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase"); - value = hash( var_type[i], var_rank[i], index); - if (inRange(value, var_type[i])) { - err = dbl2nc(value, var_type[i], buf); - IF (err) - error("error in dbl2nc"); - if (var_rank[i] == 0 && i%2 == 0) - err = nc_put_var1(ncid, i, NULL, buf); - else - err = nc_put_var1(ncid, i, index, buf); - IF (err) - error("%s", nc_strerror(err)); - } - } - } - - check_vars(ncid); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_put_vara - * Choose a random point dividing each dim into 2 parts - * Put 2^rank (nslabs) slabs so defined - * Redefine buffer for each put. - * At end check all variables using check_vars - */ -void -test_nc_put_vara(void) -{ - int ncid; - int d; - int i; - int j; - int k; - int err; - int nels; - int nslabs; - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t mid[MAX_RANK]; - double buf[MAX_NELS]; /* (void *) buffer */ - char *p; /* (void *) pointer */ - double value; - - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - - for (i = 0; i < numVars; i++) { - assert(var_rank[i] <= MAX_RANK); - assert(var_nels[i] <= MAX_NELS); - for (j = 0; j < var_rank[i]; j++) { - start[j] = 0; - edge[j] = 1; - } - err = nc_put_vara(BAD_ID, i, start, edge, buf); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_vara(ncid, BAD_VARID, start, edge, buf); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - if (var_dimid[i][j] > 0) { /* skip record dim */ - start[j] = var_shape[i][j]; - err = nc_put_vara(ncid, i, start, edge, buf); - IF (err != NC_EINVALCOORDS) - error("bad index: status = %d", err); - start[j] = 0; - edge[j] = var_shape[i][j] + 1; - err = nc_put_vara(ncid, i, start, edge, buf); - IF (err != NC_EEDGE) - error("bad edge: status = %d", err); - edge[j] = 1; - } - } - /* Choose a random point dividing each dim into 2 parts */ - /* put 2^rank (nslabs) slabs so defined */ - nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { - mid[j] = roll( var_shape[i][j] ); - nslabs *= 2; - } - /* bits of k determine whether to put lower or upper part of dim */ - for (k = 0; k < nslabs; k++) { - nels = 1; - for (j = 0; j < var_rank[i]; j++) { - if ((k >> j) & 1) { - start[j] = 0; - edge[j] = mid[j]; - }else{ - start[j] = mid[j]; - edge[j] = var_shape[i][j] - mid[j]; - } - nels *= edge[j]; - } - p = (char *) buf; - for (j = 0; j < nels; j++) { - err = toMixedBase(j, var_rank[i], edge, index); - IF (err) - error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) - index[d] += start[d]; - value = hash( var_type[i], var_rank[i], index); - if (!inRange(value, var_type[i])) - value = 0; - err = dbl2nc(value, var_type[i], p); - IF (err) - error("error in dbl2nc"); - p += nctypelen(var_type[i]); - } - if (var_rank[i] == 0 && i%2 == 0) - err = nc_put_vara(ncid, i, NULL, NULL, buf); - else - err = nc_put_vara(ncid, i, start, edge, buf); - IF (err) { - error("%s", nc_strerror(err)); - } - } - } - - check_vars(ncid); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_put_vars - * Choose a random point dividing each dim into 2 parts - * Put 2^rank (nslabs) slabs so defined - * Choose random stride from 1 to edge - * Redefine buffer for each put. - * At end check all variables using check_vars - */ -void -test_nc_put_vars(void) -{ - int ncid; - int d; - int i; - int j; - int k; - int m; - int err; - int nels; - int nslabs; - int nstarts; /* number of different starts */ - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t index2[MAX_RANK]; - size_t mid[MAX_RANK]; - size_t count[MAX_RANK]; - size_t sstride[MAX_RANK]; - ptrdiff_t stride[MAX_RANK]; - double buf[MAX_NELS]; /* (void *) buffer */ - char *p; /* (void *) pointer */ - double value; - - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - - for (i = 0; i < numVars; i++) { - assert(var_rank[i] <= MAX_RANK); - assert(var_nels[i] <= MAX_NELS); - for (j = 0; j < var_rank[i]; j++) { - start[j] = 0; - edge[j] = 1; - stride[j] = 1; - } - err = nc_put_vars(BAD_ID, i, start, edge, stride, buf); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_vars(ncid, BAD_VARID, start, edge, stride, buf); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - if (var_dimid[i][j] > 0) { /* skip record dim */ - start[j] = var_shape[i][j]; - err = nc_put_vars(ncid, i, start, edge, stride, buf); - IF (err != NC_EINVALCOORDS && err != NC_EEDGE) - error("bad index: status = %d", err); - start[j] = 0; - edge[j] = var_shape[i][j] + 1; - err = nc_put_vars(ncid, i, start, edge, stride, buf); - IF (err != NC_EEDGE) - error("bad edge: status = %d", err); - edge[j] = 1; - stride[j] = 0; - err = nc_put_vars(ncid, i, start, edge, stride, buf); - IF (err != NC_ESTRIDE) - error("bad stride: status = %d", err); - stride[j] = 1; - } - } - /* Choose a random point dividing each dim into 2 parts */ - /* put 2^rank (nslabs) slabs so defined */ - nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { - mid[j] = roll( var_shape[i][j] ); - nslabs *= 2; - } - /* bits of k determine whether to put lower or upper part of dim */ - /* choose random stride from 1 to edge */ - for (k = 0; k < nslabs; k++) { - nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { - if ((k >> j) & 1) { - start[j] = 0; - edge[j] = mid[j]; - }else{ - start[j] = mid[j]; - edge[j] = var_shape[i][j] - mid[j]; - } - sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; - nstarts *= stride[j]; - } - for (m = 0; m < nstarts; m++) { - err = toMixedBase(m, var_rank[i], sstride, index); - IF (err) - error("error in toMixedBase"); - nels = 1; - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / stride[j]; - nels *= count[j]; - index[j] += start[j]; - } - /* Random choice of forward or backward */ -/* TODO - if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { - index[j] += (count[j] - 1) * stride[j]; - stride[j] = -stride[j]; - } - } - */ - p = (char *) buf; - for (j = 0; j < nels; j++) { - err = toMixedBase(j, var_rank[i], count, index2); - IF (err) - error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) - index2[d] = index[d] + index2[d] * stride[d]; - value = hash( var_type[i], var_rank[i], index2); - if (!inRange(value, var_type[i])) - value = 0; - err = dbl2nc(value, var_type[i], p); - IF (err) - error("error in dbl2nc"); - p += nctypelen(var_type[i]); - } - if (var_rank[i] == 0 && i%2 == 0) - err = nc_put_vars(ncid, i, NULL, NULL, NULL, buf); - else - err = nc_put_vars(ncid, i, index, count, stride, buf); - IF (err) { - error("%s", nc_strerror(err)); - } - } - } - } - - check_vars(ncid); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_put_varm - * Choose a random point dividing each dim into 2 parts - * Put 2^rank (nslabs) slabs so defined - * Choose random stride from 1 to edge - * Buffer is bit image of whole external variable. - * So all puts for a variable put different elements of buffer - * At end check all variables using check_vars - */ -void -test_nc_put_varm(void) -{ - int ncid; - int i; - int j; - int k; - int m; - int err; - int nslabs; - int nstarts; /* number of different starts */ - size_t start[MAX_RANK]; - size_t edge[MAX_RANK]; - size_t index[MAX_RANK]; - size_t mid[MAX_RANK]; - size_t count[MAX_RANK]; - size_t sstride[MAX_RANK]; - ptrdiff_t stride[MAX_RANK]; - ptrdiff_t imap[MAX_RANK]; - ptrdiff_t imap2[MAX_RANK]; - double buf[MAX_NELS]; /* (void *) buffer */ - char *p; /* (void *) pointer */ - double value; - - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - def_vars(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - - for (i = 0; i < numVars; i++) { - assert(var_rank[i] <= MAX_RANK); - assert(var_nels[i] <= MAX_NELS); - for (j = 0; j < var_rank[i]; j++) { - start[j] = 0; - edge[j] = 1; - stride[j] = 1; - } - if (var_rank[i] > 0) { - j = var_rank[i] - 1; - // imap[j] = nctypelen(var_type[i]); /* in bytes */ - imap[j] = 1; /* in numbers of elements */ - for (; j > 0; j--) - imap[j-1] = imap[j] * var_shape[i][j]; - } - p = (char *) buf; - for (j = 0; j < var_nels[i]; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase"); - value = hash( var_type[i], var_rank[i], index); - if (!inRange(value, var_type[i])) - value = 0; - err = dbl2nc(value, var_type[i], p); - IF (err) - error("error in dbl2nc"); - p += nctypelen(var_type[i]); - } - err = nc_put_varm(BAD_ID, i, start, edge, stride, imap, buf); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_varm(ncid, BAD_VARID, start, edge, stride, imap, buf); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - for (j = 0; j < var_rank[i]; j++) { - if (var_dimid[i][j] > 0) { /* skip record dim */ - start[j] = var_shape[i][j]; - err = nc_put_varm(ncid, i, start, edge, stride, imap, buf); - IF (err != NC_EINVALCOORDS && err != NC_EEDGE) - error("bad index: status = %d", err); - start[j] = 0; - edge[j] = var_shape[i][j] + 1; - err = nc_put_varm(ncid, i, start, edge, stride, imap, buf); - IF (err != NC_EEDGE) - error("bad edge: status = %d", err); - edge[j] = 1; - stride[j] = 0; - err = nc_put_varm(ncid, i, start, edge, stride, imap, buf); - IF (err != NC_ESTRIDE) - error("bad stride: status = %d", err); - stride[j] = 1; - } - } - /* Choose a random point dividing each dim into 2 parts */ - /* put 2^rank (nslabs) slabs so defined */ - nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { - mid[j] = roll( var_shape[i][j] ); - nslabs *= 2; - } - /* bits of k determine whether to put lower or upper part of dim */ - /* choose random stride from 1 to edge */ - for (k = 0; k < nslabs; k++) { - nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { - if ((k >> j) & 1) { - start[j] = 0; - edge[j] = mid[j]; - }else{ - start[j] = mid[j]; - edge[j] = var_shape[i][j] - mid[j]; - } - sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; - imap2[j] = imap[j] * sstride[j]; - nstarts *= stride[j]; - } - for (m = 0; m < nstarts; m++) { - if (var_rank[i] == 0 && i%2 == 0) { - err = nc_put_varm(ncid, i, NULL, NULL, NULL, NULL, buf); - } else { - err = toMixedBase(m, var_rank[i], sstride, index); - IF (err) - error("error in toMixedBase"); - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / stride[j]; - index[j] += start[j]; - } - /* Random choice of forward or backward */ -/* TODO - if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { - index[j] += (count[j] - 1) * stride[j]; - stride[j] = -stride[j]; - } - } - */ - j = fromMixedBase(var_rank[i], index, var_shape[i]); - p = (char *) buf + j * nctypelen(var_type[i]); - err = nc_put_varm(ncid, i, index, count, stride, imap2, p); - } - IF (err) { - error("%s", nc_strerror(err)); - } - } - } - } - - check_vars(ncid); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_rename_var - * try with bad netCDF handle, check error - * try with bad variable handle, check error - * try renaming to existing variable name, check error - * check that proper rename worked with nc_inq_varid - * try in data mode, check error - */ -void -test_nc_rename_var(void) -{ - int ncid; - int varid; - int err; - int i; - char name[NC_MAX_NAME]; - - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - err = nc_rename_var(ncid, BAD_VARID, "newName"); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - def_dims(ncid); - def_vars(ncid); - - /* Prefix "new_" to each name */ - for (i = 0; i < numVars; i++) { - err = nc_rename_var(BAD_ID, i, "newName"); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_rename_var(ncid, i, var_name[numVars-1]); - IF (err != NC_ENAMEINUSE) - error("duplicate name: status = %d", err); - (void) strcpy(name, "new_"); - (void) strcat(name, var_name[i]); - err = nc_rename_var(ncid, i, name); - IF (err) - error("nc_rename_var: %s", nc_strerror(err)); - err = nc_inq_varid(ncid, name, &varid); - IF (err) - error("nc_inq_varid: %s", nc_strerror(err)); - IF (varid != i) - error("Unexpected varid"); - } - - /* Change to data mode */ - /* Try making names even longer. Then restore original names */ - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - for (i = 0; i < numVars; i++) { - (void) strcpy(name, "even_longer_"); - (void) strcat(name, var_name[i]); - err = nc_rename_var(ncid, i, name); - IF (err != NC_ENOTINDEFINE) - error("longer name in data mode: status = %d", err); - err = nc_rename_var(ncid, i, var_name[i]); - IF (err) - error("nc_rename_var: %s", nc_strerror(err)); - err = nc_inq_varid(ncid, var_name[i], &varid); - IF (err) - error("nc_inq_varid: %s", nc_strerror(err)); - IF (varid != i) - error("Unexpected varid"); - } - - put_vars(ncid); - check_vars(ncid); - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -void -test_nc_put_att(void) -{ - int ncid; - int varid; - int i; - int j; - size_t k; - int err; - double buf[MAX_NELS]; /* (void *) buffer */ - char *p; /* (void *) pointer */ - char *name; /* of att */ - nc_type datatype; /* of att */ - size_t length; /* of att */ - double value; - - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - def_vars(ncid); - - for (i = -1; i < numVars; i++) { - varid = VARID(i); - for (j = 0; j < NATTS(i); j++) { - name = ATT_NAME(i,j); - datatype = ATT_TYPE(i,j); - length = ATT_LEN(i,j); - err = nc_put_att(BAD_ID, varid, name, datatype, length, buf); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_put_att(ncid, varid, BAD_NAME, datatype, length, buf); - IF (err != NC_EBADNAME) - error("bad name: status = %d", err); - err = nc_put_att(ncid, BAD_VARID, name, datatype, length, buf); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - err = nc_put_att(ncid, varid, name, BAD_TYPE, length, buf); - IF (err != NC_EBADTYPE) - error("bad type: status = %d", err); - p = (char *) buf; - for (k = 0; k < length; k++) { - value = hash(datatype, -1, &k ); - if (!inRange(value, datatype)) - value = 0; - err = dbl2nc(value, datatype, p); - IF (err) - error("error in dbl2nc"); - p += nctypelen(datatype); - } - err = nc_put_att(ncid, varid, name, datatype, length, buf); - IF (err) { - error("%s", nc_strerror(err)); - } - } - } - - check_atts(ncid); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_copy_att - * try with bad source or target netCDF handles, check error - * try with bad source or target variable handle, check error - * try with nonexisting attribute, check error - * check that NC_GLOBAL variable for source or target works - * check that new attribute put works with target in define mode - * check that old attribute put works with target in data mode - * check that changing type and length of an attribute work OK - * try with same ncid for source and target, different variables - * try with same ncid for source and target, same variable - */ -void -test_nc_copy_att(void) -{ - int ncid_in; - int ncid_out; - int varid; - int err; - int i; - int j; - char *name; /* of att */ - nc_type datatype; /* of att */ - size_t length; /* of att */ - char value; - - err = file_open(testfile, NC_NOWRITE, &ncid_in); - IF (err) - error("nc_open: %s", nc_strerror(err)); - err = file_create(scratch, NC_NOCLOBBER, &ncid_out); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid_out); - def_vars(ncid_out); - - for (i = -1; i < numVars; i++) { - varid = VARID(i); - for (j = 0; j < NATTS(i); j++) { - name = ATT_NAME(i,j); - err = nc_copy_att(ncid_in, BAD_VARID, name, ncid_out, varid); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - err = nc_copy_att(ncid_in, varid, name, ncid_out, BAD_VARID); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - err = nc_copy_att(BAD_ID, varid, name, ncid_out, varid); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_copy_att(ncid_in, varid, name, BAD_ID, varid); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_copy_att(ncid_in, varid, "noSuch", ncid_out, varid); - IF (err != NC_ENOTATT) - error("bad attname: status = %d", err); - err = nc_copy_att(ncid_in, varid, name, ncid_out, varid); - IF (err) - error("nc_copy_att: %s", nc_strerror(err)); - err = nc_copy_att(ncid_out, varid, name, ncid_out, varid); - IF (err) - error("source = target: %s", nc_strerror(err)); - } - } - - err = nc_close(ncid_in); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - /* Close scratch. Reopen & check attributes */ - err = nc_close(ncid_out); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = file_open(scratch, NC_WRITE, &ncid_out); - IF (err) - error("nc_open: %s", nc_strerror(err)); - check_atts(ncid_out); - - /* - * change to define mode - * define single char. global att. ':a' with value 'A' - * This will be used as source for following copies - */ - err = nc_redef(ncid_out); - IF (err) - error("nc_redef: %s", nc_strerror(err)); - err = nc_put_att_text(ncid_out, NC_GLOBAL, "a", 1, "A"); - IF (err) - error("nc_put_att_text: %s", nc_strerror(err)); - - /* - * change to data mode - * Use scratch as both source & dest. - * try copy to existing att. change type & decrease length - * rename 1st existing att of each var (if any) 'a' - * if this att. exists them copy ':a' to it - */ - err = nc_enddef(ncid_out); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - for (i = 0; i < numVars; i++) { - if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) { - err = nc_rename_att(ncid_out, i, att_name[i][0], "a"); - IF (err) - error("nc_rename_att: %s", nc_strerror(err)); - err = nc_copy_att(ncid_out, NC_GLOBAL, "a", ncid_out, i); - IF (err) - error("nc_copy_att: %s", nc_strerror(err)); - } - } - err = nc_close(ncid_out); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - /* Reopen & check */ - err = file_open(scratch, NC_WRITE, &ncid_out); - IF (err) - error("nc_open: %s", nc_strerror(err)); - for (i = 0; i < numVars; i++) { - if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) { - err = nc_inq_att(ncid_out, i, "a", &datatype, &length); - IF (err) - error("nc_inq_att: %s", nc_strerror(err)); - IF (datatype != NC_CHAR) - error("Unexpected type"); - IF (length != 1) - error("Unexpected length"); - err = nc_get_att_text(ncid_out, i, "a", &value); - IF (err) - error("nc_get_att_text: %s", nc_strerror(err)); - IF (value != 'A') - error("Unexpected value"); - } - } - - err = nc_close(ncid_out); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_rename_att - * try with bad netCDF handle, check error - * try with bad variable handle, check error - * try with nonexisting att name, check error - * try renaming to existing att name, check error - * check that proper rename worked with nc_inq_attid - * try in data mode, check error - */ -void -test_nc_rename_att(void) -{ - int ncid; - int varid; - int err; - int i; - int j; - size_t k; - int attnum; - char *attname; - char name[NC_MAX_NAME]; - char oldname[NC_MAX_NAME]; - char newname[NC_MAX_NAME]; - int nok = 0; /* count of valid comparisons */ - nc_type datatype; - nc_type atttype; - size_t length; - size_t attlength; - signed char text[MAX_NELS]; - double value[MAX_NELS]; - double expect; - - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - err = nc_rename_att(ncid, BAD_VARID, "abc", "newName"); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - def_dims(ncid); - def_vars(ncid); - put_atts(ncid); - - for (i = -1; i < numVars; i++) { - varid = VARID(i); - for (j = 0; j < NATTS(i); j++) { - attname = ATT_NAME(i,j); - err = nc_rename_att(BAD_ID, varid, attname, "newName"); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_rename_att(ncid, varid, "noSuch", "newName"); - IF (err != NC_ENOTATT) - error("bad attname: status = %d", err); - (void) strcpy(newname, "new_"); - (void) strcat(newname, attname); - err = nc_rename_att(ncid, varid, attname, newname); - IF (err) - error("nc_rename_att: %s", nc_strerror(err)); - err = nc_inq_attid(ncid, varid, newname, &attnum); - IF (err) - error("nc_inq_attid: %s", nc_strerror(err)); - IF (attnum != j) - error("Unexpected attnum"); - } - } - - /* Close. Reopen & check */ - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = file_open(scratch, NC_WRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - - for (i = -1; i < numVars; i++) { - varid = VARID(i); - for (j = 0; j < NATTS(i); j++) { - attname = ATT_NAME(i,j); - atttype = ATT_TYPE(i,j); - attlength = ATT_LEN(i,j); - (void) strcpy(newname, "new_"); - (void) strcat(newname, attname); - err = nc_inq_attname(ncid, varid, j, name); - IF (err) - error("nc_inq_attname: %s", nc_strerror(err)); - IF (strcmp(name, newname) != 0) - error("nc_inq_attname: unexpected name"); - err = nc_inq_att(ncid, varid, name, &datatype, &length); - IF (err) - error("nc_inq_att: %s", nc_strerror(err)); - IF (datatype != atttype) - error("nc_inq_att: unexpected type"); - IF (length != attlength) - error("nc_inq_att: unexpected length"); - if (datatype == NC_CHAR) { - err = nc_get_att_text(ncid, varid, name, text); - IF (err) - error("nc_get_att_text: %s", nc_strerror(err)); - for (k = 0; k < attlength; k++) { - expect = hash(datatype, -1, &k); - IF (text[k] != expect) { - error("nc_get_att_text: unexpected value"); - } else { - nok++; - } - } - } else { - err = nc_get_att_double(ncid, varid, name, value); - IF (err) - error("nc_get_att_double: %s", nc_strerror(err)); - for (k = 0; k < attlength; k++) { - expect = hash(datatype, -1, &k); - if (inRange(expect, datatype)) { - IF (!equal(value[k],expect,datatype,NCT_DOUBLE)) { - error("nc_get_att_double: unexpected value"); - } else { - nok++; - } - } - } - } - } - } - print_nok(nok); - - /* Now in data mode */ - /* Try making names even longer. Then restore original names */ - - for (i = -1; i < numVars; i++) { - varid = VARID(i); - for (j = 0; j < NATTS(i); j++) { - attname = ATT_NAME(i,j); - (void) strcpy(oldname, "new_"); - (void) strcat(oldname, attname); - (void) strcpy(newname, "even_longer_"); - (void) strcat(newname, attname); - err = nc_rename_att(ncid, varid, oldname, newname); - IF (err != NC_ENOTINDEFINE) - error("longer name in data mode: status = %d", err); - err = nc_rename_att(ncid, varid, oldname, attname); - IF (err) - error("nc_rename_att: %s", nc_strerror(err)); - err = nc_inq_attid(ncid, varid, attname, &attnum); - IF (err) - error("nc_inq_attid: %s", nc_strerror(err)); - IF (attnum != j) - error("Unexpected attnum"); - } - } - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_del_att - * try with bad netCDF handle, check error - * try with bad variable handle, check error - * try with nonexisting att name, check error - * check that proper delete worked using: - * nc_inq_attid, nc_inq_natts, nc_inq_varnatts - */ -void -test_nc_del_att(void) -{ - int ncid; - int err; - int i; - int j; - int attnum; - int natts; - int numatts; - int varid; - char *name; /* of att */ - - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - err = nc_del_att(ncid, BAD_VARID, "abc"); - IF (err != NC_ENOTVAR) - error("bad var id: status = %d", err); - def_dims(ncid); - def_vars(ncid); - put_atts(ncid); - - for (i = -1; i < numVars; i++) { - varid = VARID(i); - numatts = NATTS(i); - for (j = 0; j < numatts; j++) { - name = ATT_NAME(i,j); - err = nc_del_att(BAD_ID, varid, name); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - err = nc_del_att(ncid, varid, "noSuch"); - IF (err != NC_ENOTATT) - error("bad attname: status = %d", err); - err = nc_del_att(ncid, varid, name); - IF (err) - error("nc_del_att: %s", nc_strerror(err)); - err = nc_inq_attid(ncid, varid, name, &attnum); - IF (err != NC_ENOTATT) - error("bad attname: status = %d", err); - if (i < 0) { - err = nc_inq_natts(ncid, &natts); - IF (err) - error("nc_inq_natts: %s", nc_strerror(err)); - IF (natts != numatts-j-1) - error("natts: expected %d, got %d", numatts-j-1, natts); - } - err = nc_inq_varnatts(ncid, varid, &natts); - IF (err) - error("nc_inq_varnatts: %s", nc_strerror(err)); - IF (natts != numatts-j-1) - error("natts: expected %d, got %d", numatts-j-1, natts); - } - } - - /* Close. Reopen & check no attributes left */ - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = file_open(scratch, NC_WRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - err = nc_inq_natts(ncid, &natts); - IF (err) - error("nc_inq_natts: %s", nc_strerror(err)); - IF (natts != 0) - error("natts: expected %d, got %d", 0, natts); - for (i = -1; i < numVars; i++) { - varid = VARID(i); - err = nc_inq_varnatts(ncid, varid, &natts); - IF (err) - error("nc_inq_natts: %s", nc_strerror(err)); - IF (natts != 0) - error("natts: expected %d, got %d", 0, natts); - } - - /* restore attributes. change to data mode. try to delete */ - err = nc_redef(ncid); - IF (err) - error("nc_redef: %s", nc_strerror(err)); - put_atts(ncid); - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - - for (i = -1; i < numVars; i++) { - varid = VARID(i); - numatts = NATTS(i); - for (j = 0; j < numatts; j++) { - name = ATT_NAME(i,j); - err = nc_del_att(ncid, varid, name); - IF (err != NC_ENOTINDEFINE) - error("in data mode: status = %d", err); - } - } - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - - -/* - * Test nc_set_fill - * try with bad netCDF handle, check error - * try in read-only mode, check error - * try with bad new_fillmode, check error - * try in data mode, check error - * check that proper set to NC_FILL works for record & non-record variables - * (note that it is not possible to test NC_NOFILL mode!) - * close file & create again for test using attribute _FillValue - */ -void -test_nc_set_fill(void) -{ - int ncid; - int varid; - int err; - int i; - int j; - int old_fillmode; - int nok = 0; /* count of valid comparisons */ - char text = 0; - double value = 0; - double fill; - size_t index[MAX_RANK]; - - /* bad ncid */ - err = nc_set_fill(BAD_ID, NC_NOFILL, &old_fillmode); - IF (err != NC_EBADID) - error("bad ncid: status = %d", err); - - /* try in read-only mode */ - err = file_open(testfile, NC_NOWRITE, &ncid); - IF (err) - error("nc_open: %s", nc_strerror(err)); - err = nc_set_fill(ncid, NC_NOFILL, &old_fillmode); - IF (err != NC_EPERM) - error("read-only: status = %d", err); - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - - /* create scratch */ - err = file_create(scratch, NC_NOCLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - - /* BAD_FILLMODE */ - err = nc_set_fill(ncid, BAD_FILLMODE, &old_fillmode); - IF (err != NC_EINVAL) - error("bad fillmode: status = %d", err); - - /* proper calls */ - err = nc_set_fill(ncid, NC_NOFILL, &old_fillmode); - IF (err) - error("nc_set_fill: %s", nc_strerror(err)); - IF (old_fillmode != NC_FILL) - error("Unexpected old fill mode: %d", old_fillmode); - err = nc_set_fill(ncid, NC_FILL, &old_fillmode); - IF (err) - error("nc_set_fill: %s", nc_strerror(err)); - IF (old_fillmode != NC_NOFILL) - error("Unexpected old fill mode: %d", old_fillmode); - - /* define dims & vars */ - def_dims(ncid); - def_vars(ncid); - - /* Change to data mode. Set fillmode again */ - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - err = nc_set_fill(ncid, NC_FILL, &old_fillmode); - IF (err) - error("nc_set_fill: %s", nc_strerror(err)); - IF (old_fillmode != NC_FILL) - error("Unexpected old fill mode: %d", old_fillmode); - - /* Write record number NRECS to force writing of preceding records */ - /* Assumes variable cr is char vector with UNLIMITED dimension */ - err = nc_inq_varid(ncid, "cr", &varid); - IF (err) - error("nc_inq_varid: %s", nc_strerror(err)); - index[0] = NRECS; - err = nc_put_var1_text(ncid, varid, index, &text); - IF (err) - error("nc_put_var1_text: %s", nc_strerror(err)); - - /* get all variables & check all values equal default fill */ - for (i = 0; i < numVars; i++) { - switch (var_type[i]) { - case NC_CHAR: fill = NC_FILL_CHAR; break; - case NC_BYTE: fill = NC_FILL_BYTE; break; - case NC_SHORT: fill = NC_FILL_SHORT; break; - case NC_INT: fill = NC_FILL_INT; break; - case NC_FLOAT: fill = NC_FILL_FLOAT; break; - case NC_DOUBLE: fill = NC_FILL_DOUBLE; break; - default: assert(0); - } - for (j = 0; j < var_nels[i]; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase"); - if (var_type[i] == NC_CHAR) { - err = nc_get_var1_text(ncid, i, index, &text); - IF (err) - error("nc_get_var1_text failed: %s", nc_strerror(err)); - value = text; - } else { - err = nc_get_var1_double(ncid, i, index, &value); - IF (err) - error("nc_get_var1_double failed: %s", nc_strerror(err)); - } - IF (value != fill && fabs((fill - value)/fill) > DBL_EPSILON) - error("\n\t\tValue expected: %-23.17e,\n\t\t read: %-23.17e\n", - fill, value); - else - nok++; - } - } - - /* close scratch & create again for test using attribute _FillValue */ - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = file_create(scratch, NC_CLOBBER, &ncid); - IF (err) { - error("nc_create: %s", nc_strerror(err)); - return; - } - def_dims(ncid); - def_vars(ncid); - - /* set _FillValue = 42 for all vars */ - text = fill = 42; - for (i = 0; i < numVars; i++) { - if (var_type[i] == NC_CHAR) { - err = nc_put_att_text(ncid, i, "_FillValue", 1, &text); - IF (err) - error("nc_put_att_text: %s", nc_strerror(err)); - } else { - err = nc_put_att_double(ncid, i, "_FillValue",var_type[i],1,&fill); - IF (err) - error("nc_put_att_double: %s", nc_strerror(err)); - } - } - - /* data mode. write records */ - err = nc_enddef(ncid); - IF (err) - error("nc_enddef: %s", nc_strerror(err)); - index[0] = NRECS; - err = nc_put_var1_text(ncid, varid, index, &text); - IF (err) - error("nc_put_var1_text: %s", nc_strerror(err)); - - /* get all variables & check all values equal 42 */ - for (i = 0; i < numVars; i++) { - for (j = 0; j < var_nels[i]; j++) { - err = toMixedBase(j, var_rank[i], var_shape[i], index); - IF (err) - error("error in toMixedBase"); - if (var_type[i] == NC_CHAR) { - err = nc_get_var1_text(ncid, i, index, &text); - IF (err) - error("nc_get_var1_text failed: %s", nc_strerror(err)); - value = text; - } else { - err = nc_get_var1_double(ncid, i, index, &value); - IF (err) - error("nc_get_var1_double failed: %s", nc_strerror(err)); - } - IF (value != fill) - error(" Value expected: %g, read: %g\n", fill, value); - else - nok++; - } - } - print_nok(nok); - - err = nc_close(ncid); - IF (err) - error("nc_close: %s", nc_strerror(err)); - err = remove(scratch); - IF (err) - error("remove of %s failed", scratch); -} - -/* This function gets the version of a netCDF file, 1 is for netCDF - classic, 2 for 64-bit offset format, (someday) 3 for HDF5 format, - 5 for 64-bit data format (CDF-5). -*/ -#define MAGIC_NUM_LEN 4 -static -int -nc_get_file_version(char *path, int *version) -{ - FILE *fp; - char magic[MAGIC_NUM_LEN]; - - /* Need two valid pointers - check for NULL. */ - if (!version || !path) - return NC_EINVAL; - - /* Figure out if this is a netcdf or hdf5 file. */ - if (!(fp = fopen(path, "r")) || - fread(magic, MAGIC_NUM_LEN, 1, fp) != 1) { - fclose(fp); - return errno; - } - fclose(fp); - if (strncmp(magic, "CDF", MAGIC_NUM_LEN-1)==0) - { - if (magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CLASSIC || - magic[MAGIC_NUM_LEN-1] == NC_FORMAT_64BIT_OFFSET || - magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF5) - *version = magic[MAGIC_NUM_LEN-1]; - else - return NC_ENOTNC; - } - /* tomorrow, tomorrow, I love you tomorrow, you're always a day - away! */ - /*if (magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F') - *version = 3;*/ - return NC_NOERR; -} - -/* - * Test nc_set_default_format - * try with bad default format - * try with NULL old_formatp - * try in data mode, check error - * check that proper set to NC_FILL works for record & non-record variables - * (note that it is not possible to test NC_NOFILL mode!) - * close file & create again for test using attribute _FillValue - */ -void -test_nc_set_default_format(void) -{ - int ncid; - int err; - int i; - int version; - int old_format; - - /* bad format */ - err = nc_set_default_format(BAD_DEFAULT_FORMAT, &old_format); - IF (err != NC_EINVAL) - error("bad default format: status = %d", err); - - /* NULL old_formatp */ - err = nc_set_default_format(NC_FORMAT_64BIT_OFFSET, NULL); - IF (err) - error("null old_fortmatp: status = %d", err); - - /* Cycle through available formats. */ - for(i=NC_FORMAT_CLASSIC; i +#endif + +#include /* open() */ +#include /* open() */ +#include /* open() */ +#ifdef _MSC_VER +#include +#else +#include /* read() */ +#endif + +#include "tests.h" +#include "math.h" + +define(`EXPECT_ERR',`error("expecting $1 but got %s",nc_err_code_name($2));')dnl + +define(`IntType', `ifdef(`PNETCDF',`MPI_Offset',`size_t')')dnl +define(`PTRDType',`ifdef(`PNETCDF',`MPI_Offset',`ptrdiff_t')')dnl +define(`TestFunc',`ifdef(`PNETCDF',`test_ncmpi_$1',`test_nc_$1')')dnl +define(`APIFunc', `ifdef(`PNETCDF',`ncmpi_$1',`nc_$1')')dnl + +define(`FileOpen', `ifdef(`PNETCDF',`ncmpi_open(comm, $1, $2, info, $3)', `file_open($1, $2, $3)')')dnl +define(`FileCreate',`ifdef(`PNETCDF',`ncmpi_create(comm, $1, $2, info, $3)', `file_create($1, $2, $3)')')dnl +define(`FileDelete',`ifdef(`PNETCDF',`ncmpi_delete($1,$2)',`nc_delete($1)')')dnl + +define(`Def_Vars', `ifdef(`PNETCDF',`def_vars($1,$2)',`def_vars($1)')')dnl +define(`Put_Atts', `ifdef(`PNETCDF',`put_atts($1,$2,$3)',`put_atts($1)')')dnl +define(`Put_Vars', `ifdef(`PNETCDF',`put_vars($1,$2)',`put_vars($1)')')dnl +define(`Check_File',`ifdef(`PNETCDF',`check_file($1,$2,$3)',`check_file($1)')')dnl +define(`Check_Atts',`ifdef(`PNETCDF',`check_atts($1,$2,$3)',`check_atts($1)')')dnl +define(`Check_Vars',`ifdef(`PNETCDF',`check_vars($1,$2)',`check_vars($1)')')dnl +define(`VarArgs', `ifdef(`PNETCDF',`int numVars',`void')')dnl +define(`AttVarArgs',`ifdef(`PNETCDF',`int numGatts, int numVars',`void')')dnl + +define(`GetVar1TYPE',`ifdef(`PNETCDF',`ncmpi_get_var1_$1_all',`nc_get_var1_$1')')dnl +define(`PutVar1TYPE',`ifdef(`PNETCDF',`ncmpi_put_var1_$1_all',`nc_put_var1_$1')')dnl + +define(`PutVar1', `ifdef(`PNETCDF',`ncmpi_put_var1_all($1,$2,$3,$4,$5,$6)', `nc_put_var1($1,$2,$3,$4)')')dnl +define(`PutVar', `ifdef(`PNETCDF',`ncmpi_put_var_all( $1,$2,$3,$4,$5)', `nc_put_var( $1,$2,$3)')')dnl +define(`PutVara', `ifdef(`PNETCDF',`ncmpi_put_vara_all($1,$2,$3,$4,$5,$6,$7)', `nc_put_vara($1,$2,$3,$4,$5)')')dnl +define(`PutVars', `ifdef(`PNETCDF',`ncmpi_put_vars_all($1,$2,$3,$4,$5,$6,$7,$8)', `nc_put_vars($1,$2,$3,$4,$5,$6)')')dnl +define(`PutVarm', `ifdef(`PNETCDF',`ncmpi_put_varm_all($1,$2,$3,$4,$5,$6,$7,$8,$9)', `nc_put_varm($1,$2,$3,$4,$5,$6,$7)')')dnl + + +/* + * Test APIFunc(create) + * For mode in NC_NOCLOBBER, NC_CLOBBER do: + * create netcdf file 'scratch.nc' with no data, close it + * test that it can be opened, do APIFunc(inq) to check nvars = 0, etc. + * Try again in NC_NOCLOBBER mode, check error return + * On exit, delete this file + */ +int +TestFunc(create)(void) +{ + int clobber; /* 0 for NC_NOCLOBBER, 1 for NC_CLOBBER */ + int err; + int ncid; + int ndims; /* number of dimensions */ + int nvars; /* number of variables */ + int ngatts; /* number of global attributes */ + int recdim; /* id of unlimited dimension */ + int nok=0; + + for (clobber = 0; clobber < 2; clobber++) { + err = FileCreate(scratch, clobber ? NC_CLOBBER : NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) + error("create: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileOpen(scratch, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(inq)(ncid, &ndims, &nvars, &ngatts, &recdim); + IF (err != NC_NOERR) + error("inq: %s", APIFunc(strerror)(err)); + else IF (ndims != 0) + error("inq: wrong number of dimensions returned, %d", ndims); + else IF (nvars != 0) + error("inq: wrong number of variables returned, %d", nvars); + else IF (ngatts != 0) + error("inq: wrong number of global atts returned, %d", ngatts); + else IF (recdim != -1) + error("inq: wrong record dimension ID returned, %d", recdim); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + } + + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_EEXIST) + error("expecting NC_EEXIST but got %s", nc_err_code_name(err)); + ELSE_NOK + + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test APIFunc(redef) + * (In fact also tests APIFunc(enddef) - called from TestFunc(enddef)) + * BAD_ID + * attempt redef (error) & enddef on read-only file + * create file, define dims & vars. + * attempt put var (error) + * attempt redef (error) & enddef. + * put vars + * attempt def new dims (error) + * redef + * def new dims, vars. + * put atts + * enddef + * put vars + * close + * check file: vars & atts + * check reopening with NC_WRITE and adding new dims, atts, vars + */ +int +TestFunc(redef)(AttVarArgs) +{ + int ncid; /* netcdf id */ + /* used to force effective test of ncio->move() in redef */ + IntType sizehint = 8192; + int dimid; /* dimension id */ + int varid; /* variable id */ + int varid1; /* variable id */ + int nok=0, err; + const char * title = "Not funny"; + double var; + char name[NC_MAX_NAME]; + IntType length; + int fmt_variant1, fmt_variant2; + + /* BAD_ID tests */ + err = APIFunc(redef)(BAD_ID); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(enddef)(BAD_ID); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* read-only tests */ + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(redef)(ncid); + IF (err != NC_EPERM) + error("expecting NC_EPERM but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(enddef)(ncid); + IF (err != NC_ENOTINDEFINE) + error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + /* tests using scratch file */ +ifdef(`PNETCDF',`dnl + err = FileCreate(scratch, NC_NOCLOBBER, &ncid);',`dnl + err = file__create(scratch, NC_NOCLOBBER, 0, &sizehint, &ncid);') + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } +ifdef(`PNETCDF',,`dnl + /* limit for ncio implementations which have infinite chunksize */ + if(sizehint > 32768) sizehint = 16384;') + def_dims(ncid); + Def_Vars(ncid, numVars); + Put_Atts(ncid, numGatts, numVars); + err = APIFunc(inq_varid)(ncid, "d", &varid); + IF (err != NC_NOERR) + error("inq_varid: %s", APIFunc(strerror)(err)); + var = 1.0; + +ifdef(`PNETCDF', ` + err = ncmpi_begin_indep_data(ncid); + IF (err != NC_EINDEFINE) + error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err));')dnl + + err = PutVar1TYPE(double)(ncid, varid, NULL, &var); + IF (err != NC_EINDEFINE) + error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err)); + +ifdef(`PNETCDF', ` + err = ncmpi_end_indep_data(ncid); + IF (err != NC_ENOTINDEP) + error("expecting NC_ENOTINDEP but got %s", nc_err_code_name(err));')dnl + + err = APIFunc(redef)(ncid); + IF (err != NC_EINDEFINE) + error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + ELSE_NOK + Put_Vars(ncid, numVars); + err = APIFunc(def_dim)(ncid, "abc", sizehint, &dimid); + IF (err != NC_ENOTINDEFINE) + error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); + err = APIFunc(redef)(ncid); + IF (err != NC_NOERR) + error("redef: %s", APIFunc(strerror)(err)); + ELSE_NOK + + err = APIFunc(set_fill)(ncid, NC_NOFILL, NULL); + IF (err != NC_NOERR) + error("set_fill: %s", APIFunc(strerror)(err)); + + err = APIFunc(def_dim)(ncid, "abc", sizehint, &dimid); + IF (err != NC_NOERR) + error("def_dim: %s", APIFunc(strerror)(err)); + err = APIFunc(def_var)(ncid, "abcScalar", NC_INT, 0, NULL, &varid); + IF (err != NC_NOERR) + error("def_var: %s", APIFunc(strerror)(err)); + err = APIFunc(def_var)(ncid, "abc", NC_INT, 1, &dimid, &varid1); + IF (err != NC_NOERR) + error("def_var: %s", APIFunc(strerror)(err)); + { + int dimids[NDIMS +1]; + int ii = 0; + for(ii = 0; ii < NDIMS; ii++) dimids[ii] = ii; + dimids[NDIMS] = dimid; + err = APIFunc(def_var)(ncid, "abcRec", NC_INT, NDIMS, dimids, &varid1); + IF (err != NC_NOERR) + error("def_var: %s", APIFunc(strerror)(err)); + } + err = APIFunc(put_att_text)(ncid, NC_GLOBAL, "title", 1+strlen(title), title); + IF (err != NC_NOERR) + error("put_att_text: %s", APIFunc(strerror)(err)); + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + ELSE_NOK + var = 1.0; + +ifdef(`PNETCDF', ` + err = ncmpi_end_indep_data(ncid); + IF (err != NC_ENOTINDEP) + error("expecting NC_ENOTINDEP but got %s", nc_err_code_name(err));')dnl + + err = PutVar1TYPE(double)(ncid, varid, NULL, &var); + IF (err != NC_NOERR) + error("put_var1_double: %s", APIFunc(strerror)(err)); + err = APIFunc(inq_format)(ncid, &fmt_variant1); + IF (err) + error("inq_format: %s", APIFunc(strerror)(err)); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + /* check scratch file written as expected */ + Check_File(scratch, numGatts, numVars); /* checks all except "abc" stuff added above */ + + IF ((err = FileOpen(scratch, NC_NOWRITE, &ncid))) + error("open: %s", APIFunc(strerror)(err)); + IF ((err = APIFunc(inq_dim)(ncid, dimid, name, &length))) + error("inq_dim: %s", APIFunc(strerror)(err)); + IF (strcmp(name, "abc") != 0) + error("Unexpected dim name"); + IF (length != sizehint) + error("Unexpected dim length"); + IF ((err = GetVar1TYPE(double)(ncid, varid, NULL, &var))) + error("get_var1_double: %s", APIFunc(strerror)(err)); + IF (var != 1.0) + error("get_var1_double: unexpected value"); + IF ((err = APIFunc(close)(ncid))) + error("close: %s", APIFunc(strerror)(err)); + + /* open scratch file for writing, add another dim, var, att, then check */ + IF ((err = FileOpen(scratch, NC_WRITE, &ncid))) + error("open: %s", APIFunc(strerror)(err)); + IF ((err = APIFunc(redef)(ncid))) + error("redef: %s", APIFunc(strerror)(err)); + IF ((err = APIFunc(def_dim)(ncid, "def", sizehint, &dimid))) + error("def_dim: %s", APIFunc(strerror)(err)); + IF ((err = APIFunc(def_var)(ncid, "defScalar", NC_INT, 0, NULL, &varid))) + error("def_var: %s", APIFunc(strerror)(err)); + IF ((err = APIFunc(def_var)(ncid, "def", NC_INT, 1, &dimid, &varid1))) + error("def_var: %s", APIFunc(strerror)(err)); + IF ((err = APIFunc(put_att_text)(ncid, NC_GLOBAL, "Credits", 1+strlen("Thanks!"), "Thanks!"))) + error("put_att_text: %s", APIFunc(strerror)(err)); + IF ((err = APIFunc(enddef)(ncid))) + error("enddef: %s", APIFunc(strerror)(err)); + var = 2.0; + IF ((err = PutVar1TYPE(double)(ncid, varid, NULL, &var))) + error("put_var1_double: %s", APIFunc(strerror)(err)); + IF ((err = APIFunc(close)(ncid))) + error("close: %s", APIFunc(strerror)(err)); + + /* check scratch file written as expected */ + Check_File(scratch, numGatts, numVars); + + err = FileOpen(scratch, NC_NOWRITE, &ncid); + IF (err) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(inq_dim)(ncid, dimid, name, &length); + IF (err) + error("inq_dim: %s", APIFunc(strerror)(err)); + IF (strcmp(name, "def") != 0) + error("Unexpected dim name"); + IF (length != sizehint) + error("Unexpected dim length"); + err = GetVar1TYPE(double)(ncid, varid, NULL, &var); + IF (err) + error("get_var1_double: %s", APIFunc(strerror)(err)); + IF (var != 2.0) + error("get_var1_double: unexpected value"); + /* make sure format variant hasn't changed from when created */ + err = APIFunc(inq_format)(ncid, &fmt_variant2); + IF (err) + error("inq_format: %s", APIFunc(strerror)(err)); + IF (fmt_variant1 != fmt_variant2) + error("enddef changed format variant"); + err = APIFunc(close)(ncid); + IF (err) + error("close: %s", APIFunc(strerror)(err)); + + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test APIFunc(enddef) + * Simply calls TestFunc(redef) which tests both APIFunc(redef) & APIFunc(enddef) + */ +int +TestFunc(enddef)(AttVarArgs) +{ + ifdef(`PNETCDF', + `return test_ncmpi_redef(numGatts, numVars);', + `return test_nc_redef();') +} + + +/* + * Test APIFunc(sync) + * try with bad handle, check error + * try in define mode, check error + * try writing with one handle, reading with another on same netCDF + */ +int +TestFunc(sync)(AttVarArgs) +{ + int ncidw; /* netcdf id for writing */ + int ncidr; /* netcdf id for reading */ + int nok=0, err; + + /* BAD_ID test */ + err = APIFunc(sync)(BAD_ID); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* create scratch file & try APIFunc(sync) in define mode */ + err = FileCreate(scratch, NC_NOCLOBBER, &ncidw); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + err = APIFunc(sync)(ncidw); + IF (err != NC_EINDEFINE) + error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* write using same handle */ + def_dims(ncidw); + Def_Vars(ncidw, numVars); + Put_Atts(ncidw, numGatts, numVars); + err = APIFunc(enddef)(ncidw); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + Put_Vars(ncidw, numVars); + err = APIFunc(sync)(ncidw); + IF (err != NC_NOERR) + error("sync of ncidw failed: %s", APIFunc(strerror)(err)); + ELSE_NOK + + /* open another handle, APIFunc(sync), read (check) */ + err = FileOpen(scratch, NC_NOWRITE, &ncidr); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(sync)(ncidr); + IF (err != NC_NOERR) + error("sync of ncidr failed: %s", APIFunc(strerror)(err)); + ELSE_NOK + check_dims(ncidr); + Check_Atts(ncidr, numGatts, numVars); + Check_Vars(ncidr, numVars); + + /* close both handles */ + err = APIFunc(close)(ncidr); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = APIFunc(close)(ncidw); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test APIFunc(abort) + * try with bad handle, check error + * try in define mode before anything written, check that file was deleted + * try after APIFunc(enddef), APIFunc(redef), define new dims, vars, atts + * try after writing variable + */ +int +TestFunc(abort)(AttVarArgs) +{ + int ncid; /* netcdf id */ + int err; + int ndims; + int nvars; + int ngatts; + int nok=0; + + /* BAD_ID test */ + err = APIFunc(abort)(BAD_ID); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* create scratch file & try APIFunc(abort) in define mode */ + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + def_dims(ncid); + Def_Vars(ncid, numVars); + Put_Atts(ncid, numGatts, numVars); + err = APIFunc(abort)(ncid); + IF (err != NC_NOERR) + error("abort of ncid failed: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(close)(ncid); /* should already be closed */ + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + err = FileDelete(scratch, info); /* should already be deleted */ +ifdef(`PNETCDF', + `IF (err != NC_ENOENT && err != NC_EFILE) + error("expecting NC_ENOENT or NC_EFILE but got %s", nc_err_code_name(err));', + `IF (err != ENOENT && err != NC_EIO) + error("expecting ENOENT or NC_EIO but got %s", nc_err_code_name(err));')dnl + + /* + * create scratch file + * do APIFunc(enddef) & APIFunc(redef) + * define new dims, vars, atts + * try APIFunc(abort): should restore previous state (no dims, vars, atts) + */ + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + err = APIFunc(redef)(ncid); + IF (err != NC_NOERR) + error("redef: %s", APIFunc(strerror)(err)); + def_dims(ncid); + Def_Vars(ncid, numVars); + Put_Atts(ncid, numGatts, numVars); + err = APIFunc(abort)(ncid); + IF (err != NC_NOERR) + error("abort of ncid failed: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(close)(ncid); /* should already be closed */ + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + err = FileOpen(scratch, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(inq)(ncid, &ndims, &nvars, &ngatts, NULL); + IF (err != NC_NOERR) + error("inq: %s", APIFunc(strerror)(err)); + IF (ndims != 0) + error("ndims should be 0"); + IF (nvars != 0) + error("nvars should be 0"); + IF (ngatts != 0) + error("ngatts should be 0"); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + /* try APIFunc(abort) in data mode - should just close */ + err = FileCreate(scratch, NC_CLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + def_dims(ncid); + Def_Vars(ncid, numVars); + Put_Atts(ncid, numGatts, numVars); + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + Put_Vars(ncid, numVars); + err = APIFunc(abort)(ncid); + IF (err != NC_NOERR) + error("abort of ncid failed: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(close)(ncid); /* should already be closed */ + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + Check_File(scratch, numGatts, numVars); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test APIFunc(def_dim) + * try with bad netCDF handle, check error + * try in data mode, check error + * check that returned id is one more than previous id + * try adding same dimension twice, check error + * try with illegal sizes, check error + * make sure unlimited size works, shows up in APIFunc(inq_unlimdim) + * try to define a second unlimited dimension, check error + */ +int +TestFunc(def_dim)(VarArgs) +{ + int ncid; + int err; /* status */ + int i, nok=0; + int dimid; /* dimension id */ + IntType length; + + /* BAD_ID test */ + err = APIFunc(def_dim)(BAD_ID, "abc", 8, &dimid); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* data mode test */ + err = FileCreate(scratch, NC_CLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + err = APIFunc(def_dim)(ncid, "abc", 8, &dimid); + IF (err != NC_ENOTINDEFINE) + error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* define-mode tests: unlimited dim */ + err = APIFunc(redef)(ncid); + IF (err != NC_NOERR) + error("redef: %s", APIFunc(strerror)(err)); + err = APIFunc(def_dim)(ncid, dim_name[0], NC_UNLIMITED, &dimid); + IF (err != NC_NOERR) + error("def_dim: %s", APIFunc(strerror)(err)); + ELSE_NOK + IF (dimid != 0) + error("Unexpected dimid"); + ELSE_NOK + err = APIFunc(inq_unlimdim)(ncid, &dimid); + IF (err != NC_NOERR) + error("inq_unlimdim: %s", APIFunc(strerror)(err)); + IF (dimid != 0) + error("Unexpected recdim"); + err = APIFunc(inq_dimlen)(ncid, dimid, &length); + IF (length != 0) + error("Unexpected length"); + err = APIFunc(def_dim)(ncid, "abc", NC_UNLIMITED, &dimid); + IF (err != NC_EUNLIMIT) + error("expecting NC_EUNLIMIT but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* define-mode tests: remaining dims */ + for (i = 1; i < NDIMS; i++) { + err = APIFunc(def_dim)(ncid, dim_name[i-1], dim_len[i], &dimid); + IF (err != NC_ENAMEINUSE) + error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(def_dim)(ncid, BAD_NAME, dim_len[i], &dimid); + IF (err != NC_EBADNAME) + error("expecting NC_EBADNAME but got %s", nc_err_code_name(err)); + ELSE_NOK +ifdef(`PNETCDF', ,`if(sizeof(long) > 4) /* Fix: dmh 11/4/2011: works only if sizeof(long) > 4 */') + { + err = APIFunc(def_dim)(ncid, dim_name[i], (IntType)(NC_UNLIMITED-1), &dimid); + IF (err != NC_EDIMSIZE) + error("expecting NC_EDIMSIZE but got %s", nc_err_code_name(err)); + ELSE_NOK + } + err = APIFunc(def_dim)(ncid, dim_name[i], dim_len[i], &dimid); + IF (err != NC_NOERR) + error("def_dim: %s", APIFunc(strerror)(err)); + ELSE_NOK + IF (dimid != i) + error("Unexpected dimid"); + } + + /* Following just to expand unlimited dim */ + Def_Vars(ncid, numVars); + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + Put_Vars(ncid, numVars); + + /* Check all dims */ + check_dims(ncid); + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test APIFunc(rename_dim) + * try with bad netCDF handle, check error + * check that proper rename worked with APIFunc(inq_dim) + * try renaming to existing dimension name, check error + * try with bad dimension handle, check error + */ +int +TestFunc(rename_dim)(void) +{ + int ncid; + int err, nok=0; /* status */ + char name[NC_MAX_NAME]; + + /* BAD_ID test */ + err = APIFunc(rename_dim)(BAD_ID, 0, "abc"); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* main tests */ + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + def_dims(ncid); + err = APIFunc(rename_dim)(ncid, BAD_DIMID, "abc"); + IF (err != NC_EBADDIM) + error("expecting NC_EBADDIM but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(rename_dim)(ncid, 2, "abc"); + IF (err != NC_NOERR) + error("rename_dim: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(inq_dimname)(ncid, 2, name); + IF (strcmp(name, "abc") != 0) + error("Unexpected name: %s", name); + err = APIFunc(rename_dim)(ncid, 0, "abc"); + IF (err != NC_ENAMEINUSE) + error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err)); + ELSE_NOK + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test APIFunc(def_var) + * try with bad netCDF handle, check error + * try with bad name, check error + * scalar tests: + * check that proper define worked with APIFunc(inq_var) + * try redefining an existing variable, check error + * try with bad datatype, check error + * try with bad number of dimensions, check error + * try in data mode, check error + * check that returned id is one more than previous id + * try with bad dimension ids, check error + */ +int +TestFunc(def_var)(VarArgs) +{ + int ncid; + int varid; + int err, nok=0; /* status */ + int i; + int ndims; + int natts; + char name[NC_MAX_NAME]; + int dimids[MAX_RANK]; + nc_type datatype; + + /* BAD_ID test */ + err = APIFunc(def_var)(BAD_ID, "abc", NC_SHORT, 0, NULL, &varid); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* scalar tests */ + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + err = APIFunc(def_var)(ncid, "abc", NC_SHORT, 0, NULL, &varid); + IF (err != NC_NOERR) + error("def_var: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(inq_var)(ncid, varid, name, &datatype, &ndims, dimids, &natts); + IF (err != NC_NOERR) + error("inq_var: %s", APIFunc(strerror)(err)); + IF (strcmp(name, "abc") != 0) + error("Unexpected name: %s", name); + IF (datatype != NC_SHORT) + error("Unexpected datatype"); + IF (ndims != 0) + error("Unexpected rank"); + err = APIFunc(def_var)(ncid, BAD_NAME, NC_SHORT, 0, NULL, &varid); + IF (err != NC_EBADNAME) + error("expecting NC_EBADNAME but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(def_var)(ncid, "abc", NC_SHORT, 0, NULL, &varid); + IF (err != NC_ENAMEINUSE) + error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(def_var)(ncid, "ABC", BAD_TYPE, -1, dimids, &varid); + IF (err != NC_EBADTYPE) + error("expecting NC_EBADTYPE but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(def_var)(ncid, "ABC", NC_SHORT, -1, dimids, &varid); + IF (err != NC_EINVAL) + error("expecting NC_EINVAL but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + err = APIFunc(def_var)(ncid, "ABC", NC_SHORT, 0, dimids, &varid); + IF (err != NC_ENOTINDEFINE) + error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + + /* general tests using global vars */ + err = FileCreate(scratch, NC_CLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + def_dims(ncid); + for (i = 0; i < numVars; i++) { + err = APIFunc(def_var)(ncid, var_name[i], var_type[i], var_rank[i], + var_dimid[i], &varid); + IF (err != NC_NOERR) + error("def_var: %s", APIFunc(strerror)(err)); + ELSE_NOK + IF (varid != i) + error("Unexpected varid"); + ELSE_NOK + } + + /* try bad dim ids */ + dimids[0] = BAD_DIMID; + err = APIFunc(def_var)(ncid, "abc", NC_SHORT, 1, dimids, &varid); + IF (err != NC_EBADDIM) + error("expecting NC_EBADDIM but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test PutVar1 + */ +int +TestFunc(put_var1)(VarArgs) +{ + int i, err, ncid, nok=0; + IntType j, index[MAX_RANK]; + double value[1]; + double buf[1]; /* (void *) buffer */ + ifdef(`PNETCDF', `MPI_Datatype datatype;') + + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + + def_dims(ncid); + Def_Vars(ncid, numVars); + + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = PutVar1(BAD_ID, 0, NULL, NULL, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutVar1(ncid, BAD_VARID, NULL, NULL, 1, MPI_DATATYPE_NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + value[0] = 5; /* reset to a value within bounds */ + + ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = PutVar1(ncid, i, NULL, value, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK +')dnl + + /* test NC_EINVALCOORDS */ + for (j = 0; j < var_rank[i]; j++) index[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + index[j] = var_shape[i][j]; /* out of boundary check */ + err = PutVar1(ncid, i, index, value, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + index[j] = 0; + } + + for (j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + value[0] = hash(var_type[i], var_rank[i], index); + if (inRange(value[0], var_type[i])) { + err = dbl2nc(value[0], var_type[i], buf); + IF (err != NC_NOERR) + error("error in dbl2nc var:%s type:%s", + var_name[i],s_nc_type(var_type[i])); + err = PutVar1(ncid, i, index, buf, 1, datatype); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + } + } + } + + Check_Vars(ncid, numVars); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test PutVara + * Choose a random point dividing each dim into 2 parts + * Put 2^rank (nslabs) slabs so defined + * Redefine buffer for each put. + * At end check all variables using Check_Vars + */ +int +TestFunc(put_vara)(VarArgs) +{ + int d, i, k, err, nslabs, ncid, nok=0; + IntType j, nels; + IntType start[MAX_RANK]; + IntType edge[MAX_RANK]; + IntType index[MAX_RANK]; + IntType mid[MAX_RANK]; + double buf[MAX_NELS]; /* (void *) buffer */ + char *p; /* (void *) pointer */ + double value; + ifdef(`PNETCDF', `MPI_Datatype datatype;') + + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + + def_dims(ncid); + Def_Vars(ncid, numVars); + + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = PutVara(BAD_ID, 0, start, edge, buf, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutVara(ncid, BAD_VARID, start, edge, buf, 1, MPI_DATATYPE_NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + buf[0] = 5; /* reset to a value within bounds */ + + /* check if can detect a bad file ID */ + err = PutVara(BAD_ID, i, start, edge, buf, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') + + for (j = 0; j < var_rank[i]; j++) { + start[j] = 0; + edge[j] = 1; + } + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = PutVara(ncid, i, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + + /* for non-scalar variables, argument count cannot be NULL */ + err = PutVara(ncid, i, start, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EEDGE) { + EXPECT_ERR(NC_EEDGE, err) + } + ELSE_NOK +')dnl + + /* first test when edge[*] > 0 */ + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVara(ncid, i, start, edge, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + edge[j] = var_shape[i][j] + 1; + err = PutVara(ncid, i, start, edge, buf, 1, datatype); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDG, err) + ELSE_NOK + edge[j] = 1; + } + /* Check correct error returned when nothing to put, when edge[*]==0 */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVara(ncid, i, start, edge, buf, 0, datatype); +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + ELSE_NOK + start[j] = var_shape[i][j]+1; /* out of boundary check */ + err = PutVara(ncid, i, start, edge, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + /* Choose a random point dividing each dim into 2 parts */ + /* put 2^rank (nslabs) slabs so defined */ + nslabs = 1; + for (j = 0; j < var_rank[i]; j++) { + mid[j] = roll( var_shape[i][j] ); + nslabs *= 2; + } + /* bits of k determine whether to put lower or upper part of dim */ + for (k = 0; k < nslabs; k++) { + nels = 1; + for (j = 0; j < var_rank[i]; j++) { + if ((k >> j) & 1) { + start[j] = 0; + edge[j] = mid[j]; + }else{ + start[j] = mid[j]; + edge[j] = var_shape[i][j] - mid[j]; + } + nels *= edge[j]; + } + p = (char *) buf; + for (j = 0; j < nels; j++) { + err = toMixedBase(j, var_rank[i], edge, index); + IF (err != 0) error("error in toMixedBase"); + for (d = 0; d < var_rank[i]; d++) + index[d] += start[d]; + value = hash(var_type[i], var_rank[i], index); + if (!inRange(value, var_type[i])) + value = 0; + err = dbl2nc(value, var_type[i], p); + IF (err != NC_NOERR) + error("error in dbl2nc"); + p += nctypelen(var_type[i]); + } + err = PutVara(ncid, i, start, edge, buf, nels, datatype); + IF (err != NC_NOERR) + error("%s", APIFunc(strerror)(err)); + ELSE_NOK + } + } + + Check_Vars(ncid, numVars); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test PutVars + * Choose a random point dividing each dim into 2 parts + * Put 2^rank (nslabs) slabs so defined + * Choose random stride from 1 to edge + * Redefine buffer for each put. + * At end check all variables using Check_Vars + */ +int +TestFunc(put_vars)(VarArgs) +{ + int ncid, d, i, k, err, nslabs, nok=0; + PTRDType nstarts; /* number of different starts */ + IntType j, m, nels; + IntType start[MAX_RANK]; + IntType edge[MAX_RANK]; + IntType index[MAX_RANK]; + IntType index2[MAX_RANK]; + IntType mid[MAX_RANK]; + IntType count[MAX_RANK]; + IntType sstride[MAX_RANK]; + PTRDType stride[MAX_RANK]; + double buf[MAX_NELS]; /* (void *) buffer */ + char *p; /* (void *) pointer */ + double value; + ifdef(`PNETCDF', `MPI_Datatype datatype;') + + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + + def_dims(ncid); + Def_Vars(ncid, numVars); + + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = PutVars(BAD_ID, 0, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutVars(ncid, BAD_VARID, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + buf[0] = 5; /* reset to a value within bounds */ + + /* check if can detect a bad file ID */ + err = PutVars(BAD_ID, i, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') + + for (j = 0; j < var_rank[i]; j++) { + start[j] = 0; + edge[j] = 1; + stride[j] = 1; + } + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = PutVars(ncid, i, NULL, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + + /* for non-scalar variables, argument count cannot be NULL */ + err = PutVars(ncid, i, start, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EEDGE) { + EXPECT_ERR(NC_EEDGE, err) + } + ELSE_NOK +')dnl + + /* first test when edge[*] > 0 */ + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == 0) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + edge[j] = var_shape[i][j] + 1; /* edge error check */ + err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDG, err) + ELSE_NOK + edge[j] = 1; + stride[j] = 0; /* strided edge error check */ + err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); + IF (err != NC_ESTRIDE) + EXPECT_ERR(NC_ESTRIDE, err) + ELSE_NOK + stride[j] = 1; + } + /* Check correct error returned even when nothing to put */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == 0) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVars(ncid, i, start, edge, stride, buf, 0, datatype); +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + ELSE_NOK + start[j] = var_shape[i][j]+1; /* out of boundary check */ + err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + /* Choose a random point dividing each dim into 2 parts */ + /* put 2^rank (nslabs) slabs so defined */ + nslabs = 1; + for (j = 0; j < var_rank[i]; j++) { + mid[j] = roll( var_shape[i][j] ); + nslabs *= 2; + } + /* bits of k determine whether to put lower or upper part of dim */ + /* choose random stride from 1 to edge */ + for (k = 0; k < nslabs; k++) { + nstarts = 1; + for (j = 0; j < var_rank[i]; j++) { + if ((k >> j) & 1) { + start[j] = 0; + edge[j] = mid[j]; + }else{ + start[j] = mid[j]; + edge[j] = var_shape[i][j] - mid[j]; + } + sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + stride[j] = (PTRDType)sstride[j]; + nstarts *= stride[j]; + } + for (m = 0; m < nstarts; m++) { + err = toMixedBase(m, var_rank[i], sstride, index); + IF (err != 0) error("error in toMixedBase"); + nels = 1; + for (j = 0; j < var_rank[i]; j++) { + count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + nels *= count[j]; + index[j] += start[j]; + } + /* Random choice of forward or backward */ +/* TODO + if ( roll(2) ) { + for (j = 0; j < var_rank[i]; j++) { + index[j] += (count[j] - 1) * (IntType)stride[j]; + stride[j] = -stride[j]; + } + } + */ + p = (char *) buf; + for (j = 0; j < nels; j++) { + err = toMixedBase(j, var_rank[i], count, index2); + IF (err != 0) error("error in toMixedBase"); + for (d = 0; d < var_rank[i]; d++) + index2[d] = index[d] + index2[d] * (IntType)stride[d]; + value = hash(var_type[i], var_rank[i], index2); + if (!inRange(value, var_type[i])) + value = 0; + err = dbl2nc(value, var_type[i], p); + IF (err != NC_NOERR) + error("error in dbl2nc"); + p += nctypelen(var_type[i]); + } + err = PutVars(ncid, i, index, count, stride, buf, nels, datatype); + IF (err != NC_NOERR) + EXPECT_ERR(NC_NOERR, err) + ELSE_NOK + } + } + } + + Check_Vars(ncid, numVars); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test PutVarm + * Choose a random point dividing each dim into 2 parts + * Put 2^rank (nslabs) slabs so defined + * Choose random stride from 1 to edge + * Buffer is bit image of whole external variable. + * So all puts for a variable put different elements of buffer + * At end check all variables using Check_Vars + */ +int +TestFunc(put_varm)(VarArgs) +{ + int ncid, nok=0; + int i; + int k; + int err; + int nslabs; + IntType j, m; + PTRDType nstarts; /* number of different starts */ + IntType start[MAX_RANK]; + IntType edge[MAX_RANK]; + IntType index[MAX_RANK]; + IntType mid[MAX_RANK]; + IntType count[MAX_RANK]; + IntType sstride[MAX_RANK]; + PTRDType stride[MAX_RANK]; + PTRDType imap[MAX_RANK]; + PTRDType imap2[MAX_RANK]; + ifdef(`PNETCDF', `IntType bufcount;') + double buf[MAX_NELS]; /* (void *) buffer */ + char *p; /* (void *) pointer */ + double value; + ifdef(`PNETCDF', `MPI_Datatype datatype;') + + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + + def_dims(ncid); + Def_Vars(ncid, numVars); + + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + /* check if can detect a bad file ID */ + err = PutVarm(NC_EBADID, 0, NULL, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + /* check if can detect a bad variable ID */ + err = PutVarm(ncid, BAD_VARID, NULL, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); + IF (err != NC_ENOTVAR) + EXPECT_ERR(NC_ENOTVAR, err) + ELSE_NOK + + for (i = 0; i < numVars; i++) { + assert(var_rank[i] <= MAX_RANK); + assert(var_nels[i] <= MAX_NELS); + + buf[0] = 5; /* reset to a value within bounds */ + + /* check if can detect a bad file ID */ + err = PutVarm(BAD_ID, i, NULL, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL); + IF (err != NC_EBADID) + EXPECT_ERR(NC_EBADID, err) + ELSE_NOK + + ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') + + for (j = 0; j < var_rank[i]; j++) { + start[j] = 0; + edge[j] = 1; + stride[j] = 1; + imap[j] = 1; + } + +ifdef(`PNETCDF',`dnl + /* for non-scalar variables, argument start cannot be NULL */ + err = PutVarm(ncid, i, NULL, NULL, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { /* scalar variable */ + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EINVALCOORDS) { + EXPECT_ERR(NC_EINVALCOORDS, err) + } + ELSE_NOK + + /* for non-scalar variables, argument count cannot be NULL */ + err = PutVarm(ncid, i, start, NULL, NULL, NULL, buf, 1, datatype); + if (var_rank[i] == 0) { + IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) + } + else IF (err != NC_EEDGE) { + EXPECT_ERR(NC_EEDGE, err) + } + ELSE_NOK +')dnl + + /* first test when edge[*] > 0 */ + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == 0) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + edge[j] = var_shape[i][j] + 1; /* edge error check */ + err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); + IF (err != NC_EEDGE) + EXPECT_ERR(NC_EEDG, err) + ELSE_NOK + edge[j] = 1; + stride[j] = 0; /* strided edge error check */ + err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); + IF (err != NC_ESTRIDE) + EXPECT_ERR(NC_ESTRIDE, err) + ELSE_NOK + stride[j] = 1; + } + /* Check correct error returned even when nothing to put */ + for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + + for (j = 0; j < var_rank[i]; j++) { + if (var_dimid[i][j] == 0) continue; /* skip record dim */ + start[j] = var_shape[i][j]; + err = PutVarm(ncid, i, start, edge, stride, imap, buf, 0, datatype); +#ifdef RELAX_COORD_BOUND + IF (err != NC_NOERR) /* allowed when edge[j]==0 */ + EXPECT_ERR(NC_NOERR, err) +#else + IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ + EXPECT_ERR(NC_EINVALCOORDS, err) +#endif + ELSE_NOK + start[j] = var_shape[i][j]+1; /* out of boundary check */ + err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); + IF (err != NC_EINVALCOORDS) + EXPECT_ERR(NC_EINVALCOORDS, err) + ELSE_NOK + start[j] = 0; + } + for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + + if (var_rank[i] > 0) { + int jj = var_rank[i] - 1; + imap[jj] = nctypelen(var_type[i]); /* netCDF considers imap in bytes */ + imap[jj] = 1; /* PnetCDF considers imap in elements */ + for (; jj > 0; jj--) + imap[jj-1] = imap[jj] * (PTRDType)var_shape[i][jj]; + } + p = (char *) buf; + for (j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + value = hash(var_type[i], var_rank[i], index); + if (!inRange(value, var_type[i])) + value = 0; + err = dbl2nc(value, var_type[i], p); + IF (err != NC_NOERR) + error("error in dbl2nc"); + p += nctypelen(var_type[i]); + } + + /* Choose a random point dividing each dim into 2 parts */ + /* put 2^rank (nslabs) slabs so defined */ + nslabs = 1; + for (j = 0; j < var_rank[i]; j++) { + mid[j] = roll( var_shape[i][j] ); + nslabs *= 2; + } + /* bits of k determine whether to put lower or upper part of dim */ + /* choose random stride from 1 to edge */ + for (k = 0; k < nslabs; k++) { + nstarts = 1; + for (j = 0; j < var_rank[i]; j++) { + if ((k >> j) & 1) { + start[j] = 0; + edge[j] = mid[j]; + }else{ + start[j] = mid[j]; + edge[j] = var_shape[i][j] - mid[j]; + } + sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; + stride[j] = (PTRDType)sstride[j]; + imap2[j] = imap[j] * (PTRDType)sstride[j]; + nstarts *= stride[j]; + } + for (m = 0; m < nstarts; m++) { + if (var_rank[i] == 0 && i%2 == 0) { + err = PutVarm(ncid, i, NULL, NULL, NULL, NULL, buf, 1, datatype); + } else { + err = toMixedBase(m, var_rank[i], sstride, index); + IF (err != 0) error("error in toMixedBase"); + for (j = 0; j < var_rank[i]; j++) { + count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + index[j] += start[j]; + } + /* Random choice of forward or backward */ +/* TODO + if ( roll(2) ) { + for (j = 0; j < var_rank[i]; j++) { + index[j] += (count[j] - 1) * (IntType)stride[j]; + stride[j] = -stride[j]; + } + } + */ + j = fromMixedBase(var_rank[i], index, var_shape[i]); + p = (char *) buf + (int)j * nctypelen(var_type[i]); + ifdef(`PNETCDF', `for (bufcount=1,j=0; j 0 && ATT_LEN(i,j) > 0) { + err = APIFunc(rename_att)(ncid_out, i, att_name[i][0], "a"); + IF (err != NC_NOERR) + error("rename_att: %s", APIFunc(strerror)(err)); + err = APIFunc(copy_att)(ncid_out, NC_GLOBAL, "a", ncid_out, i); + IF (err != NC_NOERR) + error("copy_att: %s", APIFunc(strerror)(err)); + ELSE_NOK + } + } + err = APIFunc(close)(ncid_out); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + /* Reopen & check */ + err = FileOpen(scratch, NC_WRITE, &ncid_out); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + for (i = 0; i < numVars; i++) { + if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) { + err = APIFunc(inq_att)(ncid_out, i, "a", &datatype, &length); + IF (err != NC_NOERR) + error("inq_att: %s", APIFunc(strerror)(err)); + IF (datatype != NC_CHAR) + error("Unexpected type"); + IF (length != 1) + error("Unexpected length"); + err = APIFunc(get_att_text)(ncid_out, i, "a", &value); + IF (err != NC_NOERR) + error("get_att_text: %s", APIFunc(strerror)(err)); + IF (value != 'A') + error("Unexpected value"); + } + } + + err = APIFunc(close)(ncid_out); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test APIFunc(rename_att) + * try with bad netCDF handle, check error + * try with bad variable handle, check error + * try with nonexisting att name, check error + * try renaming to existing att name, check error + * check that proper rename worked with APIFunc(inq_attid) + * try in data mode, check error + */ +int +TestFunc(rename_att)(AttVarArgs) +{ + int ncid; + int varid; + int err; + int i; + int j; + IntType k, ndx[1]; + int attnum; + char *attname; + char name[NC_MAX_NAME]; + char oldname[NC_MAX_NAME]; + char newname[NC_MAX_NAME]; + int nok = 0; /* count of valid comparisons */ + nc_type datatype; + nc_type atttype; + IntType length; + IntType attlength; + char text[MAX_NELS]; + double value[MAX_NELS]; + double expect; + + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + err = APIFunc(rename_att)(ncid, BAD_VARID, "abc", "newName"); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + def_dims(ncid); + Def_Vars(ncid, numVars); + Put_Atts(ncid, numGatts, numVars); + + for (i = -1; i < numVars; i++) { + varid = VARID(i); + for (j = 0; j < NATTS(i); j++) { + attname = ATT_NAME(i,j); + err = APIFunc(rename_att)(BAD_ID, varid, attname, "newName"); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(rename_att)(ncid, varid, "noSuch", "newName"); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + ELSE_NOK + strcpy(newname, "new_"); + strcat(newname, attname); + err = APIFunc(rename_att)(ncid, varid, attname, newname); + IF (err != NC_NOERR) + error("rename_att: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(inq_attid)(ncid, varid, newname, &attnum); + IF (err != NC_NOERR) + error("inq_attid: %s", APIFunc(strerror)(err)); + IF (attnum != j) + error("Unexpected attnum"); + } + } + + /* Close. Reopen & check */ + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileOpen(scratch, NC_WRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + + for (i = -1; i < numVars; i++) { + varid = VARID(i); + for (j = 0; j < NATTS(i); j++) { + attname = ATT_NAME(i,j); + atttype = ATT_TYPE(i,j); + attlength = ATT_LEN(i,j); + strcpy(newname, "new_"); + strcat(newname, attname); + err = APIFunc(inq_attname)(ncid, varid, j, name); + IF (err != NC_NOERR) + error("inq_attname: %s", APIFunc(strerror)(err)); + IF (strcmp(name, newname) != 0) + error("inq_attname: unexpected name"); + err = APIFunc(inq_att)(ncid, varid, name, &datatype, &length); + IF (err != NC_NOERR) + error("inq_att: %s", APIFunc(strerror)(err)); + IF (datatype != atttype) + error("inq_att: unexpected type"); + IF (length != attlength) + error("inq_att: unexpected length"); + if (datatype == NC_CHAR) { + err = APIFunc(get_att_text)(ncid, varid, name, text); + IF (err != NC_NOERR) + error("get_att_text: %s", APIFunc(strerror)(err)); + for (k = 0; k < attlength; k++) { + ndx[0] = k; + expect = hash(datatype, -1, ndx); + IF (text[k] != (char)expect) + error("get_att_text: unexpected value"); + } + } else { + err = APIFunc(get_att_double)(ncid, varid, name, value); + IF (err != NC_NOERR) + error("get_att_double: %s", APIFunc(strerror)(err)); + for (k = 0; k < attlength; k++) { + ndx[0] = k; + expect = hash(datatype, -1, ndx); + if (inRange(expect, datatype)) { + IF (!equal(value[k],expect,datatype,NCT_DOUBLE)) + error("get_att_double: unexpected value"); + } + } + } + } + } + + /* Now in data mode */ + /* Try making names even longer. Then restore original names */ + + for (i = -1; i < numVars; i++) { + varid = VARID(i); + for (j = 0; j < NATTS(i); j++) { + attname = ATT_NAME(i,j); + strcpy(oldname, "new_"); + strcat(oldname, attname); + strcpy(newname, "even_longer_"); + strcat(newname, attname); + err = APIFunc(rename_att)(ncid, varid, oldname, newname); + IF (err != NC_ENOTINDEFINE) + error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(rename_att)(ncid, varid, oldname, attname); + IF (err != NC_NOERR) + error("rename_att: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(inq_attid)(ncid, varid, attname, &attnum); + IF (err != NC_NOERR) + error("inq_attid: %s", APIFunc(strerror)(err)); + IF (attnum != j) + error("Unexpected attnum"); + } + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test APIFunc(del_att) + * try with bad netCDF handle, check error + * try with bad variable handle, check error + * try with nonexisting att name, check error + * check that proper delete worked using: + * APIFunc(inq_attid), APIFunc(inq_natts), APIFunc(inq_varnatts) + */ +int +TestFunc(del_att)(AttVarArgs) +{ + int ncid; + int err, nok=0; + int i; + int j; + int attnum; + int natts; + int numatts; + int varid; + char *name; /* of att */ + + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + err = APIFunc(del_att)(ncid, BAD_VARID, "abc"); + IF (err != NC_ENOTVAR) + error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); + ELSE_NOK + def_dims(ncid); + Def_Vars(ncid, numVars); + Put_Atts(ncid, numGatts, numVars); + + for (i = -1; i < numVars; i++) { + varid = VARID(i); + numatts = NATTS(i); + for (j = 0; j < numatts; j++) { + name = ATT_NAME(i,j); + err = APIFunc(del_att)(BAD_ID, varid, name); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(del_att)(ncid, varid, "noSuch"); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + ELSE_NOK + err = APIFunc(del_att)(ncid, varid, name); + IF (err != NC_NOERR) + error("del_att: %s", APIFunc(strerror)(err)); + ELSE_NOK + err = APIFunc(inq_attid)(ncid, varid, name, &attnum); + IF (err != NC_ENOTATT) + error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); + if (i < 0) { + err = APIFunc(inq_natts)(ncid, &natts); + IF (err != NC_NOERR) + error("inq_natts: %s", APIFunc(strerror)(err)); + IF (natts != numatts-j-1) + error("natts: expected %d, got %d", numatts-j-1, natts); + } + err = APIFunc(inq_varnatts)(ncid, varid, &natts); + IF (err != NC_NOERR) + error("inq_natts: %s", APIFunc(strerror)(err)); + IF (natts != numatts-j-1) + error("natts: expected %d, got %d", numatts-j-1, natts); + } + } + + /* Close. Reopen & check no attributes left */ + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileOpen(scratch, NC_WRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(inq_natts)(ncid, &natts); + IF (err != NC_NOERR) + error("inq_natts: %s", APIFunc(strerror)(err)); + IF (natts != 0) + error("natts: expected %d, got %d", 0, natts); + for (i = -1; i < numVars; i++) { + varid = VARID(i); + err = APIFunc(inq_varnatts)(ncid, varid, &natts); + IF (err != NC_NOERR) + error("inq_natts: %s", APIFunc(strerror)(err)); + IF (natts != 0) + error("natts: expected %d, got %d", 0, natts); + } + + /* restore attributes. change to data mode. try to delete */ + err = APIFunc(redef)(ncid); + IF (err != NC_NOERR) + error("redef: %s", APIFunc(strerror)(err)); + Put_Atts(ncid, numGatts, numVars); + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + + for (i = -1; i < numVars; i++) { + varid = VARID(i); + numatts = NATTS(i); + for (j = 0; j < numatts; j++) { + name = ATT_NAME(i,j); + err = APIFunc(del_att)(ncid, varid, name); + IF (err != NC_ENOTINDEFINE) + error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); + ELSE_NOK + } + } + + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + return nok; +} + + +/* + * Test APIFunc(set_fill) + * try with bad netCDF handle, check error + * try in read-only mode, check error + * try with bad new_fillmode, check error + * try in data mode, check error + * check that proper set to NC_FILL works for record & non-record variables + * (note that it is not possible to test NC_NOFILL mode!) + * close file & create again for test using attribute _FillValue + */ +int +TestFunc(set_fill)(VarArgs) +{ + int ncid; + int varid; + int err; + int i; + IntType j; + int old_fillmode; + int nok = 0; /* count of valid comparisons */ + char text = 0; + double value = 0; + double fill; + IntType index[MAX_RANK]; + + /* bad ncid */ + err = APIFunc(set_fill)(BAD_ID, NC_NOFILL, &old_fillmode); + IF (err != NC_EBADID) + error("expecting NC_EBADID but got %s", nc_err_code_name(err)); + + /* try in read-only mode */ + err = FileOpen(testfile, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) + error("open: %s", APIFunc(strerror)(err)); + err = APIFunc(set_fill)(ncid, NC_NOFILL, &old_fillmode); + IF (err != NC_EPERM) + error("expecting NC_EPERM but got %s", nc_err_code_name(err)); + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + + /* create scratch */ + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + + /* BAD_FILLMODE */ + err = APIFunc(set_fill)(ncid, BAD_FILLMODE, &old_fillmode); + IF (err != NC_EINVAL) + error("expecting NC_EINVAL but got %s", nc_err_code_name(err)); + + /* proper calls */ + err = APIFunc(set_fill)(ncid, NC_NOFILL, &old_fillmode); + IF (err != NC_NOERR) + error("set_fill: %s", APIFunc(strerror)(err)); + IF (old_fillmode != NC_NOFILL) + error("Unexpected old fill mode: %d", old_fillmode); + err = APIFunc(set_fill)(ncid, NC_FILL, &old_fillmode); + IF (err != NC_NOERR) + error("set_fill: %s", APIFunc(strerror)(err)); + IF (old_fillmode != NC_NOFILL) + error("Unexpected old fill mode: %d", old_fillmode); + + /* define dims & vars */ + def_dims(ncid); + Def_Vars(ncid, numVars); + + /* Change to data mode. Set fillmode again */ + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + err = APIFunc(set_fill)(ncid, NC_FILL, &old_fillmode); +ifdef(`PNETCDF', + `IF (err != NC_ENOTINDEFINE) + error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));', + `IF (err) + error("nc_set_fill: %s", nc_strerror(err)); + IF (old_fillmode != NC_FILL) + error("Unexpected old fill mode: %d", old_fillmode);')dnl + + /* Write record number NRECS to force writing of preceding records */ + /* Assumes variable cr is char vector with UNLIMITED dimension */ + err = APIFunc(inq_varid)(ncid, "cr", &varid); + IF (err != NC_NOERR) + error("inq_varid: %s", APIFunc(strerror)(err)); + index[0] = NRECS; + +ifdef(`PNETCDF', ` + for (i=0; i<=index[0]; i++) + err = APIFunc(fill_var_rec)(ncid, varid, i);')dnl + + err = PutVar1TYPE(text)(ncid, varid, index, &text); + IF (err != NC_NOERR) + error("put_var1_text_all: %s", APIFunc(strerror)(err)); + + /* get all variables & check all values equal default fill */ + for (i = 0; i < numVars; i++) { + ifdef(`PNETCDF', `if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */') + switch (var_type[i]) { + case NC_CHAR: fill = (double)NC_FILL_CHAR; break; + case NC_BYTE: fill = (double)NC_FILL_BYTE; break; + case NC_SHORT: fill = (double)NC_FILL_SHORT; break; + case NC_INT: fill = (double)NC_FILL_INT; break; + case NC_FLOAT: fill = (double)NC_FILL_FLOAT; break; + case NC_DOUBLE: fill = (double)NC_FILL_DOUBLE; break; + case NC_UBYTE: fill = (double)NC_FILL_UBYTE; break; + case NC_USHORT: fill = (double)NC_FILL_USHORT; break; + case NC_UINT: fill = (double)NC_FILL_UINT; break; + case NC_INT64: fill = (double)NC_FILL_INT64; break; + case NC_UINT64: fill = (double)NC_FILL_UINT64; break; + default: assert(0); + } + for (j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + if (var_type[i] == NC_CHAR) { + err = GetVar1TYPE(text)(ncid, i, index, &text); + IF (err != NC_NOERR) + error("get_var1_text_all failed: %s", APIFunc(strerror)(err)); + value = text; + } else { + err = GetVar1TYPE(double)(ncid, i, index, &value); + IF (err != NC_NOERR) + error("get_var1_double_all failed: %s", APIFunc(strerror)(err)); + } + IF (value != fill && fabs((fill - value)/fill) > DBL_EPSILON) + error("\n\t\t%s Value expected: %-23.17e,\n\t\t read: %-23.17e\n", + var_name[i],fill, value); + ELSE_NOK + } + } + + /* close scratch & create again for test using attribute _FillValue */ + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileCreate(scratch, NC_CLOBBER, &ncid); + IF (err != NC_NOERR) { + error("create: %s", APIFunc(strerror)(err)); + return nok; + } + def_dims(ncid); + Def_Vars(ncid, numVars); + + /* set _FillValue = 42 for all vars */ + fill = 42; + text = 42; + for (i = 0; i < numVars; i++) { + if (var_type[i] == NC_CHAR) { + err = APIFunc(put_att_text)(ncid, i, "_FillValue", 1, &text); + IF (err != NC_NOERR) + error("put_att_text: %s", APIFunc(strerror)(err)); + } else { + err = APIFunc(put_att_double)(ncid, i, "_FillValue",var_type[i],1,&fill); + IF (err != NC_NOERR) + error("put_att_double: %s", APIFunc(strerror)(err)); + } + } + + /* data mode. write records */ + err = APIFunc(enddef)(ncid); + IF (err != NC_NOERR) + error("enddef: %s", APIFunc(strerror)(err)); + index[0] = NRECS; + +ifdef(`PNETCDF', ` + for (i=0; i<=index[0]; i++) + err = APIFunc(fill_var_rec)(ncid, varid, i);')dnl + + err = PutVar1TYPE(text)(ncid, varid, index, &text); + IF (err != NC_NOERR) + error("put_var1_text_all: %s", APIFunc(strerror)(err)); + + /* get all variables & check all values equal 42 */ + for (i = 0; i < numVars; i++) { + if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */ + for (j = 0; j < var_nels[i]; j++) { + err = toMixedBase(j, var_rank[i], var_shape[i], index); + IF (err != 0) error("error in toMixedBase"); + if (var_type[i] == NC_CHAR) { + err = GetVar1TYPE(text)(ncid, i, index, &text); + IF (err != NC_NOERR) + error("get_var1_text_all failed: %s", APIFunc(strerror)(err)); + value = text; + } else { + err = GetVar1TYPE(double)(ncid, i, index, &value); + IF (err != NC_NOERR) + error("get_var1_double_all failed: %s", APIFunc(strerror)(err)); + } + IF (value != fill) + error(" %s Value expected: %g, read: %g\n", var_name[i],fill, value); + ELSE_NOK + } + } + err = APIFunc(close)(ncid); + IF (err != NC_NOERR) + error("close: %s", APIFunc(strerror)(err)); + err = FileDelete(scratch, info); + IF (err != NC_NOERR) + error("remove of %s failed", scratch); + + return nok; +} + + +/* This function gets the version of a netCDF file, 1 is for netCDF + classic, 2 for 64-bit offset format, (someday) 3 for HDF5 format, + 5 for 64-bit data format (CDF-5). +*/ +#define MAGIC_NUM_LEN 4 +static +int +APIFunc(get_file_version)(char *path, int *version) +{ + int fd; + ssize_t read_len; + char magic[MAGIC_NUM_LEN]; + + /* Need two valid pointers - check for NULL. */ + if (!version || !path) + return NC_EINVAL; + + /* Figure out if this is a netcdf or hdf5 file. */ + fd = open(path, O_RDONLY, 0600); + if (fd == -1) return errno; + + read_len = read(fd, magic, MAGIC_NUM_LEN); + if (-1 == close(fd)) return errno; + + if (read_len == -1) + return errno; + + if (read_len != MAGIC_NUM_LEN) { + printf("Error: reading NC magic string unexpected short read\n"); + return 0; + } + + if (strncmp(magic, "CDF", MAGIC_NUM_LEN-1)==0) { + if (magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CLASSIC || + magic[MAGIC_NUM_LEN-1] == NC_FORMAT_64BIT_OFFSET || + magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF5) + *version = magic[MAGIC_NUM_LEN-1]; + else + return NC_ENOTNC; + } + /* tomorrow, tomorrow, I love you tomorrow, you're always a day + away! */ + /*if (magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F') + *version = 3;*/ + return NC_NOERR; +} + +/* + * Test APIFunc(set_default_format) + * try with bad default format + * try with NULL old_formatp + * try in data mode, check error + * check that proper set to NC_FILL works for record & non-record variables + * (note that it is not possible to test NC_NOFILL mode!) + * close file & create again for test using attribute _FillValue + */ +int +TestFunc(set_default_format)(void) +{ + int ncid, nok=0; + int err; + int i; + int version=1; + int old_format; + + /* bad format */ + err = APIFunc(set_default_format)(BAD_DEFAULT_FORMAT, &old_format); + IF (err != NC_EINVAL) + error("expecting NC_EINVAL but got %s", nc_err_code_name(err)); + ELSE_NOK + + /* NULL old_formatp */ + err = APIFunc(set_default_format)(NC_FORMAT_64BIT_OFFSET, NULL); + IF (err != NC_NOERR) + error("null old_fortmatp: status = %d", err); + ELSE_NOK + + /* Cycle through available formats. */ + for(i=NC_FORMAT_CLASSIC; i #endif -typedef signed char text; +typedef char text; typedef signed char schar; #ifndef HAVE_USHORT @@ -243,11 +246,11 @@ extern char dim_name[NDIMS][3]; extern size_t dim_len[NDIMS]; extern char var_name[NVARS][2+MAX_RANK]; extern nc_type var_type[NVARS]; -extern size_t var_rank[NVARS]; +extern int var_rank[NVARS]; extern int var_dimid[NVARS][MAX_RANK]; extern size_t var_shape[NVARS][MAX_RANK]; extern size_t var_nels[NVARS]; -extern size_t var_natts[NVARS]; +extern int var_natts[NVARS]; extern char att_name[NVARS][MAX_NATTS][2]; extern char gatt_name[NGATTS][3]; extern nc_type att_type[NVARS][NGATTS]; @@ -267,220 +270,221 @@ extern size_t gatt_len[NGATTS]; extern const char *s_nc_type(nc_type); -extern void test_nc_strerror(void); -extern void test_nc_open(void); -extern void test_nc_close(void); - -extern void test_nc_inq(void); -extern void test_nc_inq_natts(void); -extern void test_nc_inq_ndims(void); -extern void test_nc_inq_nvars(void); -extern void test_nc_inq_unlimdim(void); - -extern void test_nc_inq_dimid(void); -extern void test_nc_inq_dim(void); -extern void test_nc_inq_dimlen(void); -extern void test_nc_inq_dimname(void); - -extern void test_nc_inq_varid(void); -extern void test_nc_inq_vardimid(void); -extern void test_nc_inq_varname(void); -extern void test_nc_inq_varnatts(void); -extern void test_nc_inq_varndims(void); -extern void test_nc_inq_vartype(void); -extern void test_nc_inq_var(void); - -extern void test_nc_get_var_double(void); -extern void test_nc_get_var_float(void); -extern void test_nc_get_var_int(void); -extern void test_nc_get_var_long(void); -extern void test_nc_get_var_schar(void); -extern void test_nc_get_var_short(void); -extern void test_nc_get_var_text(void); -extern void test_nc_get_var_uchar(void); -extern void test_nc_get_var(void); -extern void test_nc_get_var_ushort(void); -extern void test_nc_get_var_uint(void); -extern void test_nc_get_var_longlong(void); -extern void test_nc_get_var_ulonglong(void); - -extern void test_nc_get_var1_double(void); -extern void test_nc_get_var1_float(void); -extern void test_nc_get_var1_int(void); -extern void test_nc_get_var1_long(void); -extern void test_nc_get_var1_schar(void); -extern void test_nc_get_var1_short(void); -extern void test_nc_get_var1_text(void); -extern void test_nc_get_var1_uchar(void); -extern void test_nc_get_var1(void); -extern void test_nc_get_var1_ushort(void); -extern void test_nc_get_var1_uint(void); -extern void test_nc_get_var1_longlong(void); -extern void test_nc_get_var1_ulonglong(void); - -extern void test_nc_get_vara_double(void); -extern void test_nc_get_vara_float(void); -extern void test_nc_get_vara_int(void); -extern void test_nc_get_vara_long(void); -extern void test_nc_get_vara_schar(void); -extern void test_nc_get_vara_short(void); -extern void test_nc_get_vara_text(void); -extern void test_nc_get_vara_uchar(void); -extern void test_nc_get_vara(void); -extern void test_nc_get_vara_ushort(void); -extern void test_nc_get_vara_uint(void); -extern void test_nc_get_vara_longlong(void); -extern void test_nc_get_vara_ulonglong(void); - -extern void test_nc_get_vars(void); -extern void test_nc_get_vars_double(void); -extern void test_nc_get_vars_float(void); -extern void test_nc_get_vars_int(void); -extern void test_nc_get_vars_long(void); -extern void test_nc_get_vars_schar(void); -extern void test_nc_get_vars_short(void); -extern void test_nc_get_vars_text(void); -extern void test_nc_get_vars_uchar(void); -extern void test_nc_get_vars(void); -extern void test_nc_get_vars_ushort(void); -extern void test_nc_get_vars_uint(void); -extern void test_nc_get_vars_longlong(void); -extern void test_nc_get_vars_ulonglong(void); - -extern void test_nc_get_varm(void); -extern void test_nc_get_varm_double(void); -extern void test_nc_get_varm_float(void); -extern void test_nc_get_varm_int(void); -extern void test_nc_get_varm_long(void); -extern void test_nc_get_varm_schar(void); -extern void test_nc_get_varm_short(void); -extern void test_nc_get_varm_text(void); -extern void test_nc_get_varm_uchar(void); -extern void test_nc_get_varm(void); -extern void test_nc_get_varm_ushort(void); -extern void test_nc_get_varm_uint(void); -extern void test_nc_get_varm_longlong(void); -extern void test_nc_get_varm_ulonglong(void); - -extern void test_nc_get_att(void); -extern void test_nc_get_att_double(void); -extern void test_nc_get_att_float(void); -extern void test_nc_get_att_int(void); -extern void test_nc_get_att_long(void); -extern void test_nc_get_att_schar(void); -extern void test_nc_get_att_short(void); -extern void test_nc_get_att_text(void); -extern void test_nc_get_att_uchar(void); -extern void test_nc_get_att_ushort(void); -extern void test_nc_get_att_uint(void); -extern void test_nc_get_att_longlong(void); -extern void test_nc_get_att_ulonglong(void); - -extern void test_nc_put_att(void); -extern void test_nc_put_var_double(void); -extern void test_nc_put_var_float(void); -extern void test_nc_put_var_int(void); -extern void test_nc_put_var_long(void); -extern void test_nc_put_var_schar(void); -extern void test_nc_put_var_short(void); -extern void test_nc_put_var_text(void); -extern void test_nc_put_var_uchar(void); -extern void test_nc_put_var(void); -extern void test_nc_put_var_ushort(void); -extern void test_nc_put_var_uint(void); -extern void test_nc_put_var_longlong(void); -extern void test_nc_put_var_ulonglong(void); - -extern void test_nc_put_var1_double(void); -extern void test_nc_put_var1_float(void); -extern void test_nc_put_var1_int(void); -extern void test_nc_put_var1_long(void); -extern void test_nc_put_var1_schar(void); -extern void test_nc_put_var1_short(void); -extern void test_nc_put_var1_text(void); -extern void test_nc_put_var1_uchar(void); -extern void test_nc_put_var1(void); -extern void test_nc_put_var1_ushort(void); -extern void test_nc_put_var1_uint(void); -extern void test_nc_put_var1_longlong(void); -extern void test_nc_put_var1_ulonglong(void); - -extern void test_nc_put_vara_double(void); -extern void test_nc_put_vara_float(void); -extern void test_nc_put_vara_int(void); -extern void test_nc_put_vara_long(void); -extern void test_nc_put_vara_schar(void); -extern void test_nc_put_vara_short(void); -extern void test_nc_put_vara_text(void); -extern void test_nc_put_vara_uchar(void); -extern void test_nc_put_vara(void); -extern void test_nc_put_vara_ushort(void); -extern void test_nc_put_vara_uint(void); -extern void test_nc_put_vara_longlong(void); -extern void test_nc_put_vara_ulonglong(void); - -extern void test_nc_put_vars_double(void); -extern void test_nc_put_vars_float(void); -extern void test_nc_put_vars_int(void); -extern void test_nc_put_vars_long(void); -extern void test_nc_put_vars_schar(void); -extern void test_nc_put_vars_short(void); -extern void test_nc_put_vars_text(void); -extern void test_nc_put_vars_uchar(void); -extern void test_nc_put_vars(void); -extern void test_nc_put_vars_ushort(void); -extern void test_nc_put_vars_uint(void); -extern void test_nc_put_vars_longlong(void); -extern void test_nc_put_vars_ulonglong(void); - -extern void test_nc_put_varm_double(void); -extern void test_nc_put_varm_float(void); -extern void test_nc_put_varm_int(void); -extern void test_nc_put_varm_long(void); -extern void test_nc_put_varm_schar(void); -extern void test_nc_put_varm_short(void); -extern void test_nc_put_varm_text(void); -extern void test_nc_put_varm_uchar(void); -extern void test_nc_put_varm(void); -extern void test_nc_put_varm_ushort(void); -extern void test_nc_put_varm_uint(void); -extern void test_nc_put_varm_longlong(void); -extern void test_nc_put_varm_ulonglong(void); - -extern void test_nc_put_att_double(void); -extern void test_nc_put_att_float(void); -extern void test_nc_put_att_int(void); -extern void test_nc_put_att_long(void); -extern void test_nc_put_att_schar(void); -extern void test_nc_put_att_short(void); -extern void test_nc_put_att_text(void); -extern void test_nc_put_att_uchar(void); -extern void test_nc_put_att_ushort(void); -extern void test_nc_put_att_uint(void); -extern void test_nc_put_att_longlong(void); -extern void test_nc_put_att_ulonglong(void); - -extern void test_nc_create(void); -extern void test_nc_redef(void); -extern void test_nc_enddef(void); -extern void test_nc_sync(void); -extern void test_nc_abort(void); -extern void test_nc_def_dim(void); -extern void test_nc_rename_dim(void); -extern void test_nc_def_var(void); -extern void test_nc_rename_var(void); -extern void test_nc_copy_att(void); - -extern void test_nc_inq_att(void); -extern void test_nc_inq_attname(void); -extern void test_nc_inq_attid(void); -extern void test_nc_inq_attlen(void); -extern void test_nc_inq_atttype(void); - -extern void test_nc_rename_att(void); -extern void test_nc_del_att(void); -extern void test_nc_set_fill(void); -extern void test_nc_set_default_format(void); +extern int test_nc_strerror(void); +extern int test_nc_open(void); +extern int test_nc_close(void); + +extern int test_nc_inq(void); +extern int test_nc_inq_natts(void); +extern int test_nc_inq_ndims(void); +extern int test_nc_inq_nvars(void); +extern int test_nc_inq_unlimdim(void); + +extern int test_nc_inq_dimid(void); +extern int test_nc_inq_dim(void); +extern int test_nc_inq_dimlen(void); +extern int test_nc_inq_dimname(void); + +extern int test_nc_inq_varid(void); +extern int test_nc_inq_vardimid(void); +extern int test_nc_inq_varname(void); +extern int test_nc_inq_varnatts(void); +extern int test_nc_inq_varndims(void); +extern int test_nc_inq_vartype(void); +extern int test_nc_inq_var(void); + +extern int test_nc_get_var_double(void); +extern int test_nc_get_var_float(void); +extern int test_nc_get_var_int(void); +extern int test_nc_get_var_long(void); +extern int test_nc_get_var_schar(void); +extern int test_nc_get_var_short(void); +extern int test_nc_get_var_text(void); +extern int test_nc_get_var_uchar(void); +extern int test_nc_get_var(void); +extern int test_nc_get_var_ushort(void); +extern int test_nc_get_var_uint(void); +extern int test_nc_get_var_longlong(void); +extern int test_nc_get_var_ulonglong(void); + +extern int test_nc_get_var1_double(void); +extern int test_nc_get_var1_float(void); +extern int test_nc_get_var1_int(void); +extern int test_nc_get_var1_long(void); +extern int test_nc_get_var1_schar(void); +extern int test_nc_get_var1_short(void); +extern int test_nc_get_var1_text(void); +extern int test_nc_get_var1_uchar(void); +extern int test_nc_get_var1(void); +extern int test_nc_get_var1_ushort(void); +extern int test_nc_get_var1_uint(void); +extern int test_nc_get_var1_longlong(void); +extern int test_nc_get_var1_ulonglong(void); + +extern int test_nc_get_vara_double(void); +extern int test_nc_get_vara_float(void); +extern int test_nc_get_vara_int(void); +extern int test_nc_get_vara_long(void); +extern int test_nc_get_vara_schar(void); +extern int test_nc_get_vara_short(void); +extern int test_nc_get_vara_text(void); +extern int test_nc_get_vara_uchar(void); +extern int test_nc_get_vara(void); +extern int test_nc_get_vara_ushort(void); +extern int test_nc_get_vara_uint(void); +extern int test_nc_get_vara_longlong(void); +extern int test_nc_get_vara_ulonglong(void); + +extern int test_nc_get_vars(void); +extern int test_nc_get_vars_double(void); +extern int test_nc_get_vars_float(void); +extern int test_nc_get_vars_int(void); +extern int test_nc_get_vars_long(void); +extern int test_nc_get_vars_schar(void); +extern int test_nc_get_vars_short(void); +extern int test_nc_get_vars_text(void); +extern int test_nc_get_vars_uchar(void); +extern int test_nc_get_vars(void); +extern int test_nc_get_vars_ushort(void); +extern int test_nc_get_vars_uint(void); +extern int test_nc_get_vars_longlong(void); +extern int test_nc_get_vars_ulonglong(void); + +extern int test_nc_get_varm(void); +extern int test_nc_get_varm_double(void); +extern int test_nc_get_varm_float(void); +extern int test_nc_get_varm_int(void); +extern int test_nc_get_varm_long(void); +extern int test_nc_get_varm_schar(void); +extern int test_nc_get_varm_short(void); +extern int test_nc_get_varm_text(void); +extern int test_nc_get_varm_uchar(void); +extern int test_nc_get_varm(void); +extern int test_nc_get_varm_ushort(void); +extern int test_nc_get_varm_uint(void); +extern int test_nc_get_varm_longlong(void); +extern int test_nc_get_varm_ulonglong(void); + +extern int test_nc_get_att(void); +extern int test_nc_get_att_double(void); +extern int test_nc_get_att_float(void); +extern int test_nc_get_att_int(void); +extern int test_nc_get_att_long(void); +extern int test_nc_get_att_schar(void); +extern int test_nc_get_att_short(void); +extern int test_nc_get_att_text(void); +extern int test_nc_get_att_uchar(void); +extern int test_nc_get_att_ushort(void); +extern int test_nc_get_att_uint(void); +extern int test_nc_get_att_longlong(void); +extern int test_nc_get_att_ulonglong(void); + +extern int test_nc_put_att(void); +extern int test_nc_put_var_double(void); +extern int test_nc_put_var_float(void); +extern int test_nc_put_var_int(void); +extern int test_nc_put_var_long(void); +extern int test_nc_put_var_schar(void); +extern int test_nc_put_var_short(void); +extern int test_nc_put_var_text(void); +extern int test_nc_put_var_uchar(void); +extern int test_nc_put_var(void); +extern int test_nc_put_var_ushort(void); +extern int test_nc_put_var_uint(void); +extern int test_nc_put_var_longlong(void); +extern int test_nc_put_var_ulonglong(void); + +extern int test_nc_put_var1_double(void); +extern int test_nc_put_var1_float(void); +extern int test_nc_put_var1_int(void); +extern int test_nc_put_var1_long(void); +extern int test_nc_put_var1_schar(void); +extern int test_nc_put_var1_short(void); +extern int test_nc_put_var1_text(void); +extern int test_nc_put_var1_uchar(void); +extern int test_nc_put_var1(void); +extern int test_nc_put_var1_ushort(void); +extern int test_nc_put_var1_uint(void); +extern int test_nc_put_var1_longlong(void); +extern int test_nc_put_var1_ulonglong(void); + +extern int test_nc_put_vara_double(void); +extern int test_nc_put_vara_float(void); +extern int test_nc_put_vara_int(void); +extern int test_nc_put_vara_long(void); +extern int test_nc_put_vara_schar(void); +extern int test_nc_put_vara_short(void); +extern int test_nc_put_vara_text(void); +extern int test_nc_put_vara_uchar(void); +extern int test_nc_put_vara(void); +extern int test_nc_put_vara_ushort(void); +extern int test_nc_put_vara_uint(void); +extern int test_nc_put_vara_longlong(void); +extern int test_nc_put_vara_ulonglong(void); + +extern int test_nc_put_vars_double(void); +extern int test_nc_put_vars_float(void); +extern int test_nc_put_vars_int(void); +extern int test_nc_put_vars_long(void); +extern int test_nc_put_vars_schar(void); +extern int test_nc_put_vars_short(void); +extern int test_nc_put_vars_text(void); +extern int test_nc_put_vars_uchar(void); +extern int test_nc_put_vars(void); +extern int test_nc_put_vars_ushort(void); +extern int test_nc_put_vars_uint(void); +extern int test_nc_put_vars_longlong(void); +extern int test_nc_put_vars_ulonglong(void); + +extern int test_nc_put_varm_double(void); +extern int test_nc_put_varm_float(void); +extern int test_nc_put_varm_int(void); +extern int test_nc_put_varm_long(void); +extern int test_nc_put_varm_schar(void); +extern int test_nc_put_varm_short(void); +extern int test_nc_put_varm_text(void); +extern int test_nc_put_varm_uchar(void); +extern int test_nc_put_varm(void); +extern int test_nc_put_varm_ushort(void); +extern int test_nc_put_varm_uint(void); +extern int test_nc_put_varm_longlong(void); +extern int test_nc_put_varm_ulonglong(void); + +extern int test_nc_put_att_double(void); +extern int test_nc_put_att_float(void); +extern int test_nc_put_att_int(void); +extern int test_nc_put_att_long(void); +extern int test_nc_put_att_schar(void); +extern int test_nc_put_att_short(void); +extern int test_nc_put_att_text(void); +extern int test_nc_put_att_uchar(void); +extern int test_nc_put_att_ushort(void); +extern int test_nc_put_att_uint(void); +extern int test_nc_put_att_longlong(void); +extern int test_nc_put_att_ulonglong(void); + +extern int test_nc_create(void); +extern int test_nc_redef(void); +extern int test_nc_enddef(void); +extern int test_nc_sync(void); +extern int test_nc_abort(void); +extern int test_nc_def_dim(void); +extern int test_nc_rename_dim(void); +extern int test_nc_def_var(void); +extern int test_nc_rename_var(void); +extern int test_nc_copy_att(void); + +extern int test_nc_inq_att(void); +extern int test_nc_inq_attname(void); +extern int test_nc_inq_attid(void); +extern int test_nc_inq_attlen(void); +extern int test_nc_inq_atttype(void); + +extern int test_nc_rename_att(void); +extern int test_nc_del_att(void); +extern int test_nc_set_fill(void); +extern int test_nc_set_default_format(void); +extern int test_nc_against_pnetcdf(void); void print_nok(int nok); @@ -508,26 +512,28 @@ typedef enum { #define NCT_ULONGLONG NCT_UINT64 } nct_itype; -int inRange3(const double value, const nc_type datatype, const nct_itype itype); +int inRange3(const int cdf_format, const double value, const nc_type datatype, const nct_itype itype); int equal(const double x, const double y, nc_type extType, nct_itype itype); +int equal2(const double x, const double y, nc_type extType); + int int_vec_eq(const int *v1, const int *v2, const int n); -int roll( int n ); +size_t roll( size_t n ); int toMixedBase( size_t number, /* number to be converted to mixed base */ - size_t length, - const size_t base[], /* dimensioned [length], base[0] ignored */ - size_t result[]); /* dimensioned [length] */ + int length, + const size_t base[], /* dimensioned [length], base[0] ignored */ + size_t result[]); /* dimensioned [length] */ size_t fromMixedBase( - size_t length, + int length, size_t number[], /* dimensioned [length] */ - size_t base[]); /* dimensioned [length], base[0] ignored */ + size_t base[]); /* dimensioned [length], base[0] ignored */ int nc2dbl ( const nc_type datatype, const void *p, double *result); @@ -536,6 +542,7 @@ int dbl2nc ( const double d, const nc_type datatype, void *p); double hash( const nc_type type, const int rank, const size_t *index ); double hash4( + const int cdf_format, const nc_type type, const int rank, const size_t *index, @@ -563,8 +570,12 @@ void check_file(char *filename); int file_create(const char *filename, int cmode, int *ncid); +int file__create(const char *filename, int cmode, size_t initialsz, size_t *bufrsizehintp, int *ncid); + int file_open(const char *filename, int omode, int *ncid); +char* nc_err_code_name(int err); + #ifdef __cplusplus } #endif diff --git a/nc_test/tst_atts3.c b/nc_test/tst_atts3.c index 3855e01fed..e5ffc25d3f 100644 --- a/nc_test/tst_atts3.c +++ b/nc_test/tst_atts3.c @@ -136,7 +136,7 @@ main(int argc, char **argv) signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; unsigned char uchar_in[ATT_LEN]; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; - int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; + int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 127, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {-0.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {-0.25, .5, 0.125}; long long longlong_in[ATT_LEN] = {-1LL, -1LL, -1LL}; @@ -211,8 +211,10 @@ main(int argc, char **argv) * supported C types. though the conversion may encounter * out-of-range values */ if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_INT_NAME, uchar_in) != NC_ERANGE) ERR; - for (i = 0; i < ATT_LEN; i++) + for (i = 0; i < ATT_LEN; i++) { + if (i == 0 || i == 2) continue; if (uchar_in[i] != (unsigned char) int_out[i]) ERR; + } /* This was bug NCF-171: on 32-bit platforms, bad values returned */ if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT_NAME, longlong_in)) ERR; @@ -346,8 +348,10 @@ main(int argc, char **argv) for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_INT_NAME, short_in) != NC_ERANGE) ERR; - for (i = 0; i < ATT_LEN; i++) + for (i = 0; i < ATT_LEN; i++) { + if (i == 0 || i == 2) continue; if (short_in[i] != (short) int_out[i]) ERR; + } if (nc_get_att_short(ncid, NC_GLOBAL, ATT_FLOAT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short) float_out[i]) ERR; @@ -360,11 +364,15 @@ main(int argc, char **argv) for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in) != NC_ERANGE) ERR; - for (i = 0; i < ATT_LEN; i++) + for (i = 0; i < ATT_LEN; i++) { + if (i == 0 || i == 2) continue; if (schar_in[i] != (signed char) short_out[i]) ERR; + } if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in) != NC_ERANGE) ERR; - for (i = 0; i < ATT_LEN; i++) + for (i = 0; i < ATT_LEN; i++) { + if (i == 0 || i == 2) continue; if (schar_in[i] != (signed char) int_out[i]) ERR; + } if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char) float_out[i]) ERR; @@ -373,22 +381,25 @@ main(int argc, char **argv) if (schar_in[i] != (signed char) double_out[i]) ERR; /* Read all atts (except text) as uchar. */ - /* Shouldn't this get an NC_ERANGE error for storing -128 into an unsigned char? Possible bug ... */ if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, uchar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uchar_in[i] != (unsigned char) schar_out[i]) ERR; if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_SHORT_NAME, uchar_in) != NC_ERANGE) ERR; - for (i = 0; i < ATT_LEN; i++) - if (uchar_in[i] != (unsigned char) short_out[i]) ERR; if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_INT_NAME, uchar_in) != NC_ERANGE) ERR; - for (i = 0; i < ATT_LEN; i++) + for (i = 0; i < ATT_LEN; i++) { + if (i == 0 || i == 2) continue; if (uchar_in[i] != (unsigned char) int_out[i]) ERR; + } if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, uchar_in) != NC_ERANGE) ERR; - for (i = 0; i < ATT_LEN; i++) + for (i = 0; i < ATT_LEN; i++) { + if (i == 0) continue; if (uchar_in[i] != (unsigned char) float_out[i]) ERR; + } if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, uchar_in) != NC_ERANGE) ERR; - for (i = 0; i < ATT_LEN; i++) + for (i = 0; i < ATT_LEN; i++) { + if (i == 0) continue; if (uchar_in[i] != (unsigned char) double_out[i]) ERR; + } /* Read all atts (except text) into long long variable. */ if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_SCHAR_NAME, longlong_in)) ERR; diff --git a/nc_test/tst_small.c b/nc_test/tst_small.c index 9d4791ea3e..750baf5a66 100644 --- a/nc_test/tst_small.c +++ b/nc_test/tst_small.c @@ -104,6 +104,7 @@ test_small_atts(const char *testfile) { /* Create null-terminated text string of correct length. */ strncpy(att, source, t); + att[t] = '\0'; /* Create a file with one attribute. */ if (file_create(testfile, NC_CLOBBER, &ncid)) ERR; diff --git a/nc_test/util.c b/nc_test/util.c index 6ac318c51f..33b53234b6 100644 --- a/nc_test/util.c +++ b/nc_test/util.c @@ -4,8 +4,9 @@ * $Id: util.c 2792 2014-10-27 06:02:59Z wkliao $ *********************************************************************/ +#include /* floor() */ #include "tests.h" -#include + void print_nok(int nok) { @@ -17,64 +18,58 @@ print_nok(int nok) /* Is value within external type range? */ int -inRange(const double value, const nc_type datatype) +inRange(const double value, const nc_type xtype) { + switch (xtype) { double min = 0.0; double max = 0.0; - switch (datatype) { - case NC_CHAR: return value >= X_CHAR_MIN && value <= X_CHAR_MAX; - case NC_BYTE: return value >= X_BYTE_MIN && value <= X_BYTE_MAX; - case NC_SHORT: return value >= X_SHORT_MIN && value <= X_SHORT_MAX; - case NC_INT: return value >= X_INT_MIN && value <= X_INT_MAX; - case NC_FLOAT: return value >= X_FLOAT_MIN && value <= X_FLOAT_MAX; - case NC_DOUBLE: return value >= X_DOUBLE_MIN && value <= X_DOUBLE_MAX; - case NC_UBYTE: return value >= 0 && value <= X_UCHAR_MAX; - case NC_USHORT: return value >= 0 && value <= X_USHORT_MAX; - case NC_UINT: return value >= 0 && value <= X_UINT_MAX; - case NC_INT64: return value >= X_INT64_MIN && value <= X_INT64_MAX; - case NC_UINT64: return value >= 0 && value <= X_UINT64_MAX; - default: assert(0); - } - return value >= min && value <= max; -} -static int -inRange_uchar(const double value, const nc_type datatype) -{ - if (datatype == NC_BYTE) { - return(value >= 0 && value <= 255); - } - /* else */ - return inRange(value, datatype); + case NC_CHAR: return value >= X_CHAR_MIN && value <= X_CHAR_MAX; + case NC_BYTE: return value >= X_BYTE_MIN && value <= X_BYTE_MAX; + case NC_SHORT: return value >= X_SHORT_MIN && value <= X_SHORT_MAX; + case NC_INT: return value >= X_INT_MIN && value <= X_INT_MAX; + case NC_FLOAT: return value >= X_FLOAT_MIN && value <= X_FLOAT_MAX; + case NC_DOUBLE: return value >= X_DOUBLE_MIN && value <= X_DOUBLE_MAX; + case NC_UBYTE: return value >= 0 && value <= X_UCHAR_MAX; + case NC_USHORT: return value >= 0 && value <= X_USHORT_MAX; + case NC_UINT: return value >= 0 && value <= X_UINT_MAX; + case NC_INT64: return value >= X_INT64_MIN && value <= X_INT64_MAX; + case NC_UINT64: return value >= 0 && value <= X_UINT64_MAX; + default: assert(0); + return(0); + } } static int -inRange_schar(const double value, const nc_type datatype) +inRange_uchar(const int cdf_format, + const double value, + const nc_type xtype) { - /* check value of type datatype if within schar range */ + /* check value of type xtype if within uchar range */ - if (datatype == NC_UBYTE) { + if (cdf_format < NC_FORMAT_CDF5 && xtype == NC_BYTE) { /* netCDF specification make a special case for type conversion between * uchar and scahr: do not check for range error. See - * http://www.unidata.ucar.edu/software/netcdf/docs_rc/data_type.html#type_conversion + * http://www.unidata.ucar.edu/software/netcdf/docs/data_type.html#type_conversion */ - return(value >= X_CHAR_MIN && value <= X_CHAR_MAX); + return(value >= 0 && value <= 255); + /* this is to ensure value is within the range of uchar */ } /* else */ - return inRange(value, datatype); + return inRange(value, xtype); } static int -inRange_float(const double value, const nc_type datatype) +inRange_float(const double value, const nc_type xtype) { double min, max; - switch (datatype) { - case NC_CHAR: min = X_CHAR_MIN; max = X_CHAR_MAX; break; - case NC_BYTE: min = X_BYTE_MIN; max = X_BYTE_MAX; break; + switch (xtype) { + case NC_CHAR: min = X_CHAR_MIN; max = X_CHAR_MAX; break; + case NC_BYTE: min = X_BYTE_MIN; max = X_BYTE_MAX; break; case NC_SHORT: min = X_SHORT_MIN; max = X_SHORT_MAX; break; - case NC_INT: min = X_INT_MIN; max = X_INT_MAX; break; + case NC_INT: min = X_INT_MIN; max = X_INT_MAX; break; case NC_FLOAT: if(FLT_MAX < X_FLOAT_MAX) { min = (-FLT_MAX); @@ -102,7 +97,7 @@ inRange_float(const double value, const nc_type datatype) } if(!( value >= min && value <= max)) { #if 0 /* DEBUG */ - if(datatype == NC_FLOAT) { + if(xtype == NC_FLOAT) { fprintf(stderr, "\n"); fprintf(stderr, "min % .17e\n", min); fprintf(stderr, "value % .17e\n", value); @@ -114,7 +109,7 @@ inRange_float(const double value, const nc_type datatype) #if FLT_MANT_DIG != DBL_MANT_DIG /* else */ { - const float fvalue = value; + const float fvalue = (float)value; return fvalue >= min && fvalue <= max; } #else @@ -123,24 +118,37 @@ inRange_float(const double value, const nc_type datatype) } /* wrapper for inRange to handle special NC_BYTE/uchar adjustment */ +/* this function checks whether "value" to be casted to type "itype" is + * within the range of external "xtype". + */ int -inRange3( - const double value, - const nc_type datatype, - const nct_itype itype) +inRange3(const int cdf_format, + const double value, + const nc_type xtype, + const nct_itype itype) { + /* netCDF specification make a special case for type conversion between + * uchar and NC_BYTE: do not check for range error. See + * http://www.unidata.ucar.edu/software/netcdf/docs/data_type.html#type_conversion + * The _uchar and _schar functions were introduced in netCDF-3 to eliminate + * an ambiguity, and support both signed and unsigned byte data. In + * netCDF-2, whether the external NC_BYTE type represented signed or + * unsigned values was left up to the user. In netcdf-3, we treat NC_BYTE + * as signed for the purposes of conversion to short, int, long, float, or + * double. (Of course, no conversion takes place when the internal type is + * signed char.) In the _uchar functions, we treat NC_BYTE as if it were + * unsigned. Thus, no NC_ERANGE error can occur converting between NC_BYTE + * and unsigned char. + */ switch (itype) { - case NCT_SCHAR: - case NCT_CHAR: - return inRange_schar(value, datatype); - case NCT_UCHAR: - return inRange_uchar(value, datatype); - case NCT_FLOAT: - return inRange_float(value, datatype); - default: - break; + case NCT_UCHAR: + return inRange_uchar(cdf_format, value, xtype); + case NCT_FLOAT: + return inRange_float(value, xtype); + default: + break; } - return inRange(value, datatype); + return inRange(value, xtype); } @@ -149,17 +157,51 @@ inRange3( * Use tolerant comparison based on IEEE FLT_EPSILON or DBL_EPSILON. */ int -equal( - const double x, - const double y, - nc_type extType, /* external data type */ - nct_itype itype) +equal(const double x, + const double y, + nc_type xtype, /* external data type */ + nct_itype itype) { const double flt_epsilon = 1.19209290E-07; const double dbl_epsilon = 2.2204460492503131E-16; double epsilon; - epsilon = extType == NC_FLOAT || itype == NCT_FLOAT ? flt_epsilon : dbl_epsilon; + epsilon = xtype == NC_FLOAT || + itype == NCT_FLOAT ? flt_epsilon : dbl_epsilon; + + if (xtype == NC_CHAR && itype == NCT_TEXT) { + /* because in-memory data type char can be signed or unsigned, + * type cast the value from external NC_CHAR before the comparison + */ + char x2 = (char) x; + char y2 = (char) y; + return ABS(x2-y2) <= epsilon * MAX( ABS(x2), ABS(y2)); + } + + return ABS(x-y) <= epsilon * MAX( ABS(x), ABS(y)); +} + +/* this function is for the APIs without itype, i.e. xtype == itype */ +int +equal2(const double x, + const double y, + nc_type xtype) /* external data type */ +{ + const double flt_epsilon = 1.19209290E-07; + const double dbl_epsilon = 2.2204460492503131E-16; + double epsilon; + + epsilon = xtype == NC_FLOAT ? flt_epsilon : dbl_epsilon; + + if (xtype == NC_CHAR) { + /* because in-memory data type char can be signed or unsigned, + * type cast the value from external NC_CHAR before the comparison + */ + char x2 = (char) x; + char y2 = (char) y; + return ABS(x2-y2) <= epsilon * MAX( ABS(x2), ABS(y2)); + } + return ABS(x-y) <= epsilon * MAX( ABS(x), ABS(y)); } @@ -178,9 +220,9 @@ int_vec_eq(const int *v1, const int *v2, const int n) * Generate random integer from 0 to n-1 * Like throwing an n-sided dice marked 0, 1, 2, ..., n-1 */ -int roll( int n ) +size_t roll( size_t n ) { - int r; + size_t r; do /* @@ -190,7 +232,7 @@ int roll( int n ) * We don't use RAND_MAX here because not all compilation * environments define it (e.g. gcc(1) under SunOS 4.1.4). */ - r = ((rand() % 32768) / 32767.0) * (n - 1) + 0.5; + r = (size_t)(((rand() % 32768) / 32767.0) * (n - 1) + 0.5); while (r >= n); return r; @@ -210,16 +252,15 @@ int roll( int n ) int toMixedBase( size_t number, /* number to be converted to mixed base */ - size_t length, + int length, const size_t base[], /* dimensioned [length], base[0] ignored */ size_t result[]) /* dimensioned [length] */ { - size_t i; + int i; if (length > 0) { for (i = length - 1; i > 0; i--) { - if (base[i] == 0) - return 1; + if (base[i] == 0) return 1; result[i] = number % base[i]; number = number / base[i]; } @@ -239,10 +280,9 @@ toMixedBase( * Author: Harvey Davies, Unidata/UCAR, Boulder, Colorado */ size_t -fromMixedBase( - size_t length, - size_t number[], /* dimensioned [length] */ - size_t base[]) /* dimensioned [length], base[0] ignored */ +fromMixedBase(int length, + size_t number[], /* dimensioned [length] */ + size_t base[]) /* dimensioned [length], base[0] ignored */ { size_t i; size_t result = 0; @@ -258,30 +298,30 @@ fromMixedBase( /* Convert any nc_type to double */ -int nc2dbl ( const nc_type datatype, const void *p, double *result) +int nc2dbl ( const nc_type xtype, const void *p, double *result) { if ( ! p ) return 2; if ( ! result ) return 3; - switch (datatype) { - case NC_BYTE: *result = *((signed char *) p); break; - case NC_CHAR: *result = *((signed char *) p); break; - case NC_SHORT: *result = *((short *) p); break; + switch (xtype) { + case NC_CHAR: *result = *((char *) p); break; + case NC_BYTE: *result = *((signed char *) p); break; + case NC_UBYTE: *result = *((unsigned char *) p); break; + case NC_SHORT: *result = *((short *) p); break; + case NC_USHORT: *result = *((unsigned short *) p); break; case NC_INT: #if INT_MAX >= X_INT_MAX *result = *((int *) p); break; #else *result = *((long *) p); break; #endif - case NC_FLOAT: *result = *((float *) p); break; - case NC_DOUBLE: *result = *((double *) p); break; - case NC_UBYTE: *result = *((unsigned char *) p); break; - case NC_USHORT: *result = *((unsigned short *) p); break; case NC_UINT: #if UINT_MAX >= X_UINT_MAX *result = *((unsigned int *) p); break; #else *result = *((unsigned long *) p); break; #endif + case NC_FLOAT: *result = *((float *) p); break; + case NC_DOUBLE: *result = *((double *) p); break; case NC_INT64: *result = *((long long *) p); break; case NC_UINT64: *result = *((unsigned long long *) p); break; default: return 1; @@ -291,83 +331,86 @@ int nc2dbl ( const nc_type datatype, const void *p, double *result) /* Convert double to any nc_type */ -int dbl2nc ( const double d, const nc_type datatype, void *p) +int dbl2nc ( const double d, const nc_type xtype, void *p) { double r; /* rounded value */ - if (p) { - switch (datatype) { - case NC_BYTE: - r = floor(0.5+d); - if ( r < schar_min || r > schar_max ) return 2; - *((signed char *) p) = r; - break; - case NC_CHAR: - r = floor(0.5+d); - if ( r < text_min || r > text_max ) return 2; -#ifndef __CHAR_UNSIGNED__ - *((char *) p) = r; -#else - *((signed char*) p) = r; -#endif - break; - case NC_SHORT: - r = floor(0.5+d); - if ( r < short_min || r > short_max ) return 2; - *((short *) p) = r; - break; - case NC_INT: - r = floor(0.5+d); - if ( r < long_min || r > long_max ) return 2; -#if INT_MAX >= X_INT_MAX - *((int *) p) = r; + if (p == NULL) return 1; + switch (xtype) { + case NC_CHAR: + r = floor(0.5+d); + /* d is obtained from hash() which may be set to X_CHAR_MIN (0) + * or X_CHAR_MAX (255). When in-memory data type char is signed + * (i.e. ranged from -128 to 127), we should still allow a type + * cast a unsigned value > 127 to a signed char without + * reporting it as a range error. + */ + if ( r < X_CHAR_MIN || r > X_CHAR_MAX ) return 2; +#if defined(__CHAR_UNSIGNED__) && __CHAR_UNSIGNED__ != 0 + *((signed char*) p) = (signed char)r; #else - *((long *) p) = r; + *((char *) p) = (char)r; #endif - break; - case NC_FLOAT: - if ( fabs(d) > float_max ) return 2; - *((float *) p) = d; - break; - case NC_DOUBLE: - *((double *) p) = d; - break; + break; + case NC_BYTE: + r = floor(0.5+d); + if ( r < schar_min || r > schar_max ) return 2; + *((signed char *) p) = (signed char)r; + break; case NC_UBYTE: r = floor(0.5+d); if ( r < 0.0 || r > uchar_max ) return 2; - *((unsigned char *) p) = r; + *((unsigned char *) p) = (unsigned char)r; + break; + case NC_SHORT: + r = floor(0.5+d); + if ( r < short_min || r > short_max ) return 2; + *((short *) p) = (short)r; break; case NC_USHORT: r = floor(0.5+d); if ( r < 0.0 || r > ushort_max ) return 2; - *((unsigned short *) p) = r; + *((unsigned short *) p) = (unsigned short)r; + break; + case NC_INT: + r = floor(0.5+d); + if ( r < long_min || r > long_max ) return 2; +#if INT_MAX >= X_INT_MAX + *((int *) p) = (int)r; +#else + *((long *) p) = (long)r; +#endif break; case NC_UINT: r = floor(0.5+d); if ( r < 0.0 || r > uint_max ) return 2; #if UINT_MAX >= X_UINT_MAX - *((unsigned int *) p) = r; + *((unsigned int *) p) = (unsigned int)r; #else - *((unsigned long *) p) = r; + *((unsigned long *) p) = (unsigned long)r; #endif break; + case NC_FLOAT: + if ( fabs(d) > float_max ) return 2; + *((float *) p) = (float)d; + break; + case NC_DOUBLE: + *((double *) p) = (double)d; + break; case NC_INT64: r = floor(0.5+d); if ( r < int64_min || r > int64_max ) return 2; - *((long long *) p) = r; + *((long long *) p) = (long long)r; break; case NC_UINT64: r = floor(0.5+d); if ( r < 0.0 || r > uint64_max ) return 2; - *((unsigned long long *) p) = r; + *((unsigned long long *) p) = (unsigned long long)r; break; - default: - return 1; - } - return 0; - } else { - return 1; + default: + return 1; } + return 0; } #define FUZZ (1.19209290E-07) @@ -375,7 +418,7 @@ int dbl2nc ( const double d, const nc_type datatype, void *p) #ifdef USE_EXTREME_NUMBERS /* Generate data values as function of type, rank (-1 for attribute), index */ double -hash( const nc_type type, const int rank, const size_t *index ) +hash( const nc_type xtype, const int rank, const size_t *index ) { double base; double result; @@ -386,11 +429,11 @@ hash( const nc_type type, const int rank, const size_t *index ) if (abs(rank) == 1 && index[0] <= 3) { switch (index[0]) { case 0: - switch (type) { + switch (xtype) { case NC_CHAR: return X_CHAR_MIN; case NC_BYTE: return X_BYTE_MIN; case NC_SHORT: return X_SHORT_MIN; - case NC_INT: return X_INT_MIN; + case NC_INT: return X_INT_MIN; case NC_FLOAT: return X_FLOAT_MIN; case NC_DOUBLE: return X_DOUBLE_MIN; case NC_UBYTE: return 0; @@ -402,11 +445,11 @@ hash( const nc_type type, const int rank, const size_t *index ) default: assert(0); } case 1: - switch (type) { + switch (xtype) { case NC_CHAR: return X_CHAR_MAX; case NC_BYTE: return X_BYTE_MAX; case NC_SHORT: return X_SHORT_MAX; - case NC_INT: return X_INT_MAX; + case NC_INT: return X_INT_MAX; case NC_FLOAT: return X_FLOAT_MAX; case NC_DOUBLE: return X_DOUBLE_MAX; case NC_UBYTE: return X_UCHAR_MAX; @@ -419,11 +462,11 @@ hash( const nc_type type, const int rank, const size_t *index ) default: assert(0); } case 2: - switch (type) { + switch (xtype) { case NC_CHAR: return 'A'; case NC_BYTE: return X_BYTE_MIN-1.0; case NC_SHORT: return X_SHORT_MIN-1.0; - case NC_INT: return X_INT_MIN-1.0; + case NC_INT: return X_INT_MIN-1.0; case NC_FLOAT: return X_FLOAT_MIN * (1.0 + FUZZ); case NC_DOUBLE: return -1.0; case NC_UBYTE: return -1.0; @@ -434,11 +477,11 @@ hash( const nc_type type, const int rank, const size_t *index ) default: assert(0); } case 3: - switch (type) { + switch (xtype) { case NC_CHAR: return 'Z'; case NC_BYTE: return X_BYTE_MAX+1.0; case NC_SHORT: return X_SHORT_MAX+1.0; - case NC_INT: return X_INT_MAX+1.0; + case NC_INT: return X_INT_MAX+1.0; case NC_FLOAT: return X_FLOAT_MAX * (1.0 + FUZZ); case NC_DOUBLE: return 1.0; case NC_UBYTE: return X_UCHAR_MAX +1.0; @@ -450,12 +493,12 @@ hash( const nc_type type, const int rank, const size_t *index ) } } } else { - switch (type) { - case NC_CHAR: base = 2; break; - case NC_BYTE: base = -2; break; - case NC_SHORT: base = -5; break; - case NC_INT: base = -20; break; - case NC_FLOAT: base = -9; break; + switch (xtype) { + case NC_CHAR: base = 2; break; + case NC_BYTE: base = -2; break; + case NC_SHORT: base = -5; break; + case NC_INT: base = -20; break; + case NC_FLOAT: base = -9; break; case NC_DOUBLE: base = -10; break; /* not sure what right values are */ @@ -480,7 +523,7 @@ hash( const nc_type type, const int rank, const size_t *index ) /* Generate data values as function of type, rank (-1 for attribute), index */ double -hash( const nc_type type, const int rank, const size_t *index ) +hash( const nc_type xtype, const int rank, const size_t *index ) { double base; double result; @@ -491,7 +534,7 @@ hash( const nc_type type, const int rank, const size_t *index ) if (abs(rank) == 1 && index[0] <= 3) { switch (index[0]) { case 0: - switch (type) { + switch (xtype) { case NC_CHAR: return X_CHAR_MIN; case NC_BYTE: return X_BYTE_MIN; case NC_SHORT: return SANE_SHORT; @@ -507,7 +550,7 @@ hash( const nc_type type, const int rank, const size_t *index ) default: assert(0); } case 1: - switch (type) { + switch (xtype) { case NC_CHAR: return X_CHAR_MAX; case NC_BYTE: return X_BYTE_MAX; case NC_SHORT: return SANE_SHORT; @@ -524,7 +567,7 @@ hash( const nc_type type, const int rank, const size_t *index ) default: assert(0); } case 2: - switch (type) { + switch (xtype) { case NC_CHAR: return 'A'; case NC_BYTE: return X_BYTE_MIN-1.0; case NC_SHORT: return SANE_SHORT-1.0; @@ -539,7 +582,7 @@ hash( const nc_type type, const int rank, const size_t *index ) default: assert(0); } case 3: - switch (type) { + switch (xtype) { case NC_CHAR: return 'Z'; case NC_BYTE: return X_BYTE_MAX+1.0; case NC_SHORT: return SANE_SHORT+1.0; @@ -555,7 +598,7 @@ hash( const nc_type type, const int rank, const size_t *index ) } } } else { - switch (type) { + switch (xtype) { case NC_CHAR: base = 2; break; case NC_BYTE: base = -2; break; case NC_SHORT: base = -5; break; @@ -580,17 +623,34 @@ hash( const nc_type type, const int rank, const size_t *index ) #endif /* wrapper for hash to handle special NC_BYTE/uchar adjustment */ double -hash4( - const nc_type type, - const int rank, - const size_t *index, - const nct_itype itype) +hash4(const int cdf_format, + const nc_type xtype, + const int rank, + const size_t *index, + const nct_itype itype) { double result; - result = hash( type, rank, index ); - if (itype == NCT_UCHAR && type == NC_BYTE && result >= -128 && result < 0) + result = hash( xtype, rank, index ); + + /* netCDF specification make a special case for type conversion between + * uchar and NC_BYTE: do not check for range error. See + * http://www.unidata.ucar.edu/software/netcdf/docs/data_type.html#type_conversion + * The _uchar and _schar functions were introduced in netCDF-3 to eliminate + * an ambiguity, and support both signed and unsigned byte data. In + * netCDF-2, whether the external NC_BYTE type represented signed or + * unsigned values was left up to the user. In netcdf-3, we treat NC_BYTE + * as signed for the purposes of conversion to short, int, long, float, or + * double. (Of course, no conversion takes place when the internal type is + * signed char.) In the _uchar functions, we treat NC_BYTE as if it were + * unsigned. Thus, no NC_ERANGE error can occur converting between NC_BYTE + * and unsigned char. + */ + if (cdf_format < NC_FORMAT_CDF5 && + itype == NCT_UCHAR && xtype == NC_BYTE && + result >= -128 && result < 0) result += 256; + return result; } @@ -642,7 +702,7 @@ init_gatts(const char *type_letter) } static size_t -product(size_t nn, const size_t *sp) +product(int nn, const size_t *sp) { size_t result = 1; while(nn-- > 0) @@ -670,7 +730,7 @@ init_gvars (void) */ const char digit[] = "r123456789"; - size_t rank; + int rank; int vn; /* var number */ int xtype; /* index of type */ int an; /* attribute number */ @@ -686,7 +746,7 @@ init_gvars (void) { /* number variables of a type and rank */ const size_t nvars = product(rank, max_dim_len); - int jj; + size_t jj; for (jj = 0; jj < nvars; jj++) { @@ -782,13 +842,13 @@ put_atts(int ncid) int j; /* index of attribute */ int allInRange; double att[MAX_NELS]; - signed char catt[MAX_NELS]; + char catt[MAX_NELS]; for (i = -1; i < numVars; i++) { for (j = 0; j < NATTS(i); j++) { if (ATT_TYPE(i,j) == NC_CHAR) { for (k = 0; k < ATT_LEN(i,j); k++) { - catt[k] = hash(ATT_TYPE(i,j), -1, &k); + catt[k] = (char) hash(ATT_TYPE(i,j), -1, &k); } err = nc_put_att_text(ncid, i, ATT_NAME(i,j), ATT_LEN(i,j), catt); @@ -823,7 +883,7 @@ put_vars(int ncid) int i; size_t j; double value[MAX_NELS]; - signed char text[MAX_NELS]; + char text[MAX_NELS]; int allInRange; for (j = 0; j < MAX_RANK; j++) @@ -833,7 +893,7 @@ put_vars(int ncid) err = toMixedBase(j, var_rank[i], var_shape[i], index); IF (err) error("toMixedBase"); if (var_name[i][0] == 'c') { - text[j] = hash(var_type[i], var_rank[i], index); + text[j] = (char) hash(var_type[i], var_rank[i], index); } else { value[j] = hash(var_type[i], var_rank[i], index); allInRange = allInRange && inRange(value[j], var_type[i]); @@ -923,28 +983,23 @@ void check_vars(int ncid) { size_t index[MAX_RANK]; - int err; /* status */ - int i; + char text, name[NC_MAX_NAME]; + int i, err; /* status */ size_t j; - signed char text; - double value; - nc_type datatype; - int ndims; - int dimids[MAX_RANK]; - int isChar; - double expect; - char name[NC_MAX_NAME]; - size_t length; int nok = 0; /* count of valid comparisons */ + int isChar, ndims, dimids[MAX_RANK]; + double value, expect; + nc_type xtype; + size_t length; for (i = 0; i < numVars; i++) { isChar = var_type[i] == NC_CHAR; - err = nc_inq_var(ncid, i, name, &datatype, &ndims, dimids, NULL); + err = nc_inq_var(ncid, i, name, &xtype, &ndims, dimids, NULL); IF (err) error("nc_inq_var: %s", nc_strerror(err)); IF (strcmp(name, var_name[i]) != 0) error("Unexpected var_name"); - IF (datatype != var_type[i]) + IF (xtype != var_type[i]) error("Unexpected type"); IF (ndims != var_rank[i]) error("Unexpected rank"); @@ -961,18 +1016,14 @@ check_vars(int ncid) error("error in toMixedBase 2"); expect = hash( var_type[i], var_rank[i], index ); if (isChar) { - err = nc_get_var1_text(ncid, i, index, &text); - IF (err) + err = nc_get_var1_text(ncid, i, index, &text); + IF (err) error("nc_get_var1_text: %s", nc_strerror(err)); - IF (text != expect) { - error("Var %s value read 0x%02x not that expected 0x%02x ", - var_name[i], text, (char)expect); - print_n_size_t(var_rank[i], index); + IF (text != (char)expect) { + error("Var %s [%lu] value read %hhd not that expected %g ", + var_name[i], j, text, expect); + print_n_size_t(var_rank[i], index); } else { -#if 0 - print("\nOk %s ", var_name[i]); - print_n_size_t(var_rank[i], index); -#endif nok++; } } else { @@ -982,16 +1033,10 @@ check_vars(int ncid) error("nc_get_var1_double: %s", nc_strerror(err)); } else { IF (!equal(value,expect,var_type[i], NCT_DOUBLE)) { - value = 0; - err = nc_get_var1_double(ncid, i, index, &value); - error("Var %s value read % 12.5e not that expected % 12.7e ", - var_name[i], value, expect); + error("Var %s [%lu] value read %g not that expected %g ", + var_name[i], j, value, expect); print_n_size_t(var_rank[i], index); } else { -#if 0 - print("\nOk %s ", var_name[i]); - print_n_size_t(var_rank[i], index); -#endif nok++; } } @@ -1013,10 +1058,10 @@ check_atts(int ncid) int i; int j; size_t k; - nc_type datatype; + nc_type xtype; char name[NC_MAX_NAME]; size_t length; - signed char text[MAX_NELS]; + char text[MAX_NELS]; double value[MAX_NELS]; double expect; int nok = 0; /* count of valid comparisons */ @@ -1028,28 +1073,29 @@ check_atts(int ncid) error("nc_inq_attname: %s", nc_strerror(err)); IF (strcmp(name, ATT_NAME(i,j)) != 0) error("nc_inq_attname: unexpected name"); - err = nc_inq_att(ncid, i, name, &datatype, &length); + err = nc_inq_att(ncid, i, name, &xtype, &length); IF (err) error("nc_inq_att: %s", nc_strerror(err)); - IF (datatype != ATT_TYPE(i,j)) + IF (xtype != ATT_TYPE(i,j)) error("nc_inq_att: unexpected type"); IF (length != ATT_LEN(i,j)) error("nc_inq_att: unexpected length"); - if (datatype == NC_CHAR) { + if (xtype == NC_CHAR) { err = nc_get_att_text(ncid, i, name, text); IF (err) error("nc_get_att_text: %s", nc_strerror(err)); for (k = 0; k < ATT_LEN(i,j); k++) { - IF (text[k] != hash(datatype, -1, &k)) { + expect = hash(xtype, -1, &k); + IF (text[k] != (char)expect) { error("nc_get_att_text: unexpected value"); - } else { - nok++; - } + } else { + nok++; + } } } else { err = nc_get_att_double(ncid, i, name, value); for (k = 0; k < ATT_LEN(i,j); k++) { - expect = hash(datatype, -1, &k); + expect = hash(xtype, -1, &k); if (inRange(expect,ATT_TYPE(i,j))) { IF (err) error("nc_get_att_double: %s", nc_strerror(err)); @@ -1089,9 +1135,9 @@ check_file(char *filename) /* TODO: Maybe this function belongs in the netcdf library. */ const char * -s_nc_type(nc_type type) +s_nc_type(nc_type xtype) { - switch((int)type){ + switch((int)xtype){ case NC_CHAR: return "NC_CHAR"; case NC_BYTE: return "NC_BYTE"; case NC_UBYTE: return "NC_UBYTE"; @@ -1112,13 +1158,13 @@ int file_create(const char *filename, int cmode, int *ncid) { int err; +#ifdef USE_PNETCDF /* get the default file format */ int default_format; nc_set_default_format(NC_FORMAT_CLASSIC, &default_format); /* set it back to the default */ nc_set_default_format(default_format, NULL); -#ifdef USE_PNETCDF if (default_format == NC_FORMAT_CLASSIC || default_format == NC_FORMAT_64BIT_OFFSET || default_format == NC_FORMAT_64BIT_DATA) @@ -1130,17 +1176,43 @@ int file_create(const char *filename, int cmode, int *ncid) return err; } -int file_open(const char *filename, int omode, int *ncid) +int file__create(const char *filename, + int cmode, + size_t initialsz, + size_t *bufrsizehintp, + int *ncid) { int err; +#ifdef USE_PNETCDF /* get the default file format */ int default_format; err = nc_set_default_format(NC_FORMAT_CLASSIC, &default_format); /* set it back to the default */ err = nc_set_default_format(default_format, NULL); + if (default_format == NC_FORMAT_CLASSIC || + default_format == NC_FORMAT_64BIT_OFFSET || + default_format == NC_FORMAT_64BIT_DATA) + err = nc_create_par(filename, cmode|NC_PNETCDF, MPI_COMM_WORLD, MPI_INFO_NULL, ncid); + else +#endif + err = nc__create(filename, cmode, initialsz, bufrsizehintp, ncid); + + return err; +} + +int file_open(const char *filename, int omode, int *ncid) +{ + int err; + #ifdef USE_PNETCDF + /* get the default file format */ + int default_format; + err = nc_set_default_format(NC_FORMAT_CLASSIC, &default_format); + /* set it back to the default */ + err = nc_set_default_format(default_format, NULL); + if (default_format == NC_FORMAT_CLASSIC || default_format == NC_FORMAT_64BIT_OFFSET || default_format == NC_FORMAT_64BIT_DATA) @@ -1151,3 +1223,241 @@ int file_open(const char *filename, int omode, int *ncid) return err; } + + +#ifdef USE_PNETCDF +#include /* to include PnetCDF error codes */ +#endif + +char* nc_err_code_name(int err) +{ + static char unknown_str[32]; + + if (err > 0) { /* system error */ + const char *cp = (const char *) strerror(err); + if (cp == NULL) + sprintf(unknown_str,"Unknown error code %d",err); + else + sprintf(unknown_str,"Error code %d (%s)",err,cp); + return unknown_str; + } + + switch (err) { + case (NC_NOERR): return "NC_NOERR"; + case (NC_EBADID): return "NC_EBADID"; + case (NC_ENFILE): return "NC_ENFILE"; + case (NC_EEXIST): return "NC_EEXIST"; + case (NC_EINVAL): return "NC_EINVAL"; + case (NC_EPERM): return "NC_EPERM"; + case (NC_ENOTINDEFINE): return "NC_ENOTINDEFINE"; + case (NC_EINDEFINE): return "NC_EINDEFINE"; + case (NC_EINVALCOORDS): return "NC_EINVALCOORDS"; + case (NC_EMAXDIMS): return "NC_EMAXDIMS"; + case (NC_ENAMEINUSE): return "NC_ENAMEINUSE"; + case (NC_ENOTATT): return "NC_ENOTATT"; + case (NC_EMAXATTS): return "NC_EMAXATTS"; + case (NC_EBADTYPE): return "NC_EBADTYPE"; + case (NC_EBADDIM): return "NC_EBADDIM"; + case (NC_EUNLIMPOS): return "NC_EUNLIMPOS"; + case (NC_EMAXVARS): return "NC_EMAXVARS"; + case (NC_ENOTVAR): return "NC_ENOTVAR"; + case (NC_EGLOBAL): return "NC_EGLOBAL"; + case (NC_ENOTNC): return "NC_ENOTNC"; + case (NC_ESTS): return "NC_ESTS"; + case (NC_EMAXNAME): return "NC_EMAXNAME"; + case (NC_EUNLIMIT): return "NC_EUNLIMIT"; + case (NC_ENORECVARS): return "NC_ENORECVARS"; + case (NC_ECHAR): return "NC_ECHAR"; + case (NC_EEDGE): return "NC_EEDGE"; + case (NC_ESTRIDE): return "NC_ESTRIDE"; + case (NC_EBADNAME): return "NC_EBADNAME"; + case (NC_ERANGE): return "NC_ERANGE"; + case (NC_ENOMEM): return "NC_ENOMEM"; + case (NC_EVARSIZE): return "NC_EVARSIZE"; + case (NC_EDIMSIZE): return "NC_EDIMSIZE"; + case (NC_ETRUNC): return "NC_ETRUNC"; + case (NC_EAXISTYPE): return "NC_EAXISTYPE"; + case (NC_EDAP): return "NC_EDAP"; + case (NC_ECURL): return "NC_ECURL"; + case (NC_EIO): return "NC_EIO"; + case (NC_ENODATA): return "NC_ENODATA"; + case (NC_EDAPSVC): return "NC_EDAPSVC"; + case (NC_EDAS): return "NC_EDAS"; + case (NC_EDDS): return "NC_EDDS"; + case (NC_EDATADDS): return "NC_EDATADDS"; + case (NC_EDAPURL): return "NC_EDAPURL"; + case (NC_EDAPCONSTRAINT): return "NC_EDAPCONSTRAINT"; + case (NC_ETRANSLATION): return "NC_ETRANSLATION"; + case (NC_EACCESS): return "NC_EACCESS"; + case (NC_EAUTH): return "NC_EAUTH"; + case (NC_ENOTFOUND): return "NC_ENOTFOUND"; + case (NC_ECANTREMOVE): return "NC_ECANTREMOVE"; + case (NC_EHDFERR): return "NC_EHDFERR"; + case (NC_ECANTREAD): return "NC_ECANTREAD"; + case (NC_ECANTWRITE): return "NC_ECANTWRITE"; + case (NC_ECANTCREATE): return "NC_ECANTCREATE"; + case (NC_EFILEMETA): return "NC_EFILEMETA"; + case (NC_EDIMMETA): return "NC_EDIMMETA"; + case (NC_EATTMETA): return "NC_EATTMETA"; + case (NC_EVARMETA): return "NC_EVARMETA"; + case (NC_ENOCOMPOUND): return "NC_ENOCOMPOUND"; + case (NC_EATTEXISTS): return "NC_EATTEXISTS"; + case (NC_ENOTNC4): return "NC_ENOTNC4"; + case (NC_ESTRICTNC3): return "NC_ESTRICTNC3"; + case (NC_ENOTNC3): return "NC_ENOTNC3"; + case (NC_ENOPAR): return "NC_ENOPAR"; + case (NC_EPARINIT): return "NC_EPARINIT"; + case (NC_EBADGRPID): return "NC_EBADGRPID"; + case (NC_EBADTYPID): return "NC_EBADTYPID"; + case (NC_ETYPDEFINED): return "NC_ETYPDEFINED"; + case (NC_EBADFIELD): return "NC_EBADFIELD"; + case (NC_EBADCLASS): return "NC_EBADCLASS"; + case (NC_EMAPTYPE): return "NC_EMAPTYPE"; + case (NC_ELATEFILL): return "NC_ELATEFILL"; + case (NC_ELATEDEF): return "NC_ELATEDEF"; + case (NC_EDIMSCALE): return "NC_EDIMSCALE"; + case (NC_ENOGRP): return "NC_ENOGRP"; + case (NC_ESTORAGE): return "NC_ESTORAGE"; + case (NC_EBADCHUNK): return "NC_EBADCHUNK"; + case (NC_ENOTBUILT): return "NC_ENOTBUILT"; + case (NC_EDISKLESS): return "NC_EDISKLESS"; + case (NC_ECANTEXTEND): return "NC_ECANTEXTEND"; + case (NC_EMPI): return "NC_EMPI"; + // case (NC_EURL): return "NC_EURL"; + // case (NC_ECONSTRAINT): return "NC_ECONSTRAINT"; +#ifdef USE_PNETCDF + case (NC_ESMALL): return "NC_ESMALL"; + case (NC_ENOTINDEP): return "NC_ENOTINDEP"; + case (NC_EINDEP): return "NC_EINDEP"; + case (NC_EFILE): return "NC_EFILE"; + case (NC_EREAD): return "NC_EREAD"; + case (NC_EWRITE): return "NC_EWRITE"; + case (NC_EOFILE): return "NC_EOFILE"; + case (NC_EMULTITYPES): return "NC_EMULTITYPES"; + case (NC_EIOMISMATCH): return "NC_EIOMISMATCH"; + case (NC_ENEGATIVECNT): return "NC_ENEGATIVECNT"; + case (NC_EUNSPTETYPE): return "NC_EUNSPTETYPE"; + case (NC_EINVAL_REQUEST): return "NC_EINVAL_REQUEST"; + case (NC_EAINT_TOO_SMALL): return "NC_EAINT_TOO_SMALL"; + case (NC_ENOENT): return "NC_ENOENT"; +#ifdef NC_EMULTIDEFINE + case (NC_EMULTIDEFINE): return "NC_EMULTIDEFINE"; +#endif +#if PNETCDF_VERSION_MAJOR>=1 && PNETCDF_VERSION_MINOR>=3 + case (NC_ENOTSUPPORT): return "NC_ENOTSUPPORT"; + case (NC_ENULLBUF): return "NC_ENULLBUF"; + case (NC_EPREVATTACHBUF): return "NC_EPREVATTACHBUF"; + case (NC_ENULLABUF): return "NC_ENULLABUF"; + case (NC_EPENDINGBPUT): return "NC_EPENDINGBPUT"; + case (NC_EINSUFFBUF): return "NC_EINSUFFBUF"; +#endif +#if PNETCDF_VERSION_MAJOR>=1 && PNETCDF_VERSION_MINOR>=4 + case (NC_EINTOVERFLOW): return "NC_EINTOVERFLOW"; + case (NC_EMULTIDEFINE_OMODE): return "NC_EMULTIDEFINE_OMODE"; + case (NC_EMULTIDEFINE_DIM_NUM): return "NC_EMULTIDEFINE_DIM_NUM"; + case (NC_EMULTIDEFINE_DIM_SIZE): return "NC_EMULTIDEFINE_DIM_SIZE"; + case (NC_EMULTIDEFINE_DIM_NAME): return "NC_EMULTIDEFINE_DIM_NAME"; + case (NC_EMULTIDEFINE_VAR_NUM): return "NC_EMULTIDEFINE_VAR_NUM"; + case (NC_EMULTIDEFINE_VAR_NAME): return "NC_EMULTIDEFINE_VAR_NAME"; + case (NC_EMULTIDEFINE_VAR_NDIMS): return "NC_EMULTIDEFINE_VAR_NDIMS"; + case (NC_EMULTIDEFINE_VAR_DIMIDS): return "NC_EMULTIDEFINE_VAR_DIMIDS"; + case (NC_EMULTIDEFINE_VAR_TYPE): return "NC_EMULTIDEFINE_VAR_TYPE"; + case (NC_EMULTIDEFINE_VAR_LEN): return "NC_EMULTIDEFINE_VAR_LEN"; + case (NC_EMULTIDEFINE_NUMRECS): return "NC_EMULTIDEFINE_NUMRECS"; + case (NC_EMULTIDEFINE_VAR_BEGIN): return "NC_EMULTIDEFINE_VAR_BEGIN"; + case (NC_EMULTIDEFINE_ATTR_NUM): return "NC_EMULTIDEFINE_ATTR_NUM"; + case (NC_EMULTIDEFINE_ATTR_SIZE): return "NC_EMULTIDEFINE_ATTR_SIZE"; + case (NC_EMULTIDEFINE_ATTR_NAME): return "NC_EMULTIDEFINE_ATTR_NAME"; + case (NC_EMULTIDEFINE_ATTR_TYPE): return "NC_EMULTIDEFINE_ATTR_TYPE"; + case (NC_EMULTIDEFINE_ATTR_LEN): return "NC_EMULTIDEFINE_ATTR_LEN"; + case (NC_EMULTIDEFINE_ATTR_VAL): return "NC_EMULTIDEFINE_ATTR_VAL"; +#endif +#if PNETCDF_VERSION_MAJOR>=1 && PNETCDF_VERSION_MINOR>=5 + case (NC_ENOTENABLED): return "NC_ENOTENABLED"; + case (NC_EBAD_FILE): return "NC_EBAD_FILE"; + case (NC_ENO_SPACE): return "NC_ENO_SPACE"; + case (NC_EQUOTA): return "NC_EQUOTA"; + case (NC_EMULTIDEFINE_FNC_ARGS): return "NC_EMULTIDEFINE_FNC_ARGS"; +#endif +#if PNETCDF_VERSION_MAJOR>=1 && PNETCDF_VERSION_MINOR>=6 + case (NC_EINVAL_CMODE): return "NC_EINVAL_CMODE"; + case (NC_ENULLSTART): return "NC_ENULLSTART"; + case (NC_ENULLCOUNT): return "NC_ENULLCOUNT"; + case (NC_ETYPESIZE_MISMATCH): return "NC_ETYPESIZE_MISMATCH"; + case (NC_ETYPESIZE): return "NC_ETYPESIZE"; + case (NC_ETYPE_MISMATCH): return "NC_ETYPE_MISMATCH"; + case (NC_ESTRICTCDF2): return "NC_ESTRICTCDF2"; +#endif +#if PNETCDF_VERSION_MAJOR>=1 && PNETCDF_VERSION_MINOR>=7 + case (NC_ENOTRECVAR): return "NC_ENOTRECVAR"; + case (NC_ENOTFILL): return "NC_ENOTFILL"; + case (NC_EMULTIDEFINE_FILL_MODE): return "NC_EMULTIDEFINE_FILL_MODE"; + case (NC_EMULTIDEFINE_VAR_FILL_MODE): return "NC_EMULTIDEFINE_VAR_FILL_MODE"; + case (NC_EMULTIDEFINE_VAR_FILL_VALUE): return "NC_EMULTIDEFINE_VAR_FILL_VALUE"; +#endif +#if PNETCDF_VERSION_MAJOR>=1 && PNETCDF_VERSION_MINOR>=8 + case (NC_EPENDING): return "NC_EPENDING"; + case (NC_EINVAL_OMODE): return "NC_EINVAL_OMODE"; + case (NC_EMULTIDEFINE_CMODE): return "NC_EMULTIDEFINE_CMODE"; +#endif +#endif + default: + sprintf(unknown_str,"Unknown code %d",err); + } + return unknown_str; +} + + +int +test_nc_against_pnetcdf(void) +{ +#ifdef USE_PNETCDF + int ncid; /* netCDF id */ + int err; /* status */ + + /* Using netCDF library to create file */ + err = nc_create(scratch, NC_CLOBBER, &ncid); + IF (err != NC_NOERR) error("nc_create: %s", nc_strerror(err)); + def_dims(ncid); + def_vars(ncid); + put_atts(ncid); + err = nc_enddef(ncid); + IF (err != NC_NOERR) error("nc_enddef: %s", nc_strerror(err)); + put_vars(ncid); + err = nc_close (ncid); + IF (err != NC_NOERR) error("nc_close: %s", nc_strerror(err)); + + /* Using PnetCDF library to check file */ + err = nc_open_par(scratch, NC_NOWRITE|NC_PNETCDF, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); + IF (err != NC_NOERR) error("nc_open_par: %s", nc_strerror(err)); + check_dims(ncid); + check_vars(ncid); + check_atts(ncid); + err = nc_close (ncid); + IF (err != NC_NOERR) error("nc_close: %s", nc_strerror(err)); + + /* Using PnetCDF library to create file */ + err = nc_create_par(scratch, NC_PNETCDF, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); + IF (err != NC_NOERR) error("nc_create_par: %s", nc_strerror(err)); + def_dims(ncid); + def_vars(ncid); + put_atts(ncid); + err = nc_enddef(ncid); + IF (err != NC_NOERR) error("nc_enddef: %s", nc_strerror(err)); + put_vars(ncid); + err = nc_close (ncid); + IF (err != NC_NOERR) error("nc_close: %s", nc_strerror(err)); + + /* Using NetCDF library to check file */ + err = nc_open(scratch, NC_NOWRITE, &ncid); + IF (err != NC_NOERR) error("nc_open: %s", nc_strerror(err)); + check_dims(ncid); + check_vars(ncid); + check_atts(ncid); + err = nc_close (ncid); + IF (err != NC_NOERR) error("nc_close: %s", nc_strerror(err)); + err = nc_delete(scratch); + IF (err != NC_NOERR) error("remove of %s failed", scratch); +#endif + return 1; +} diff --git a/nc_test4/tst_converts.c b/nc_test4/tst_converts.c index e0e3deb464..183da06de0 100644 --- a/nc_test4/tst_converts.c +++ b/nc_test4/tst_converts.c @@ -70,8 +70,12 @@ create_file(int format, unsigned char *uchar_out) if (nc_def_var(ncid, VAR1_NAME, NC_BYTE, 1, dimids, &varid)) ERR; if (nc_enddef(ncid)) ERR; retval = nc_put_var_uchar(ncid, varid, uchar_out); - if ((format != NC_FORMAT_NETCDF4) && retval) ERR; - if ((format == NC_FORMAT_NETCDF4) && (retval != NC_ERANGE)) ERR; + if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA) + { + if (retval != NC_ERANGE) ERR; + } + else if (retval != NC_NOERR) ERR; + if (nc_close(ncid)) ERR; return NC_NOERR; } @@ -105,7 +109,7 @@ check_file(int format, unsigned char *uchar_out) * because range errors are not generated for byte type * conversions. */ res = nc_get_var_uchar(ncid, 0, uchar_in); - if (format == NC_FORMAT_NETCDF4) + if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA) { if (res != NC_ERANGE) ERR; } diff --git a/nc_test4/tst_files.c b/nc_test4/tst_files.c index 5b949a9bec..1fe342c805 100644 --- a/nc_test4/tst_files.c +++ b/nc_test4/tst_files.c @@ -502,8 +502,11 @@ test_redef(int format) /* Add att. */ ret = nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_BYTE, 1, &uchar_out); - if (format != NC_FORMAT_NETCDF4 && ret) ERR; - else if (format == NC_FORMAT_NETCDF4 && ret != NC_ERANGE) ERR; + if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA) + { + if (ret != NC_ERANGE) ERR; + } + else if (ret) ERR; /* Check it out. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; @@ -539,7 +542,7 @@ test_redef(int format) if (nc_get_att_int(ncid, NC_GLOBAL, REDEF_ATT2_NAME, &int_in)) ERR; if (int_in != short_out) ERR; ret = nc_get_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, &uchar_in); - if (format == NC_FORMAT_NETCDF4) + if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA) { if (ret != NC_ERANGE) ERR; } diff --git a/ncdump/Makefile.am b/ncdump/Makefile.am index ce1be6d0b0..dee4c2b51b 100644 --- a/ncdump/Makefile.am +++ b/ncdump/Makefile.am @@ -132,7 +132,10 @@ 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 \ -nc4_fileinfo.nc hdf5_fileinfo.hdf +nc4_fileinfo.nc hdf5_fileinfo.hdf \ +ref_hdf5_compat1.nc ref_hdf5_compat2.nc ref_hdf5_compat3.nc \ +ref_tst_compounds.nc ref_tst_dims.nc ref_tst_interops4.nc \ +ref_tst_xplatform2_1.nc ref_tst_xplatform2_2.nc # These files all have to be included with the distribution. EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \ @@ -169,3 +172,6 @@ tst_ncgen4_diff.sh tst_ncgen4_cycle.sh ref_ctest.c ref_ctest64.c CLEANFILES += results/*.nc results/*.dmp results/*.dmp2 tmp*.cdl tst_bug324.nc DISTCLEANFILES = results + +clean-local: + -rm -rf results diff --git a/ncgen/ncgenl.c b/ncgen/ncgenl.c index 2987187cf3..55cd2ef3a6 100644 --- a/ncgen/ncgenl.c +++ b/ncgen/ncgenl.c @@ -1,5 +1,5 @@ -#line 3 "ncgenl.c" +#line 3 "lex.ncg.c" #define YY_INT_ALIGNED short int @@ -65,6 +65,7 @@ typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; @@ -171,7 +172,12 @@ typedef unsigned int flex_uint32_t; typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif -extern int ncgleng; +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t ncgleng; extern FILE *ncgin, *ncgout; @@ -197,11 +203,6 @@ extern FILE *ncgin, *ncgout; #define unput(c) yyunput( c, (yytext_ptr) ) -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state @@ -219,7 +220,7 @@ struct yy_buffer_state /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - int yy_n_chars; + yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -289,8 +290,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* yy_hold_char holds the character lost when ncgtext is formed. */ static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int ncgleng; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t ncgleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; @@ -318,7 +319,7 @@ static void ncg_init_buffer (YY_BUFFER_STATE b,FILE *file ); YY_BUFFER_STATE ncg_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE ncg_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE ncg_scan_bytes (yyconst char *bytes,int len ); +YY_BUFFER_STATE ncg_scan_bytes (yyconst char *bytes,yy_size_t len ); void *ncgalloc (yy_size_t ); void *ncgrealloc (void *,yy_size_t ); @@ -373,7 +374,7 @@ static void yy_fatal_error (yyconst char msg[] ); */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ - ncgleng = (size_t) (yy_cp - yy_bp); \ + ncgleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; @@ -1319,7 +1320,7 @@ ID ([A-Za-z_]|{UTF8})([A-Z.@#\[\]a-z_0-9+-]|{UTF8})* /* Note: this definition of string will work for utf8 as well, although it is a very relaxed definition */ -#line 1323 "ncgenl.c" +#line 1324 "lex.ncg.c" #define INITIAL 0 #define ST_C_COMMENT 1 @@ -1360,7 +1361,7 @@ FILE *ncgget_out (void ); void ncgset_out (FILE * out_str ); -int ncgget_leng (void ); +yy_size_t ncgget_leng (void ); char *ncgget_text (void ); @@ -1421,7 +1422,7 @@ static int input (void ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - int n; \ + yy_size_t n; \ for ( n = 0; n < max_size && \ (c = getc( ncgin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -1505,7 +1506,7 @@ YY_DECL #line 217 "ncgen.l" -#line 1509 "ncgenl.c" +#line 1510 "lex.ncg.c" if ( !(yy_init) ) { @@ -2118,7 +2119,7 @@ YY_RULE_SETUP #line 570 "ncgen.l" ECHO; YY_BREAK -#line 2122 "ncgenl.c" +#line 2123 "lex.ncg.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(TEXT): yyterminate(); @@ -2305,7 +2306,7 @@ static int yy_get_next_buffer (void) else { - int num_to_read = + yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) @@ -2319,7 +2320,7 @@ static int yy_get_next_buffer (void) if ( b->yy_is_our_buffer ) { - int new_size = b->yy_buf_size * 2; + yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -2350,7 +2351,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); + (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } @@ -2460,7 +2461,7 @@ static int yy_get_next_buffer (void) if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register int number_to_move = (yy_n_chars) + 2; + register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = @@ -2509,7 +2510,7 @@ static int yy_get_next_buffer (void) else { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) @@ -2533,7 +2534,7 @@ static int yy_get_next_buffer (void) case EOB_ACT_END_OF_FILE: { if ( ncgwrap( ) ) - return EOF; + return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; @@ -2785,7 +2786,7 @@ void ncgpop_buffer_state (void) */ static void ncgensure_buffer_stack (void) { - int num_to_alloc; + yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { @@ -2882,12 +2883,11 @@ YY_BUFFER_STATE ncg_scan_string (yyconst char * yystr ) * * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE ncg_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +YY_BUFFER_STATE ncg_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; - yy_size_t n; - int i; + yy_size_t n, i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -2969,7 +2969,7 @@ FILE *ncgget_out (void) /** Get the length of the current token. * */ -int ncgget_leng (void) +yy_size_t ncgget_leng (void) { return ncgleng; } diff --git a/ncgen/ncgeny.c b/ncgen/ncgeny.c index da81d607a2..61ad4e38e6 100644 --- a/ncgen/ncgeny.c +++ b/ncgen/ncgeny.c @@ -1,13 +1,14 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 2.3. */ -/* Bison implementation for Yacc-like parsers in C +/* Skeleton implementation for Bison's Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + 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 3 of the License, or - (at your option) any later version. + the Free Software Foundation; either version 2, 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 @@ -15,7 +16,9 @@ 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, see . */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -44,7 +47,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -52,25 +55,136 @@ /* Pure parsers. */ #define YYPURE 0 -/* Push parsers. */ -#define YYPUSH 0 +/* Using locations. */ +#define YYLSP_NEEDED 0 -/* Pull parsers. */ -#define YYPULL 1 +/* Substitute the variable and function names. */ +#define yyparse ncgparse +#define yylex ncglex +#define yyerror ncgerror +#define yylval ncglval +#define yychar ncgchar +#define yydebug ncgdebug +#define yynerrs ncgnerrs + + +/* Tokens. */ +#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, + _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 _NCPROPS 305 +#define _ISNETCDF4 306 +#define _SUPERBLOCK 307 +#define DATASETID 308 -/* Substitute the variable and function names. */ -#define yyparse ncgparse -#define yylex ncglex -#define yyerror ncgerror -#define yydebug ncgdebug -#define yynerrs ncgnerrs -#define yylval ncglval -#define yychar ncgchar /* Copy the first part of user declarations. */ -#line 11 "ncgen.y" /* yacc.c:339 */ +#line 11 "ncgen.y" /* static char SccsId[] = "$Id: ncgen.y,v 1.42 2010/05/18 21:32:46 dmh Exp $"; @@ -195,15 +309,11 @@ static void yyerror(fmt,va_alist) const char* fmt; va_dcl; extern int lex_init(void); -#line 199 "ncgeny.c" /* yacc.c:339 */ -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# endif +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE @@ -213,109 +323,37 @@ extern int lex_init(void); # define YYERROR_VERBOSE 1 #endif -/* In a future release of Bison, this section will be replaced - by #include "ncgeny.h". */ -#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; +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 #endif -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - 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 - -/* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -union YYSTYPE +typedef union YYSTYPE +#line 138 "ncgen.y" { -#line 138 "ncgen.y" /* yacc.c:355 */ - 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 302 "ncgeny.c" /* yacc.c:355 */ -}; - -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 +} +/* Line 193 of yacc.c. */ +#line 344 "ncgen.tab.c" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 #endif -extern YYSTYPE ncglval; - -int ncgparse (void); - -#endif /* !YY_NCG_NCGEN_TAB_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 319 "ncgeny.c" /* yacc.c:358 */ + +/* Line 216 of yacc.c. */ +#line 357 "ncgen.tab.c" #ifdef short # undef short @@ -329,8 +367,11 @@ typedef unsigned char yytype_uint8; #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; -#else +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; +#else +typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 @@ -350,7 +391,8 @@ typedef short int yytype_int16; # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t -# elif ! defined YYSIZE_T +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else @@ -364,68 +406,39 @@ typedef short int yytype_int16; # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -# else -# define YY_ATTRIBUTE(Spec) /* empty */ -# endif -#endif - -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YYUSE(e) ((void) (e)) #else -# define YYUSE(E) /* empty */ +# define YYUSE(e) /* empty */ #endif -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) #else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int i) +#else +static int +YYID (i) + int i; #endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ +{ + return i; +} #endif - #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -443,11 +456,11 @@ typedef short int yytype_int16; # define alloca _alloca # else # define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 +# ifndef _STDLIB_H +# define _STDLIB_H 1 # endif # endif # endif @@ -455,8 +468,8 @@ typedef short int yytype_int16; # endif # ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely @@ -470,23 +483,25 @@ typedef short int yytype_int16; # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ +# if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) + && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 +# ifndef _STDLIB_H +# define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif @@ -496,14 +511,14 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -}; + yytype_int16 yyss; + YYSTYPE yyvs; + }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) @@ -514,46 +529,42 @@ union yyalloc ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) -# define YYCOPY_NEEDED 1 +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) #endif -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - /* YYFINAL -- State number of the termination state. */ #define YYFINAL 5 /* YYLAST -- Last index in YYTABLE. */ @@ -565,19 +576,17 @@ union yyalloc #define YYNNTS 67 /* YYNRULES -- Number of rules. */ #define YYNRULES 151 -/* YYNSTATES -- Number of states. */ +/* YYNRULES -- Number of states. */ #define YYNSTATES 258 -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 308 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -614,7 +623,79 @@ static const yytype_uint8 yytranslate[] = }; #if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 7, 9, 14, 20, 21, 24, 25, + 26, 36, 37, 39, 42, 44, 47, 49, 51, 54, + 57, 60, 63, 66, 67, 69, 76, 78, 82, 86, + 92, 98, 104, 107, 111, 114, 116, 118, 120, 122, + 124, 126, 128, 130, 132, 134, 136, 137, 139, 142, + 145, 149, 151, 153, 155, 159, 163, 167, 169, 170, + 172, 175, 178, 182, 184, 186, 189, 191, 195, 198, + 199, 203, 205, 209, 211, 213, 217, 220, 221, 225, + 227, 231, 233, 235, 237, 239, 241, 243, 244, 248, + 253, 258, 263, 268, 275, 281, 287, 294, 300, 306, + 312, 318, 324, 330, 336, 341, 343, 345, 346, 348, + 351, 354, 358, 362, 364, 366, 367, 369, 373, 375, + 379, 381, 383, 385, 387, 389, 391, 393, 398, 400, + 404, 406, 408, 410, 412, 414, 416, 418, 420, 422, + 424, 426, 428, 430, 434, 436, 438, 440, 442, 444, + 446, 448 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int16 yyrhs[] = +{ + 64, 0, -1, 30, 65, 66, -1, 53, -1, 54, + 67, 68, 55, -1, 110, 72, 87, 93, 113, -1, + -1, 68, 69, -1, -1, -1, 37, 129, 54, 70, + 67, 68, 71, 55, 110, -1, -1, 32, -1, 32, + 73, -1, 75, -1, 73, 75, -1, 129, -1, 76, + -1, 111, 56, -1, 78, 77, -1, 83, 77, -1, + 82, 77, -1, 81, 77, -1, -1, 56, -1, 86, + 34, 74, 54, 79, 55, -1, 80, -1, 79, 57, + 80, -1, 129, 58, 126, -1, 35, 59, 20, 60, + 74, -1, 108, 59, 61, 60, 74, -1, 33, 74, + 54, 84, 55, -1, 85, 56, -1, 84, 85, 56, + -1, 108, 102, -1, 4, -1, 5, -1, 6, -1, + 7, -1, 8, -1, 9, -1, 10, -1, 11, -1, + 12, -1, 13, -1, 14, -1, -1, 28, -1, 28, + 88, -1, 89, 56, -1, 88, 89, 56, -1, 90, + -1, 111, -1, 91, -1, 90, 57, 91, -1, 92, + 58, 126, -1, 92, 58, 3, -1, 129, -1, -1, + 29, -1, 29, 94, -1, 95, 56, -1, 94, 95, + 56, -1, 96, -1, 111, -1, 108, 97, -1, 98, + -1, 97, 57, 98, -1, 129, 99, -1, -1, 59, + 100, 60, -1, 101, -1, 100, 57, 101, -1, 112, + -1, 103, -1, 102, 57, 103, -1, 129, 104, -1, + -1, 59, 105, 60, -1, 106, -1, 105, 57, 106, + -1, 24, -1, 20, -1, 109, -1, 109, -1, 112, + -1, 86, -1, -1, 111, 56, 110, -1, 62, 50, + 58, 127, -1, 62, 51, 58, 128, -1, 62, 52, + 58, 126, -1, 62, 129, 58, 116, -1, 108, 109, + 62, 129, 58, 116, -1, 109, 62, 129, 58, 116, + -1, 109, 62, 41, 58, 116, -1, 108, 109, 62, + 41, 58, 116, -1, 109, 62, 43, 58, 127, -1, + 109, 62, 44, 58, 125, -1, 109, 62, 49, 58, + 128, -1, 109, 62, 45, 58, 126, -1, 109, 62, + 46, 58, 128, -1, 109, 62, 47, 58, 127, -1, + 109, 62, 48, 58, 128, -1, 62, 42, 58, 127, + -1, 129, -1, 38, -1, -1, 31, -1, 31, 114, + -1, 115, 56, -1, 114, 115, 56, -1, 107, 58, + 116, -1, 117, -1, 118, -1, -1, 119, -1, 116, + 57, 119, -1, 120, -1, 54, 116, 55, -1, 124, + -1, 36, -1, 39, -1, 40, -1, 121, -1, 122, + -1, 112, -1, 129, 59, 123, 60, -1, 124, -1, + 123, 57, 124, -1, 17, -1, 18, -1, 19, -1, + 20, -1, 21, -1, 22, -1, 23, -1, 24, -1, + 25, -1, 26, -1, 27, -1, 16, -1, 126, -1, + 125, 57, 126, -1, 20, -1, 24, -1, 21, -1, + 25, -1, 16, -1, 127, -1, 126, -1, 15, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 218, 218, 224, 226, 233, 240, 240, 243, 252, @@ -636,7 +717,7 @@ static const yytype_uint16 yyrline[] = }; #endif -#if YYDEBUG || YYERROR_VERBOSE || 1 +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = @@ -653,24 +734,24 @@ static const char *const yytname[] = "_NCPROPS", "_ISNETCDF4", "_SUPERBLOCK", "DATASETID", "'{'", "'}'", "';'", "','", "'='", "'('", "')'", "'*'", "':'", "$accept", "ncdesc", "datasetid", "rootgroup", "groupbody", "subgrouplist", "namedgroup", - "$@1", "$@2", "typesection", "typedecls", "typename", - "type_or_attr_decl", "typedecl", "optsemicolon", "enumdecl", - "enumidlist", "enumid", "opaquedecl", "vlendecl", "compounddecl", - "fields", "field", "primtype", "dimsection", "dimdecls", - "dim_or_attr_decl", "dimdeclist", "dimdecl", "dimd", "vasection", - "vadecls", "vadecl_or_attr", "vardecl", "varlist", "varspec", "dimspec", - "dimlist", "dimref", "fieldlist", "fieldspec", "fielddimspec", - "fielddimlist", "fielddim", "varref", "typeref", "type_var_ref", - "attrdecllist", "attrdecl", "path", "datasection", "datadecls", - "datadecl", "datalist", "datalist0", "datalist1", "dataitem", - "constdata", "econstref", "function", "arglist", "simpleconstant", - "intlist", "constint", "conststring", "constbool", "ident", YY_NULLPTR + "@1", "@2", "typesection", "typedecls", "typename", "type_or_attr_decl", + "typedecl", "optsemicolon", "enumdecl", "enumidlist", "enumid", + "opaquedecl", "vlendecl", "compounddecl", "fields", "field", "primtype", + "dimsection", "dimdecls", "dim_or_attr_decl", "dimdeclist", "dimdecl", + "dimd", "vasection", "vadecls", "vadecl_or_attr", "vardecl", "varlist", + "varspec", "dimspec", "dimlist", "dimref", "fieldlist", "fieldspec", + "fielddimspec", "fielddimlist", "fielddim", "varref", "typeref", + "type_var_ref", "attrdecllist", "attrdecl", "path", "datasection", + "datadecls", "datadecl", "datalist", "datalist0", "datalist1", + "dataitem", "constdata", "econstref", "function", "arglist", + "simpleconstant", "intlist", "constint", "conststring", "constbool", + "ident", 0 }; #endif # ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, @@ -683,51 +764,51 @@ static const yytype_uint16 yytoknum[] = }; # endif -#define YYPACT_NINF -133 - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-133))) - -#define YYTABLE_NINF -106 - -#define yytable_value_is_error(Yytable_value) \ - 0 +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 63, 64, 65, 66, 67, 68, 68, 70, 71, + 69, 72, 72, 72, 73, 73, 74, 75, 75, 76, + 76, 76, 76, 77, 77, 78, 79, 79, 80, 81, + 82, 83, 84, 84, 85, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 87, 87, 87, 88, + 88, 89, 89, 90, 90, 91, 91, 92, 93, 93, + 93, 94, 94, 95, 95, 96, 97, 97, 98, 99, + 99, 100, 100, 101, 102, 102, 103, 104, 104, 105, + 105, 106, 106, 107, 108, 109, 109, 110, 110, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 112, 112, 113, 113, 113, + 114, 114, 115, 116, 116, 117, 118, 118, 119, 119, + 120, 120, 120, 120, 120, 120, 121, 122, 123, 123, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 125, 125, 126, 126, 126, 126, 127, 128, + 128, 129 +}; - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int16 yypact[] = +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = { - -11, -48, 20, -133, -19, -133, 210, -133, -133, -133, - -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, - -133, -3, -133, -133, 332, -16, 8, -4, -133, -133, - 18, 19, 29, 41, 48, -22, 47, 128, 56, 75, - 210, 94, 94, 136, 33, 281, 102, -133, -133, 2, - 63, 64, 65, 68, 71, 74, 76, 77, 78, 102, - 82, 56, -133, -133, 81, 81, 81, 81, 99, 222, - 88, 210, 117, -133, -133, -133, -133, -133, -133, -133, - -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, - -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, - 281, -133, 90, -133, -133, -133, -133, -133, -133, -133, - 89, 97, 91, 100, 281, 94, 33, 33, 136, 94, - 136, 136, 281, 105, -133, 142, -133, -133, -133, -133, - -133, -133, 102, 109, -133, 210, 107, 121, -133, 123, - -133, 125, 210, 148, 35, 281, 333, -133, 281, 281, - 90, -133, 129, -133, -133, -133, -133, -133, -133, 90, - 332, 127, 131, 130, 132, -133, 102, 95, 210, 133, - -133, 332, -133, 332, -133, -133, -133, -23, -133, 210, - 90, 90, 33, 278, 135, 102, -133, 102, 102, 102, - -133, -133, -133, -133, -133, 137, -133, 138, -133, -32, - 139, -133, 332, 140, 333, -133, -133, -133, -133, 144, - -133, 141, -133, 145, -133, 45, -133, 143, -133, -133, - 102, -12, -133, 281, 147, -133, -133, 157, -133, 102, - -2, -133, -133, 102, 33, -133, 146, 25, -133, -133, - 90, -133, 151, -133, -133, -133, 26, -133, -133, -133, - -12, -133, 210, -2, -133, -133, -133, -133 + 0, 2, 3, 1, 4, 5, 0, 2, 0, 0, + 9, 0, 1, 2, 1, 2, 1, 1, 2, 2, + 2, 2, 2, 0, 1, 6, 1, 3, 3, 5, + 5, 5, 2, 3, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 2, 2, + 3, 1, 1, 1, 3, 3, 3, 1, 0, 1, + 2, 2, 3, 1, 1, 2, 1, 3, 2, 0, + 3, 1, 3, 1, 1, 3, 2, 0, 3, 1, + 3, 1, 1, 1, 1, 1, 1, 0, 3, 4, + 4, 4, 4, 6, 5, 5, 6, 5, 5, 5, + 5, 5, 5, 5, 4, 1, 1, 0, 1, 2, + 2, 3, 3, 1, 1, 0, 1, 3, 1, 3, + 1, 1, 1, 1, 1, 1, 1, 4, 1, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, + 1, 1 }; - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 0, 0, 3, 0, 1, 87, 2, 35, 36, @@ -758,19 +839,7 @@ static const yytype_uint8 yydefact[] = 0, 70, 87, 0, 78, 72, 10, 80 }; - /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -133, -133, -133, -133, 28, 4, -133, -133, -133, -133, - -133, -109, 150, -133, 30, -133, -133, 5, -133, -133, - -133, -133, 57, -25, -133, -133, 104, -133, 79, -133, - -133, -133, 73, -133, -133, 22, -133, -133, -7, -133, - 15, -133, -133, -6, -133, -29, -18, -39, -30, -41, - -133, -133, 44, -93, -133, -133, 106, -133, -133, -133, - -133, -132, -133, -42, -31, -76, -21 -}; - - /* YYDEFGOTO[NTERM-NUM]. */ +/* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 2, 4, 7, 22, 35, 48, 179, 242, 39, @@ -782,9 +851,56 @@ static const yytype_int16 yydefgoto[] = 177, 109, 152, 81, 82, 83, 29 }; - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -133 +static const yytype_int16 yypact[] = +{ + -11, -48, 20, -133, -19, -133, 210, -133, -133, -133, + -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, + -133, -3, -133, -133, 332, -16, 8, -4, -133, -133, + 18, 19, 29, 41, 48, -22, 47, 128, 56, 75, + 210, 94, 94, 136, 33, 281, 102, -133, -133, 2, + 63, 64, 65, 68, 71, 74, 76, 77, 78, 102, + 82, 56, -133, -133, 81, 81, 81, 81, 99, 222, + 88, 210, 117, -133, -133, -133, -133, -133, -133, -133, + -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, + -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, + 281, -133, 90, -133, -133, -133, -133, -133, -133, -133, + 89, 97, 91, 100, 281, 94, 33, 33, 136, 94, + 136, 136, 281, 105, -133, 142, -133, -133, -133, -133, + -133, -133, 102, 109, -133, 210, 107, 121, -133, 123, + -133, 125, 210, 148, 35, 281, 333, -133, 281, 281, + 90, -133, 129, -133, -133, -133, -133, -133, -133, 90, + 332, 127, 131, 130, 132, -133, 102, 95, 210, 133, + -133, 332, -133, 332, -133, -133, -133, -23, -133, 210, + 90, 90, 33, 278, 135, 102, -133, 102, 102, 102, + -133, -133, -133, -133, -133, 137, -133, 138, -133, -32, + 139, -133, 332, 140, 333, -133, -133, -133, -133, 144, + -133, 141, -133, 145, -133, 45, -133, 143, -133, -133, + 102, -12, -133, 281, 147, -133, -133, 157, -133, 102, + -2, -133, -133, 102, 33, -133, 146, 25, -133, -133, + 90, -133, 151, -133, -133, -133, 26, -133, -133, -133, + -12, -133, 210, -2, -133, -133, -133, -133 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -133, -133, -133, -133, 28, 4, -133, -133, -133, -133, + -133, -109, 150, -133, 30, -133, -133, 5, -133, -133, + -133, -133, 57, -25, -133, -133, 104, -133, 79, -133, + -133, -133, 73, -133, -133, 22, -133, -133, -7, -133, + 15, -133, -133, -6, -133, -29, -18, -39, -30, -41, + -133, -133, 44, -93, -133, -133, 106, -133, -133, -133, + -133, -132, -133, -42, -31, -76, -21 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -106 static const yytype_int16 yytable[] = { 34, 73, 84, 19, 101, 3, 36, 144, 70, 69, @@ -869,8 +985,8 @@ static const yytype_int16 yycheck[] = 38 }; - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 30, 64, 53, 65, 0, 54, 66, 4, 5, @@ -901,84 +1017,96 @@ static const yytype_uint8 yystos[] = 57, 60, 55, 57, 60, 101, 110, 106 }; - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 63, 64, 65, 66, 67, 68, 68, 70, 71, - 69, 72, 72, 72, 73, 73, 74, 75, 75, 76, - 76, 76, 76, 77, 77, 78, 79, 79, 80, 81, - 82, 83, 84, 84, 85, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 87, 87, 87, 88, - 88, 89, 89, 90, 90, 91, 91, 92, 93, 93, - 93, 94, 94, 95, 95, 96, 97, 97, 98, 99, - 99, 100, 100, 101, 102, 102, 103, 104, 104, 105, - 105, 106, 106, 107, 108, 109, 109, 110, 110, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 112, 112, 113, 113, 113, - 114, 114, 115, 116, 116, 117, 118, 118, 119, 119, - 120, 120, 120, 120, 120, 120, 121, 122, 123, 123, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 125, 125, 126, 126, 126, 126, 127, 128, - 128, 129 -}; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 3, 1, 4, 5, 0, 2, 0, 0, - 9, 0, 1, 2, 1, 2, 1, 1, 2, 2, - 2, 2, 2, 0, 1, 6, 1, 3, 3, 5, - 5, 5, 2, 3, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, 2, 2, - 3, 1, 1, 1, 3, 3, 3, 1, 0, 1, - 2, 2, 3, 1, 1, 2, 1, 3, 2, 0, - 3, 1, 3, 1, 1, 3, 2, 0, 3, 1, - 3, 1, 1, 1, 1, 1, 1, 0, 3, 4, - 4, 4, 4, 6, 5, 5, 6, 5, 5, 5, - 5, 5, 5, 5, 4, 1, 1, 0, 1, 2, - 2, 3, 3, 1, 1, 0, 1, 3, 1, 3, - 1, 1, 1, 1, 1, 1, 1, 4, 1, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, - 1, 1 -}; +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + /* Enable debugging if requested. */ #if YYDEBUG @@ -987,46 +1115,54 @@ while (0) # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -/* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif - +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif { - FILE *yyo = yyoutput; - YYUSE (yyo); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); # endif - YYUSE (yytype); + switch (yytype) + { + default: + break; + } } @@ -1034,11 +1170,22 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue | Print this symbol on YYOUTPUT. | `--------------------------------*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif { - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); @@ -1049,54 +1196,66 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) | TOP (included). | `------------------------------------------------------------------*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +#else +static void +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; +#endif { YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif { - unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; + unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); + yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - YYFPRINTF (stderr, "\n"); + fprintf (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + fprintf (stderr, "\n"); } } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule); \ -} while (0) +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ @@ -1110,7 +1269,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -1125,6 +1284,7 @@ int yydebug; # define YYMAXDEPTH 10000 #endif + #if YYERROR_VERBOSE @@ -1133,8 +1293,15 @@ int yydebug; # define yystrlen strlen # else /* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) @@ -1150,8 +1317,16 @@ yystrlen (const char *yystr) # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif { char *yyd = yydest; const char *yys = yysrc; @@ -1181,27 +1356,27 @@ yytnamerr (char *yyres, const char *yystr) char const *yyp = yystr; for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } do_not_strip_quotes: ; } @@ -1212,209 +1387,211 @@ yytnamerr (char *yyres, const char *yystr) } # endif -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) { - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } + int yyn = yypact[yystate]; - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; } #endif /* YYERROR_VERBOSE */ + /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif { YYUSE (yyvaluep); + if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); - YY_IGNORE_MAYBE_UNINITIALIZED_END + switch (yytype) + { + + default: + break; + } } + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ -/* The lookahead symbol. */ + +/* The look-ahead symbol. */ int yychar; -/* The semantic value of the lookahead symbol. */ +/* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; + /* Number of syntax errors so far. */ int yynerrs; + /*----------. | yyparse. | `----------*/ +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) int yyparse (void) -{ - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; +#else +int +yyparse () +#endif +#endif +{ + + int yystate; int yyn; int yyresult; - /* Lookahead token as an internal (translated) token number. */ + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; @@ -1422,22 +1599,54 @@ yyparse (void) YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; + + + #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; /*------------------------------------------------------------. @@ -1458,23 +1667,25 @@ yyparse (void) #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1482,22 +1693,23 @@ yyparse (void) # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -1505,18 +1717,16 @@ yyparse (void) yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; + YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - if (yystate == YYFINAL) - YYACCEPT; - goto yybackup; /*-----------. @@ -1525,20 +1735,20 @@ yyparse (void) yybackup: /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ + look-ahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to lookahead token. */ + /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) + if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a lookahead token if don't already have one. */ + /* Not known => get a look-ahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); - yychar = yylex (); + yychar = YYLEX; } if (yychar <= YYEOF) @@ -1560,27 +1770,29 @@ yyparse (void) yyn = yytable[yyn]; if (yyn <= 0) { - if (yytable_value_is_error (yyn)) - goto yyerrlab; + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; yyn = -yyn; goto yyreduce; } + if (yyn == YYFINAL) + YYACCEPT; + /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the lookahead token. */ + /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token. */ - yychar = YYEMPTY; + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; @@ -1603,7 +1815,7 @@ yyparse (void) yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. + `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison @@ -1617,84 +1829,75 @@ yyparse (void) switch (yyn) { case 2: -#line 221 "ncgen.y" /* yacc.c:1646 */ - {if (error_count > 0) YYABORT;} -#line 1623 "ncgeny.c" /* yacc.c:1646 */ +#line 221 "ncgen.y" + {if (error_count > 0) YYABORT;;} break; case 3: -#line 224 "ncgen.y" /* yacc.c:1646 */ - {createrootgroup(datasetname);} -#line 1629 "ncgeny.c" /* yacc.c:1646 */ +#line 224 "ncgen.y" + {createrootgroup(datasetname);;} break; case 8: -#line 243 "ncgen.y" /* yacc.c:1646 */ +#line 243 "ncgen.y" { - Symbol* id = (yyvsp[-1].sym); + Symbol* id = (yyvsp[(2) - (3)].sym); markcdf4("Group specification"); if(creategroup(id) == NULL) yyerror("duplicate group declaration within parent group for %s", id->name); - } -#line 1641 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 9: -#line 252 "ncgen.y" /* yacc.c:1646 */ - {listpop(groupstack);} -#line 1647 "ncgeny.c" /* yacc.c:1646 */ +#line 252 "ncgen.y" + {listpop(groupstack);;} break; case 12: -#line 258 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1653 "ncgeny.c" /* yacc.c:1646 */ +#line 258 "ncgen.y" + {;} break; case 13: -#line 260 "ncgen.y" /* yacc.c:1646 */ - {markcdf4("Type specification");} -#line 1659 "ncgeny.c" /* yacc.c:1646 */ +#line 260 "ncgen.y" + {markcdf4("Type specification");;} break; case 16: -#line 266 "ncgen.y" /* yacc.c:1646 */ +#line 266 "ncgen.y" { /* Use when defining a type */ - (yyvsp[0].sym)->objectclass = NC_TYPE; - if(dupobjectcheck(NC_TYPE,(yyvsp[0].sym))) + (yyvsp[(1) - (1)].sym)->objectclass = NC_TYPE; + if(dupobjectcheck(NC_TYPE,(yyvsp[(1) - (1)].sym))) yyerror("duplicate type declaration for %s", - (yyvsp[0].sym)->name); - listpush(typdefs,(void*)(yyvsp[0].sym)); - } -#line 1671 "ncgeny.c" /* yacc.c:1646 */ + (yyvsp[(1) - (1)].sym)->name); + listpush(typdefs,(void*)(yyvsp[(1) - (1)].sym)); + ;} break; case 17: -#line 275 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1677 "ncgeny.c" /* yacc.c:1646 */ +#line 275 "ncgen.y" + {;} break; case 18: -#line 275 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1683 "ncgeny.c" /* yacc.c:1646 */ +#line 275 "ncgen.y" + {;} break; case 25: -#line 289 "ncgen.y" /* yacc.c:1646 */ +#line 289 "ncgen.y" { int i; - addtogroup((yyvsp[-3].sym)); /* sets prefix*/ - (yyvsp[-3].sym)->objectclass=NC_TYPE; - (yyvsp[-3].sym)->subclass=NC_ENUM; - (yyvsp[-3].sym)->typ.basetype=(yyvsp[-5].sym); - (yyvsp[-3].sym)->typ.size = (yyvsp[-5].sym)->typ.size; - (yyvsp[-3].sym)->typ.alignment = (yyvsp[-5].sym)->typ.alignment; - stackbase=(yyvsp[-1].mark); + addtogroup((yyvsp[(3) - (6)].sym)); /* sets prefix*/ + (yyvsp[(3) - (6)].sym)->objectclass=NC_TYPE; + (yyvsp[(3) - (6)].sym)->subclass=NC_ENUM; + (yyvsp[(3) - (6)].sym)->typ.basetype=(yyvsp[(1) - (6)].sym); + (yyvsp[(3) - (6)].sym)->typ.size = (yyvsp[(1) - (6)].sym)->typ.size; + (yyvsp[(3) - (6)].sym)->typ.alignment = (yyvsp[(1) - (6)].sym)->typ.alignment; + stackbase=(yyvsp[(5) - (6)].mark); stacklen=listlength(stack); - (yyvsp[-3].sym)->subnodes = listnew(); + (yyvsp[(3) - (6)].sym)->subnodes = listnew(); /* Variety of field fixups*/ /* 1. add in the enum values*/ /* 2. make this type be their container*/ @@ -1704,89 +1907,83 @@ yyparse (void) Symbol* eid = (Symbol*)listget(stack,i); assert(eid->subclass == NC_ECONST); addtogroup(eid); - listpush((yyvsp[-3].sym)->subnodes,(void*)eid); - eid->container = (yyvsp[-3].sym); - eid->typ.basetype = (yyvsp[-3].sym)->typ.basetype; + listpush((yyvsp[(3) - (6)].sym)->subnodes,(void*)eid); + eid->container = (yyvsp[(3) - (6)].sym); + eid->typ.basetype = (yyvsp[(3) - (6)].sym)->typ.basetype; } listsetlength(stack,stackbase);/* remove stack nodes*/ - } -#line 1714 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 26: -#line 318 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[0].sym));} -#line 1720 "ncgeny.c" /* yacc.c:1646 */ +#line 318 "ncgen.y" + {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[(1) - (1)].sym));;} break; case 27: -#line 320 "ncgen.y" /* yacc.c:1646 */ +#line 320 "ncgen.y" { int i; - (yyval.mark)=(yyvsp[-2].mark); + (yyval.mark)=(yyvsp[(1) - (3)].mark); /* check for duplicates*/ - stackbase=(yyvsp[-2].mark); + stackbase=(yyvsp[(1) - (3)].mark); stacklen=listlength(stack); for(i=stackbase;iname,elem->name)==0) + if(strcmp((yyvsp[(3) - (3)].sym)->name,elem->name)==0) yyerror("duplicate enum declaration for %s", elem->name); } - listpush(stack,(void*)(yyvsp[0].sym)); - } -#line 1739 "ncgeny.c" /* yacc.c:1646 */ + listpush(stack,(void*)(yyvsp[(3) - (3)].sym)); + ;} break; case 28: -#line 337 "ncgen.y" /* yacc.c:1646 */ +#line 337 "ncgen.y" { - (yyvsp[-2].sym)->objectclass=NC_TYPE; - (yyvsp[-2].sym)->subclass=NC_ECONST; - (yyvsp[-2].sym)->typ.econst=(yyvsp[0].constant); - (yyval.sym)=(yyvsp[-2].sym); - } -#line 1750 "ncgeny.c" /* yacc.c:1646 */ + (yyvsp[(1) - (3)].sym)->objectclass=NC_TYPE; + (yyvsp[(1) - (3)].sym)->subclass=NC_ECONST; + (yyvsp[(1) - (3)].sym)->typ.econst=(yyvsp[(3) - (3)].constant); + (yyval.sym)=(yyvsp[(1) - (3)].sym); + ;} break; case 29: -#line 346 "ncgen.y" /* yacc.c:1646 */ +#line 346 "ncgen.y" { vercheck(NC_OPAQUE); - addtogroup((yyvsp[0].sym)); /*sets prefix*/ - (yyvsp[0].sym)->objectclass=NC_TYPE; - (yyvsp[0].sym)->subclass=NC_OPAQUE; - (yyvsp[0].sym)->typ.typecode=NC_OPAQUE; - (yyvsp[0].sym)->typ.size=int32_val; - (yyvsp[0].sym)->typ.alignment=nctypealignment(NC_OPAQUE); - } -#line 1764 "ncgeny.c" /* yacc.c:1646 */ + addtogroup((yyvsp[(5) - (5)].sym)); /*sets prefix*/ + (yyvsp[(5) - (5)].sym)->objectclass=NC_TYPE; + (yyvsp[(5) - (5)].sym)->subclass=NC_OPAQUE; + (yyvsp[(5) - (5)].sym)->typ.typecode=NC_OPAQUE; + (yyvsp[(5) - (5)].sym)->typ.size=int32_val; + (yyvsp[(5) - (5)].sym)->typ.alignment=nctypealignment(NC_OPAQUE); + ;} break; case 30: -#line 358 "ncgen.y" /* yacc.c:1646 */ +#line 358 "ncgen.y" { - Symbol* basetype = (yyvsp[-4].sym); + Symbol* basetype = (yyvsp[(1) - (5)].sym); vercheck(NC_VLEN); - addtogroup((yyvsp[0].sym)); /*sets prefix*/ - (yyvsp[0].sym)->objectclass=NC_TYPE; - (yyvsp[0].sym)->subclass=NC_VLEN; - (yyvsp[0].sym)->typ.basetype=basetype; - (yyvsp[0].sym)->typ.typecode=NC_VLEN; - (yyvsp[0].sym)->typ.size=VLENSIZE; - (yyvsp[0].sym)->typ.alignment=nctypealignment(NC_VLEN); - } -#line 1780 "ncgeny.c" /* yacc.c:1646 */ + addtogroup((yyvsp[(5) - (5)].sym)); /*sets prefix*/ + (yyvsp[(5) - (5)].sym)->objectclass=NC_TYPE; + (yyvsp[(5) - (5)].sym)->subclass=NC_VLEN; + (yyvsp[(5) - (5)].sym)->typ.basetype=basetype; + (yyvsp[(5) - (5)].sym)->typ.typecode=NC_VLEN; + (yyvsp[(5) - (5)].sym)->typ.size=VLENSIZE; + (yyvsp[(5) - (5)].sym)->typ.alignment=nctypealignment(NC_VLEN); + ;} break; case 31: -#line 372 "ncgen.y" /* yacc.c:1646 */ +#line 372 "ncgen.y" { int i,j; vercheck(NC_COMPOUND); - addtogroup((yyvsp[-3].sym)); + addtogroup((yyvsp[(2) - (5)].sym)); /* check for duplicate field names*/ - stackbase=(yyvsp[-1].mark); + stackbase=(yyvsp[(4) - (5)].mark); stacklen=listlength(stack); for(i=stackbase;iobjectclass=NC_TYPE; - (yyvsp[-3].sym)->subclass=NC_COMPOUND; - (yyvsp[-3].sym)->typ.basetype=NULL; - (yyvsp[-3].sym)->typ.typecode=NC_COMPOUND; - (yyvsp[-3].sym)->subnodes = listnew(); + (yyvsp[(2) - (5)].sym)->objectclass=NC_TYPE; + (yyvsp[(2) - (5)].sym)->subclass=NC_COMPOUND; + (yyvsp[(2) - (5)].sym)->typ.basetype=NULL; + (yyvsp[(2) - (5)].sym)->typ.typecode=NC_COMPOUND; + (yyvsp[(2) - (5)].sym)->subnodes = listnew(); /* Add in the fields*/ for(i=stackbase;icontainer = (yyvsp[-3].sym); - listpush((yyvsp[-3].sym)->subnodes,(void*)fsym); + fsym->container = (yyvsp[(2) - (5)].sym); + listpush((yyvsp[(2) - (5)].sym)->subnodes,(void*)fsym); } listsetlength(stack,stackbase);/* remove stack nodes*/ - } -#line 1814 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 32: -#line 404 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=(yyvsp[-1].mark);} -#line 1820 "ncgeny.c" /* yacc.c:1646 */ +#line 404 "ncgen.y" + {(yyval.mark)=(yyvsp[(1) - (2)].mark);;} break; case 33: -#line 405 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=(yyvsp[-2].mark);} -#line 1826 "ncgeny.c" /* yacc.c:1646 */ +#line 405 "ncgen.y" + {(yyval.mark)=(yyvsp[(1) - (3)].mark);;} break; case 34: -#line 409 "ncgen.y" /* yacc.c:1646 */ +#line 409 "ncgen.y" { int i; - (yyval.mark)=(yyvsp[0].mark); - stackbase=(yyvsp[0].mark); + (yyval.mark)=(yyvsp[(2) - (2)].mark); + stackbase=(yyvsp[(2) - (2)].mark); stacklen=listlength(stack); /* process each field in the fieldlist*/ for(i=stackbase;ityp.basetype = (yyvsp[-1].sym); + f->typ.basetype = (yyvsp[(1) - (2)].sym); } - } -#line 1842 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 35: -#line 422 "ncgen.y" /* yacc.c:1646 */ - { (yyval.sym) = primsymbols[NC_CHAR]; } -#line 1848 "ncgeny.c" /* yacc.c:1646 */ +#line 422 "ncgen.y" + { (yyval.sym) = primsymbols[NC_CHAR]; ;} break; case 36: -#line 423 "ncgen.y" /* yacc.c:1646 */ - { (yyval.sym) = primsymbols[NC_BYTE]; } -#line 1854 "ncgeny.c" /* yacc.c:1646 */ +#line 423 "ncgen.y" + { (yyval.sym) = primsymbols[NC_BYTE]; ;} break; case 37: -#line 424 "ncgen.y" /* yacc.c:1646 */ - { (yyval.sym) = primsymbols[NC_SHORT]; } -#line 1860 "ncgeny.c" /* yacc.c:1646 */ +#line 424 "ncgen.y" + { (yyval.sym) = primsymbols[NC_SHORT]; ;} break; case 38: -#line 425 "ncgen.y" /* yacc.c:1646 */ - { (yyval.sym) = primsymbols[NC_INT]; } -#line 1866 "ncgeny.c" /* yacc.c:1646 */ +#line 425 "ncgen.y" + { (yyval.sym) = primsymbols[NC_INT]; ;} break; case 39: -#line 426 "ncgen.y" /* yacc.c:1646 */ - { (yyval.sym) = primsymbols[NC_FLOAT]; } -#line 1872 "ncgeny.c" /* yacc.c:1646 */ +#line 426 "ncgen.y" + { (yyval.sym) = primsymbols[NC_FLOAT]; ;} break; case 40: -#line 427 "ncgen.y" /* yacc.c:1646 */ - { (yyval.sym) = primsymbols[NC_DOUBLE]; } -#line 1878 "ncgeny.c" /* yacc.c:1646 */ +#line 427 "ncgen.y" + { (yyval.sym) = primsymbols[NC_DOUBLE]; ;} break; case 41: -#line 428 "ncgen.y" /* yacc.c:1646 */ - { vercheck(NC_UBYTE); (yyval.sym) = primsymbols[NC_UBYTE]; } -#line 1884 "ncgeny.c" /* yacc.c:1646 */ +#line 428 "ncgen.y" + { vercheck(NC_UBYTE); (yyval.sym) = primsymbols[NC_UBYTE]; ;} break; case 42: -#line 429 "ncgen.y" /* yacc.c:1646 */ - { vercheck(NC_USHORT); (yyval.sym) = primsymbols[NC_USHORT]; } -#line 1890 "ncgeny.c" /* yacc.c:1646 */ +#line 429 "ncgen.y" + { vercheck(NC_USHORT); (yyval.sym) = primsymbols[NC_USHORT]; ;} break; case 43: -#line 430 "ncgen.y" /* yacc.c:1646 */ - { vercheck(NC_UINT); (yyval.sym) = primsymbols[NC_UINT]; } -#line 1896 "ncgeny.c" /* yacc.c:1646 */ +#line 430 "ncgen.y" + { vercheck(NC_UINT); (yyval.sym) = primsymbols[NC_UINT]; ;} break; case 44: -#line 431 "ncgen.y" /* yacc.c:1646 */ - { vercheck(NC_INT64); (yyval.sym) = primsymbols[NC_INT64]; } -#line 1902 "ncgeny.c" /* yacc.c:1646 */ +#line 431 "ncgen.y" + { vercheck(NC_INT64); (yyval.sym) = primsymbols[NC_INT64]; ;} break; case 45: -#line 432 "ncgen.y" /* yacc.c:1646 */ - { vercheck(NC_UINT64); (yyval.sym) = primsymbols[NC_UINT64]; } -#line 1908 "ncgeny.c" /* yacc.c:1646 */ +#line 432 "ncgen.y" + { vercheck(NC_UINT64); (yyval.sym) = primsymbols[NC_UINT64]; ;} break; case 47: -#line 436 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1914 "ncgeny.c" /* yacc.c:1646 */ +#line 436 "ncgen.y" + {;} break; case 48: -#line 437 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1920 "ncgeny.c" /* yacc.c:1646 */ +#line 437 "ncgen.y" + {;} break; case 51: -#line 444 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1926 "ncgeny.c" /* yacc.c:1646 */ +#line 444 "ncgen.y" + {;} break; case 52: -#line 444 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1932 "ncgeny.c" /* yacc.c:1646 */ +#line 444 "ncgen.y" + {;} break; case 55: -#line 452 "ncgen.y" /* yacc.c:1646 */ +#line 452 "ncgen.y" { - (yyvsp[-2].sym)->dim.declsize = (size_t)extractint((yyvsp[0].constant)); + (yyvsp[(1) - (3)].sym)->dim.declsize = (size_t)extractint((yyvsp[(3) - (3)].constant)); #ifdef GENDEBUG1 -fprintf(stderr,"dimension: %s = %llu\n",(yyvsp[-2].sym)->name,(unsigned long long)(yyvsp[-2].sym)->dim.declsize); +fprintf(stderr,"dimension: %s = %llu\n",(yyvsp[(1) - (3)].sym)->name,(unsigned long long)(yyvsp[(1) - (3)].sym)->dim.declsize); #endif - } -#line 1943 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 56: -#line 459 "ncgen.y" /* yacc.c:1646 */ +#line 459 "ncgen.y" { - (yyvsp[-2].sym)->dim.declsize = NC_UNLIMITED; - (yyvsp[-2].sym)->dim.isunlimited = 1; + (yyvsp[(1) - (3)].sym)->dim.declsize = NC_UNLIMITED; + (yyvsp[(1) - (3)].sym)->dim.isunlimited = 1; #ifdef GENDEBUG1 -fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); +fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name); #endif - } -#line 1955 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 57: -#line 469 "ncgen.y" /* yacc.c:1646 */ +#line 469 "ncgen.y" { - (yyvsp[0].sym)->objectclass=NC_DIM; - if(dupobjectcheck(NC_DIM,(yyvsp[0].sym))) + (yyvsp[(1) - (1)].sym)->objectclass=NC_DIM; + if(dupobjectcheck(NC_DIM,(yyvsp[(1) - (1)].sym))) yyerror( "Duplicate dimension declaration for %s", - (yyvsp[0].sym)->name); - addtogroup((yyvsp[0].sym)); - (yyval.sym)=(yyvsp[0].sym); - listpush(dimdefs,(void*)(yyvsp[0].sym)); - } -#line 1969 "ncgeny.c" /* yacc.c:1646 */ + (yyvsp[(1) - (1)].sym)->name); + addtogroup((yyvsp[(1) - (1)].sym)); + (yyval.sym)=(yyvsp[(1) - (1)].sym); + listpush(dimdefs,(void*)(yyvsp[(1) - (1)].sym)); + ;} break; case 59: -#line 481 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1975 "ncgeny.c" /* yacc.c:1646 */ +#line 481 "ncgen.y" + {;} break; case 60: -#line 482 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1981 "ncgeny.c" /* yacc.c:1646 */ +#line 482 "ncgen.y" + {;} break; case 63: -#line 489 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1987 "ncgeny.c" /* yacc.c:1646 */ +#line 489 "ncgen.y" + {;} break; case 64: -#line 489 "ncgen.y" /* yacc.c:1646 */ - {} -#line 1993 "ncgeny.c" /* yacc.c:1646 */ +#line 489 "ncgen.y" + {;} break; case 65: -#line 492 "ncgen.y" /* yacc.c:1646 */ +#line 492 "ncgen.y" { int i; - stackbase=(yyvsp[0].mark); + stackbase=(yyvsp[(2) - (2)].mark); stacklen=listlength(stack); /* process each variable in the varlist*/ for(i=stackbase;iname); yyerror("Duplicate variable declaration for %s", sym->name); } else { - sym->typ.basetype = (yyvsp[-1].sym); + sym->typ.basetype = (yyvsp[(1) - (2)].sym); addtogroup(sym); listpush(vardefs,(void*)sym); } } listsetlength(stack,stackbase);/* remove stack nodes*/ - } -#line 2017 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 66: -#line 514 "ncgen.y" /* yacc.c:1646 */ +#line 514 "ncgen.y" {(yyval.mark)=listlength(stack); - listpush(stack,(void*)(yyvsp[0].sym)); - } -#line 2025 "ncgeny.c" /* yacc.c:1646 */ + listpush(stack,(void*)(yyvsp[(1) - (1)].sym)); + ;} break; case 67: -#line 518 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=(yyvsp[-2].mark); listpush(stack,(void*)(yyvsp[0].sym));} -#line 2031 "ncgeny.c" /* yacc.c:1646 */ +#line 518 "ncgen.y" + {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));;} break; case 68: -#line 522 "ncgen.y" /* yacc.c:1646 */ +#line 522 "ncgen.y" { int i; Dimset dimset; stacklen=listlength(stack); - stackbase=(yyvsp[0].mark); + stackbase=(yyvsp[(2) - (2)].mark); count = stacklen - stackbase; if(count >= NC_MAX_VAR_DIMS) { - yyerror("%s has too many dimensions",(yyvsp[-1].sym)->name); + yyerror("%s has too many dimensions",(yyvsp[(1) - (2)].sym)->name); count = NC_MAX_VAR_DIMS - 1; stacklen = stackbase + count; } @@ -2050,78 +2218,70 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); Symbol* dsym = (Symbol*)listget(stack,stackbase+i); dimset.dimsyms[i] = dsym; } - (yyvsp[-1].sym)->typ.dimset = dimset; + (yyvsp[(1) - (2)].sym)->typ.dimset = dimset; } - (yyvsp[-1].sym)->typ.basetype = NULL; /* not yet known*/ - (yyvsp[-1].sym)->objectclass=NC_VAR; + (yyvsp[(1) - (2)].sym)->typ.basetype = NULL; /* not yet known*/ + (yyvsp[(1) - (2)].sym)->objectclass=NC_VAR; listsetlength(stack,stackbase);/* remove stack nodes*/ - } -#line 2060 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 69: -#line 548 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=listlength(stack);} -#line 2066 "ncgeny.c" /* yacc.c:1646 */ +#line 548 "ncgen.y" + {(yyval.mark)=listlength(stack);;} break; case 70: -#line 549 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=(yyvsp[-1].mark);} -#line 2072 "ncgeny.c" /* yacc.c:1646 */ +#line 549 "ncgen.y" + {(yyval.mark)=(yyvsp[(2) - (3)].mark);;} break; case 71: -#line 552 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[0].sym));} -#line 2078 "ncgeny.c" /* yacc.c:1646 */ +#line 552 "ncgen.y" + {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[(1) - (1)].sym));;} break; case 72: -#line 554 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=(yyvsp[-2].mark); listpush(stack,(void*)(yyvsp[0].sym));} -#line 2084 "ncgeny.c" /* yacc.c:1646 */ +#line 554 "ncgen.y" + {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));;} break; case 73: -#line 558 "ncgen.y" /* yacc.c:1646 */ - {Symbol* dimsym = (yyvsp[0].sym); +#line 558 "ncgen.y" + {Symbol* dimsym = (yyvsp[(1) - (1)].sym); dimsym->objectclass = NC_DIM; /* Find the actual dimension*/ dimsym = locate(dimsym); if(dimsym == NULL) { - derror("Undefined or forward referenced dimension: %s",(yyvsp[0].sym)->name); + derror("Undefined or forward referenced dimension: %s",(yyvsp[(1) - (1)].sym)->name); YYABORT; } (yyval.sym)=dimsym; - } -#line 2099 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 74: -#line 572 "ncgen.y" /* yacc.c:1646 */ +#line 572 "ncgen.y" {(yyval.mark)=listlength(stack); - listpush(stack,(void*)(yyvsp[0].sym)); - } -#line 2107 "ncgeny.c" /* yacc.c:1646 */ + listpush(stack,(void*)(yyvsp[(1) - (1)].sym)); + ;} break; case 75: -#line 576 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=(yyvsp[-2].mark); listpush(stack,(void*)(yyvsp[0].sym));} -#line 2113 "ncgeny.c" /* yacc.c:1646 */ +#line 576 "ncgen.y" + {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));;} break; case 76: -#line 581 "ncgen.y" /* yacc.c:1646 */ +#line 581 "ncgen.y" { int i; Dimset dimset; - stackbase=(yyvsp[0].mark); + stackbase=(yyvsp[(2) - (2)].mark); stacklen=listlength(stack); count = stacklen - stackbase; if(count >= NC_MAX_VAR_DIMS) { - yyerror("%s has too many dimensions",(yyvsp[-1].sym)->name); + yyerror("%s has too many dimensions",(yyvsp[(1) - (2)].sym)->name); count = NC_MAX_VAR_DIMS - 1; stacklen = stackbase + count; } @@ -2132,43 +2292,38 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); Symbol* dsym = (Symbol*)listget(stack,stackbase+i); dimset.dimsyms[i] = dsym; } - (yyvsp[-1].sym)->typ.dimset = dimset; + (yyvsp[(1) - (2)].sym)->typ.dimset = dimset; } - (yyvsp[-1].sym)->typ.basetype = NULL; /* not yet known*/ - (yyvsp[-1].sym)->objectclass=NC_TYPE; - (yyvsp[-1].sym)->subclass=NC_FIELD; + (yyvsp[(1) - (2)].sym)->typ.basetype = NULL; /* not yet known*/ + (yyvsp[(1) - (2)].sym)->objectclass=NC_TYPE; + (yyvsp[(1) - (2)].sym)->subclass=NC_FIELD; listsetlength(stack,stackbase);/* remove stack nodes*/ - (yyval.sym) = (yyvsp[-1].sym); - } -#line 2144 "ncgeny.c" /* yacc.c:1646 */ + (yyval.sym) = (yyvsp[(1) - (2)].sym); + ;} break; case 77: -#line 609 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=listlength(stack);} -#line 2150 "ncgeny.c" /* yacc.c:1646 */ +#line 609 "ncgen.y" + {(yyval.mark)=listlength(stack);;} break; case 78: -#line 610 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=(yyvsp[-1].mark);} -#line 2156 "ncgeny.c" /* yacc.c:1646 */ +#line 610 "ncgen.y" + {(yyval.mark)=(yyvsp[(2) - (3)].mark);;} break; case 79: -#line 614 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[0].sym));} -#line 2162 "ncgeny.c" /* yacc.c:1646 */ +#line 614 "ncgen.y" + {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[(1) - (1)].sym));;} break; case 80: -#line 616 "ncgen.y" /* yacc.c:1646 */ - {(yyval.mark)=(yyvsp[-2].mark); listpush(stack,(void*)(yyvsp[0].sym));} -#line 2168 "ncgeny.c" /* yacc.c:1646 */ +#line 616 "ncgen.y" + {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));;} break; case 81: -#line 621 "ncgen.y" /* yacc.c:1646 */ +#line 621 "ncgen.y" { /* Anonymous integer dimension. Can only occur in type definitions*/ char anon[32]; @@ -2177,12 +2332,11 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); (yyval.sym)->objectclass = NC_DIM; (yyval.sym)->dim.isconstant = 1; (yyval.sym)->dim.declsize = uint32_val; - } -#line 2182 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 82: -#line 631 "ncgen.y" /* yacc.c:1646 */ +#line 631 "ncgen.y" { /* Anonymous integer dimension. Can only occur in type definitions*/ char anon[32]; @@ -2195,37 +2349,34 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); (yyval.sym)->objectclass = NC_DIM; (yyval.sym)->dim.isconstant = 1; (yyval.sym)->dim.declsize = int32_val; - } -#line 2200 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 83: -#line 651 "ncgen.y" /* yacc.c:1646 */ - {Symbol* vsym = (yyvsp[0].sym); +#line 651 "ncgen.y" + {Symbol* vsym = (yyvsp[(1) - (1)].sym); if(vsym->objectclass != NC_VAR) { derror("Undefined or forward referenced variable: %s",vsym->name); YYABORT; } (yyval.sym)=vsym; - } -#line 2212 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 84: -#line 662 "ncgen.y" /* yacc.c:1646 */ - {Symbol* tsym = (yyvsp[0].sym); +#line 662 "ncgen.y" + {Symbol* tsym = (yyvsp[(1) - (1)].sym); if(tsym->objectclass != NC_TYPE) { derror("Undefined or forward referenced type: %s",tsym->name); YYABORT; } (yyval.sym)=tsym; - } -#line 2224 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 85: -#line 673 "ncgen.y" /* yacc.c:1646 */ - {Symbol* tvsym = (yyvsp[0].sym); Symbol* sym; +#line 673 "ncgen.y" + {Symbol* tvsym = (yyvsp[(1) - (1)].sym); Symbol* sym; /* disambiguate*/ tvsym->objectclass = NC_VAR; sym = locate(tvsym); @@ -2233,432 +2384,359 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); tvsym->objectclass = NC_TYPE; sym = locate(tvsym); if(tvsym == NULL) { - derror("Undefined or forward referenced name: %s",(yyvsp[0].sym)->name); + derror("Undefined or forward referenced name: %s",(yyvsp[(1) - (1)].sym)->name); YYABORT; } else tvsym = sym; } else tvsym = sym; if(tvsym == NULL) { - derror("Undefined name (line %d): %s",(yyvsp[0].sym)->lineno,(yyvsp[0].sym)->name); + derror("Undefined name (line %d): %s",(yyvsp[(1) - (1)].sym)->lineno,(yyvsp[(1) - (1)].sym)->name); YYABORT; } (yyval.sym)=tvsym; - } -#line 2247 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 86: -#line 691 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym)=(yyvsp[0].sym);} -#line 2253 "ncgeny.c" /* yacc.c:1646 */ +#line 691 "ncgen.y" + {(yyval.sym)=(yyvsp[(1) - (1)].sym);;} break; case 87: -#line 698 "ncgen.y" /* yacc.c:1646 */ - {} -#line 2259 "ncgeny.c" /* yacc.c:1646 */ +#line 698 "ncgen.y" + {;} break; case 88: -#line 698 "ncgen.y" /* yacc.c:1646 */ - {} -#line 2265 "ncgeny.c" /* yacc.c:1646 */ +#line 698 "ncgen.y" + {;} break; case 89: -#line 702 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_NCPROPS_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),ATTRGLOBAL);} -#line 2271 "ncgeny.c" /* yacc.c:1646 */ +#line 702 "ncgen.y" + {(yyval.sym) = makespecial(_NCPROPS_FLAG,NULL,NULL,(void*)&(yyvsp[(4) - (4)].constant),ATTRGLOBAL);;} break; case 90: -#line 704 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_ISNETCDF4_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),ATTRGLOBAL);} -#line 2277 "ncgeny.c" /* yacc.c:1646 */ +#line 704 "ncgen.y" + {(yyval.sym) = makespecial(_ISNETCDF4_FLAG,NULL,NULL,(void*)&(yyvsp[(4) - (4)].constant),ATTRGLOBAL);;} break; case 91: -#line 706 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_SUPERBLOCK_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),ATTRGLOBAL);} -#line 2283 "ncgeny.c" /* yacc.c:1646 */ +#line 706 "ncgen.y" + {(yyval.sym) = makespecial(_SUPERBLOCK_FLAG,NULL,NULL,(void*)&(yyvsp[(4) - (4)].constant),ATTRGLOBAL);;} break; case 92: -#line 708 "ncgen.y" /* yacc.c:1646 */ - { (yyval.sym)=makeattribute((yyvsp[-2].sym),NULL,NULL,(yyvsp[0].datalist),ATTRGLOBAL);} -#line 2289 "ncgeny.c" /* yacc.c:1646 */ +#line 708 "ncgen.y" + { (yyval.sym)=makeattribute((yyvsp[(2) - (4)].sym),NULL,NULL,(yyvsp[(4) - (4)].datalist),ATTRGLOBAL);;} break; case 93: -#line 710 "ncgen.y" /* yacc.c:1646 */ - {Symbol* tsym = (yyvsp[-5].sym); Symbol* vsym = (yyvsp[-4].sym); Symbol* asym = (yyvsp[-2].sym); +#line 710 "ncgen.y" + {Symbol* tsym = (yyvsp[(1) - (6)].sym); Symbol* vsym = (yyvsp[(2) - (6)].sym); Symbol* asym = (yyvsp[(4) - (6)].sym); if(vsym->objectclass == NC_VAR) { - (yyval.sym)=makeattribute(asym,vsym,tsym,(yyvsp[0].datalist),ATTRVAR); + (yyval.sym)=makeattribute(asym,vsym,tsym,(yyvsp[(6) - (6)].datalist),ATTRVAR); } else { derror("Doubly typed attribute: %s",asym->name); YYABORT; } - } -#line 2302 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 94: -#line 719 "ncgen.y" /* yacc.c:1646 */ - {Symbol* sym = (yyvsp[-4].sym); Symbol* asym = (yyvsp[-2].sym); +#line 719 "ncgen.y" + {Symbol* sym = (yyvsp[(1) - (5)].sym); Symbol* asym = (yyvsp[(3) - (5)].sym); if(sym->objectclass == NC_VAR) { - (yyval.sym)=makeattribute(asym,sym,NULL,(yyvsp[0].datalist),ATTRVAR); + (yyval.sym)=makeattribute(asym,sym,NULL,(yyvsp[(5) - (5)].datalist),ATTRVAR); } else if(sym->objectclass == NC_TYPE) { - (yyval.sym)=makeattribute(asym,NULL,sym,(yyvsp[0].datalist),ATTRGLOBAL); + (yyval.sym)=makeattribute(asym,NULL,sym,(yyvsp[(5) - (5)].datalist),ATTRGLOBAL); } else { derror("Attribute prefix not a variable or type: %s",asym->name); YYABORT; } - } -#line 2317 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 95: -#line 730 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[-4].sym),NULL,(void*)(yyvsp[0].datalist),0);} -#line 2323 "ncgeny.c" /* yacc.c:1646 */ +#line 730 "ncgen.y" + {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)(yyvsp[(5) - (5)].datalist),0);;} break; case 96: -#line 732 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[-4].sym),(yyvsp[-5].sym),(void*)(yyvsp[0].datalist),0);} -#line 2329 "ncgeny.c" /* yacc.c:1646 */ +#line 732 "ncgen.y" + {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[(2) - (6)].sym),(yyvsp[(1) - (6)].sym),(void*)(yyvsp[(6) - (6)].datalist),0);;} break; case 97: -#line 734 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_STORAGE_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);} -#line 2335 "ncgeny.c" /* yacc.c:1646 */ +#line 734 "ncgen.y" + {(yyval.sym) = makespecial(_STORAGE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;} break; case 98: -#line 736 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_CHUNKSIZES_FLAG,(yyvsp[-4].sym),NULL,(void*)(yyvsp[0].datalist),0);} -#line 2341 "ncgeny.c" /* yacc.c:1646 */ +#line 736 "ncgen.y" + {(yyval.sym) = makespecial(_CHUNKSIZES_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)(yyvsp[(5) - (5)].datalist),0);;} break; case 99: -#line 738 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_FLETCHER32_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);} -#line 2347 "ncgeny.c" /* yacc.c:1646 */ +#line 738 "ncgen.y" + {(yyval.sym) = makespecial(_FLETCHER32_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;} break; case 100: -#line 740 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_DEFLATE_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);} -#line 2353 "ncgeny.c" /* yacc.c:1646 */ +#line 740 "ncgen.y" + {(yyval.sym) = makespecial(_DEFLATE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;} break; case 101: -#line 742 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_SHUFFLE_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);} -#line 2359 "ncgeny.c" /* yacc.c:1646 */ +#line 742 "ncgen.y" + {(yyval.sym) = makespecial(_SHUFFLE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;} break; case 102: -#line 744 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_ENDIAN_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);} -#line 2365 "ncgeny.c" /* yacc.c:1646 */ +#line 744 "ncgen.y" + {(yyval.sym) = makespecial(_ENDIAN_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;} break; case 103: -#line 746 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_NOFILL_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);} -#line 2371 "ncgeny.c" /* yacc.c:1646 */ +#line 746 "ncgen.y" + {(yyval.sym) = makespecial(_NOFILL_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;} break; case 104: -#line 748 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym) = makespecial(_FORMAT_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),1);} -#line 2377 "ncgeny.c" /* yacc.c:1646 */ +#line 748 "ncgen.y" + {(yyval.sym) = makespecial(_FORMAT_FLAG,NULL,NULL,(void*)&(yyvsp[(4) - (4)].constant),1);;} break; case 105: -#line 753 "ncgen.y" /* yacc.c:1646 */ +#line 753 "ncgen.y" { - (yyval.sym)=(yyvsp[0].sym); - (yyvsp[0].sym)->ref.is_ref=1; - (yyvsp[0].sym)->is_prefixed=0; - setpathcurrent((yyvsp[0].sym)); - } -#line 2388 "ncgeny.c" /* yacc.c:1646 */ + (yyval.sym)=(yyvsp[(1) - (1)].sym); + (yyvsp[(1) - (1)].sym)->ref.is_ref=1; + (yyvsp[(1) - (1)].sym)->is_prefixed=0; + setpathcurrent((yyvsp[(1) - (1)].sym)); + ;} break; case 106: -#line 760 "ncgen.y" /* yacc.c:1646 */ +#line 760 "ncgen.y" { - (yyval.sym)=(yyvsp[0].sym); - (yyvsp[0].sym)->ref.is_ref=1; - (yyvsp[0].sym)->is_prefixed=1; + (yyval.sym)=(yyvsp[(1) - (1)].sym); + (yyvsp[(1) - (1)].sym)->ref.is_ref=1; + (yyvsp[(1) - (1)].sym)->is_prefixed=1; /* path is set in ncgen.l*/ - } -#line 2399 "ncgeny.c" /* yacc.c:1646 */ + ;} break; case 108: -#line 769 "ncgen.y" /* yacc.c:1646 */ - {} -#line 2405 "ncgeny.c" /* yacc.c:1646 */ +#line 769 "ncgen.y" + {;} break; case 109: -#line 770 "ncgen.y" /* yacc.c:1646 */ - {} -#line 2411 "ncgeny.c" /* yacc.c:1646 */ +#line 770 "ncgen.y" + {;} break; case 112: -#line 778 "ncgen.y" /* yacc.c:1646 */ - {(yyvsp[-2].sym)->data = (yyvsp[0].datalist);} -#line 2417 "ncgeny.c" /* yacc.c:1646 */ +#line 778 "ncgen.y" + {(yyvsp[(1) - (3)].sym)->data = (yyvsp[(3) - (3)].datalist);;} break; case 113: -#line 781 "ncgen.y" /* yacc.c:1646 */ - {(yyval.datalist) = (yyvsp[0].datalist);} -#line 2423 "ncgeny.c" /* yacc.c:1646 */ +#line 781 "ncgen.y" + {(yyval.datalist) = (yyvsp[(1) - (1)].datalist);;} break; case 114: -#line 782 "ncgen.y" /* yacc.c:1646 */ - {(yyval.datalist) = (yyvsp[0].datalist);} -#line 2429 "ncgeny.c" /* yacc.c:1646 */ +#line 782 "ncgen.y" + {(yyval.datalist) = (yyvsp[(1) - (1)].datalist);;} break; case 115: -#line 786 "ncgen.y" /* yacc.c:1646 */ - {(yyval.datalist) = builddatalist(0);} -#line 2435 "ncgeny.c" /* yacc.c:1646 */ +#line 786 "ncgen.y" + {(yyval.datalist) = builddatalist(0);;} break; case 116: -#line 790 "ncgen.y" /* yacc.c:1646 */ - {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[0].constant)));} -#line 2441 "ncgeny.c" /* yacc.c:1646 */ +#line 790 "ncgen.y" + {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[(1) - (1)].constant)));;} break; case 117: -#line 792 "ncgen.y" /* yacc.c:1646 */ - {datalistextend((yyvsp[-2].datalist),&((yyvsp[0].constant))); (yyval.datalist)=(yyvsp[-2].datalist);} -#line 2447 "ncgeny.c" /* yacc.c:1646 */ +#line 792 "ncgen.y" + {datalistextend((yyvsp[(1) - (3)].datalist),&((yyvsp[(3) - (3)].constant))); (yyval.datalist)=(yyvsp[(1) - (3)].datalist);;} break; case 118: -#line 796 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=(yyvsp[0].constant);} -#line 2453 "ncgeny.c" /* yacc.c:1646 */ +#line 796 "ncgen.y" + {(yyval.constant)=(yyvsp[(1) - (1)].constant);;} break; case 119: -#line 797 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=builddatasublist((yyvsp[-1].datalist));} -#line 2459 "ncgeny.c" /* yacc.c:1646 */ +#line 797 "ncgen.y" + {(yyval.constant)=builddatasublist((yyvsp[(2) - (3)].datalist));;} break; case 120: -#line 801 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=(yyvsp[0].constant);} -#line 2465 "ncgeny.c" /* yacc.c:1646 */ +#line 801 "ncgen.y" + {(yyval.constant)=(yyvsp[(1) - (1)].constant);;} break; case 121: -#line 802 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_OPAQUE);} -#line 2471 "ncgeny.c" /* yacc.c:1646 */ +#line 802 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_OPAQUE);;} break; case 122: -#line 803 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_FILLVALUE);} -#line 2477 "ncgeny.c" /* yacc.c:1646 */ +#line 803 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_FILLVALUE);;} break; case 123: -#line 804 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_NIL);} -#line 2483 "ncgeny.c" /* yacc.c:1646 */ +#line 804 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_NIL);;} break; case 124: -#line 805 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=(yyvsp[0].constant);} -#line 2489 "ncgeny.c" /* yacc.c:1646 */ +#line 805 "ncgen.y" + {(yyval.constant)=(yyvsp[(1) - (1)].constant);;} break; case 126: -#line 810 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant) = makeenumconstref((yyvsp[0].sym));} -#line 2495 "ncgeny.c" /* yacc.c:1646 */ +#line 810 "ncgen.y" + {(yyval.constant) = makeenumconstref((yyvsp[(1) - (1)].sym));;} break; case 127: -#line 814 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=evaluate((yyvsp[-3].sym),(yyvsp[-1].datalist));} -#line 2501 "ncgeny.c" /* yacc.c:1646 */ +#line 814 "ncgen.y" + {(yyval.constant)=evaluate((yyvsp[(1) - (4)].sym),(yyvsp[(3) - (4)].datalist));;} break; case 128: -#line 819 "ncgen.y" /* yacc.c:1646 */ - {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[0].constant)));} -#line 2507 "ncgeny.c" /* yacc.c:1646 */ +#line 819 "ncgen.y" + {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[(1) - (1)].constant)));;} break; case 129: -#line 821 "ncgen.y" /* yacc.c:1646 */ - {datalistextend((yyvsp[-2].datalist),&((yyvsp[0].constant))); (yyval.datalist)=(yyvsp[-2].datalist);} -#line 2513 "ncgeny.c" /* yacc.c:1646 */ +#line 821 "ncgen.y" + {datalistextend((yyvsp[(1) - (3)].datalist),&((yyvsp[(3) - (3)].constant))); (yyval.datalist)=(yyvsp[(1) - (3)].datalist);;} break; case 130: -#line 825 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_CHAR);} -#line 2519 "ncgeny.c" /* yacc.c:1646 */ +#line 825 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_CHAR);;} break; case 131: -#line 826 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_BYTE);} -#line 2525 "ncgeny.c" /* yacc.c:1646 */ +#line 826 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_BYTE);;} break; case 132: -#line 827 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_SHORT);} -#line 2531 "ncgeny.c" /* yacc.c:1646 */ +#line 827 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_SHORT);;} break; case 133: -#line 828 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_INT);} -#line 2537 "ncgeny.c" /* yacc.c:1646 */ +#line 828 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_INT);;} break; case 134: -#line 829 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_INT64);} -#line 2543 "ncgeny.c" /* yacc.c:1646 */ +#line 829 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_INT64);;} break; case 135: -#line 830 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_UBYTE);} -#line 2549 "ncgeny.c" /* yacc.c:1646 */ +#line 830 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_UBYTE);;} break; case 136: -#line 831 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_USHORT);} -#line 2555 "ncgeny.c" /* yacc.c:1646 */ +#line 831 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_USHORT);;} break; case 137: -#line 832 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_UINT);} -#line 2561 "ncgeny.c" /* yacc.c:1646 */ +#line 832 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_UINT);;} break; case 138: -#line 833 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_UINT64);} -#line 2567 "ncgeny.c" /* yacc.c:1646 */ +#line 833 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_UINT64);;} break; case 139: -#line 834 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_FLOAT);} -#line 2573 "ncgeny.c" /* yacc.c:1646 */ +#line 834 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_FLOAT);;} break; case 140: -#line 835 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_DOUBLE);} -#line 2579 "ncgeny.c" /* yacc.c:1646 */ +#line 835 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_DOUBLE);;} break; case 141: -#line 836 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_STRING);} -#line 2585 "ncgeny.c" /* yacc.c:1646 */ +#line 836 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_STRING);;} break; case 142: -#line 840 "ncgen.y" /* yacc.c:1646 */ - {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[0].constant)));} -#line 2591 "ncgeny.c" /* yacc.c:1646 */ +#line 840 "ncgen.y" + {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[(1) - (1)].constant)));;} break; case 143: -#line 841 "ncgen.y" /* yacc.c:1646 */ - {(yyval.datalist)=(yyvsp[-2].datalist); datalistextend((yyvsp[-2].datalist),&((yyvsp[0].constant)));} -#line 2597 "ncgeny.c" /* yacc.c:1646 */ +#line 841 "ncgen.y" + {(yyval.datalist)=(yyvsp[(1) - (3)].datalist); datalistextend((yyvsp[(1) - (3)].datalist),&((yyvsp[(3) - (3)].constant)));;} break; case 144: -#line 846 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_INT);} -#line 2603 "ncgeny.c" /* yacc.c:1646 */ +#line 846 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_INT);;} break; case 145: -#line 848 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_UINT);} -#line 2609 "ncgeny.c" /* yacc.c:1646 */ +#line 848 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_UINT);;} break; case 146: -#line 850 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_INT64);} -#line 2615 "ncgeny.c" /* yacc.c:1646 */ +#line 850 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_INT64);;} break; case 147: -#line 852 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_UINT64);} -#line 2621 "ncgeny.c" /* yacc.c:1646 */ +#line 852 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_UINT64);;} break; case 148: -#line 856 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=makeconstdata(NC_STRING);} -#line 2627 "ncgeny.c" /* yacc.c:1646 */ +#line 856 "ncgen.y" + {(yyval.constant)=makeconstdata(NC_STRING);;} break; case 149: -#line 860 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=(yyvsp[0].constant);} -#line 2633 "ncgeny.c" /* yacc.c:1646 */ +#line 860 "ncgen.y" + {(yyval.constant)=(yyvsp[(1) - (1)].constant);;} break; case 150: -#line 861 "ncgen.y" /* yacc.c:1646 */ - {(yyval.constant)=(yyvsp[0].constant);} -#line 2639 "ncgeny.c" /* yacc.c:1646 */ +#line 861 "ncgen.y" + {(yyval.constant)=(yyvsp[(1) - (1)].constant);;} break; case 151: -#line 867 "ncgen.y" /* yacc.c:1646 */ - {(yyval.sym)=(yyvsp[0].sym);} -#line 2645 "ncgeny.c" /* yacc.c:1646 */ +#line 867 "ncgen.y" + {(yyval.sym)=(yyvsp[(1) - (1)].sym);;} break; -#line 2649 "ncgeny.c" /* yacc.c:1646 */ +/* Line 1267 of yacc.c. */ +#line 2738 "ncgen.tab.c" default: break; } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); @@ -2667,7 +2745,8 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); *++yyvsp = yyval; - /* Now 'shift' the result of the reduction. Determine what state + + /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -2682,14 +2761,10 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); goto yynewstate; -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { @@ -2697,36 +2772,37 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } } -# undef YYSYNTAX_ERROR #endif } @@ -2734,24 +2810,24 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); if (yyerrstatus == 3) { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } } - /* Else will try to reuse lookahead token after shifting the error + /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; @@ -2767,7 +2843,7 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); if (/*CONSTCOND*/ 0) goto yyerrorlab; - /* Do not reclaim the symbols of the rule whose action triggered + /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; @@ -2780,37 +2856,38 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; yydestruct ("Error: popping", - yystos[yystate], yyvsp); + yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + if (yyn == YYFINAL) + YYACCEPT; + *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ @@ -2834,7 +2911,7 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); yyresult = 1; goto yyreturn; -#if !defined yyoverflow || YYERROR_VERBOSE +#ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -2845,22 +2922,17 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); #endif yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - } - /* Do not reclaim the symbols of the rule whose action triggered + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); + yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow @@ -2871,9 +2943,12 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name); if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif - return yyresult; + /* Make sure YYID is used. */ + return YYID (yyresult); } -#line 870 "ncgen.y" /* yacc.c:1906 */ + + +#line 870 "ncgen.y" #ifndef NO_STDARG @@ -3501,3 +3576,4 @@ evaluate(Symbol* fcn, Datalist* arglist) done: return result; } + diff --git a/ncgen/ncgeny.h b/ncgen/ncgeny.h index 4d09af5695..cbd5b52699 100644 --- a/ncgen/ncgeny.h +++ b/ncgen/ncgeny.h @@ -1,13 +1,14 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 2.3. */ -/* Bison interface for Yacc-like parsers in C +/* Skeleton interface for Bison's Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + 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 3 of the License, or - (at your option) any later version. + the Free Software Foundation; either version 2, 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 @@ -15,7 +16,9 @@ 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, see . */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -30,100 +33,139 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -#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. */ +/* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE - 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 - }; + /* 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, + _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 _NCPROPS 305 +#define _ISNETCDF4 306 +#define _SUPERBLOCK 307 +#define DATASETID 308 + -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -union YYSTYPE -{ -#line 138 "ncgen.y" /* yacc.c:1909 */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 138 "ncgen.y" +{ 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 117 "ncgeny.h" /* yacc.c:1909 */ -}; - -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 +} +/* Line 1529 of yacc.c. */ +#line 164 "ncgen.tab.h" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 #endif - extern YYSTYPE ncglval; -int ncgparse (void); - -#endif /* !YY_NCG_NCGEN_TAB_H_INCLUDED */