[netcdf] 01/08: Imported Upstream version 4.4.0

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Fri Jan 15 01:40:46 UTC 2016


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository netcdf.

commit 7fe383c348d06bcaa0d29accb20c3861bc76865c
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri Jan 15 01:39:44 2016 +0100

    Imported Upstream version 4.4.0
---
 .gitignore                             |     4 -
 .travis.yml                            |    63 +-
 .travis.yml => .travis.yml.old         |     0
 CMakeLists.txt                         |   230 +-
 CONTRIBUTING.html                      |   248 +
 Makefile.in                            |     1 -
 RELEASE_NOTES.md                       |    32 +-
 cf                                     |    13 +-
 cf.cmake                               |    70 +-
 config.h.cmake.in                      |    23 +-
 config.h.in                            |     3 +
 configure                              |    53 +-
 configure.ac                           |    22 +-
 docs/Doxyfile.developer                |     2 +-
 docs/Makefile.in                       |     1 -
 docs/images/Makefile.in                |     1 -
 docs/release_header.html               |     4 +-
 docs/software.md                       |   113 +-
 docs/tutorial.dox                      |    22 +-
 docs/windows-binaries.md               |    26 +-
 examples/C/Makefile.in                 |     1 -
 examples/C/simple_xy_nc4_rd.c          |     4 +-
 examples/C/simple_xy_nc4_wr.c          |     5 +-
 examples/CDL/Makefile.in               |     1 -
 examples/Makefile.in                   |     1 -
 h5_test/Makefile.in                    |     1 -
 include/Makefile.in                    |     1 -
 include/nc.h                           |    18 +-
 include/netcdf.h                       |    23 +-
 include/onstack.h                      |     8 +-
 libdap2/Makefile.in                    |     1 -
 libdap2/ncd2dispatch.c                 |    12 +-
 libdispatch/Makefile.in                |     1 -
 libdispatch/dattget.c                  |   109 +-
 libdispatch/dattput.c                  |    54 +-
 libdispatch/dstring.c                  |    48 +-
 libdispatch/dvar.c                     |    18 +-
 liblib/Makefile.am                     |     4 +-
 liblib/Makefile.in                     |     5 +-
 libnetcdf.settings.in                  |     7 +-
 libsrc/Makefile.in                     |     1 -
 libsrc/dim.c                           |    11 +-
 libsrc/ncx.h                           |    53 +-
 libsrc/ncx.m4                          |    38 +-
 libsrc/posixio.c                       |     4 +
 libsrc/putget.m4                       |    16 +-
 libsrc/v1hpg.c                         |   145 +-
 libsrc4/Makefile.in                    |     1 -
 libsrc4/nc4var.c                       |   259 +-
 libsrcp/Makefile.in                    |     1 -
 nc_test/CMakeLists.txt                 |     1 +
 nc_test/Makefile.in                    |     1 -
 nc_test/nc_test.c                      |    17 +-
 nc_test/test_get.c                     | 18662 ++++++++++++------------
 nc_test/test_put.c                     | 23884 +++++++++++++++----------------
 nc_test/test_read.c                    |    67 +-
 nc_test/test_write.c                   |    62 +-
 nc_test/tests.h                        |    18 +-
 nc_test/util.c                         |   101 +-
 nc_test4/CMakeLists.txt                |     5 +-
 nc_test4/Makefile.am                   |     3 +-
 nc_test4/Makefile.in                   |     4 +-
 nc_test4/bm_many_objs.c                |     5 +-
 nc_test4/tst_put_vars_two_unlim_dim.c  |    67 +
 ncdap_test/Makefile.in                 |     1 -
 ncdap_test/expected3/Makefile.in       |     1 -
 ncdap_test/expected3/test.07.dmp       |     6 +
 ncdap_test/expected3/test.21.dmp       |     6 +
 ncdap_test/expected4/Makefile.in       |     1 -
 ncdap_test/expected4/test.07.dmp       |     6 +
 ncdap_test/expected4/test.21.dmp       |     6 +
 ncdap_test/expectremote3/Makefile.in   |     1 -
 ncdap_test/expectremote3/test.01.1.dmp |    10 +
 ncdap_test/expectremote3/test.01.dmp   |     6 +
 ncdap_test/expectremote3/test.07.1.dmp |    10 +
 ncdap_test/expectremote3/test.07.3.dmp |    10 +
 ncdap_test/expectremote3/test.07.4.dmp |    10 +
 ncdap_test/expectremote3/test.07.dmp   |     6 +
 ncdap_test/expectremote4/Makefile.in   |     1 -
 ncdap_test/expectremote4/test.01.1.dmp |    10 +
 ncdap_test/expectremote4/test.01.dmp   |     6 +
 ncdap_test/expectremote4/test.07.1.dmp |    10 +
 ncdap_test/expectremote4/test.07.dmp   |     6 +
 ncdap_test/t_dap3a.c                   |     4 +-
 ncdap_test/testdata3/Makefile.in       |     1 -
 ncdap_test/testdata3/synth6.das        |    24 +-
 ncdump/CMakeLists.txt                  |    17 +-
 ncdump/Make0                           |    24 +
 ncdump/Makefile.am                     |    24 +-
 ncdump/Makefile.in                     |    81 +-
 ncdump/cdl/Makefile.am                 |     2 +-
 ncdump/cdl/Makefile.in                 |     3 +-
 ncdump/cdl/ref_keyword.cdl             |     9 +
 ncdump/cdl/ref_tst_solar_1.cdl         |     4 +-
 ncdump/chunkspec.c                     |    10 +-
 ncdump/ctests.sh                       |     2 +-
 ncdump/expected/Makefile.am            |     2 +-
 ncdump/expected/Makefile.in            |     3 +-
 ncdump/expected/c0.dmp                 |     4 +-
 ncdump/expected/ref_ctest1_nc4.dmp     |     4 +-
 ncdump/expected/ref_ctest1_nc4c.dmp    |     4 +-
 ncdump/expected/ref_keyword.dmp        |     8 +
 ncdump/expected/ref_tst_solar_1.dmp    |     4 +-
 ncdump/inttags.cdl                     |    15 +
 ncdump/inttags4.cdl                    |    23 +
 ncdump/ncdump.c                        |    29 +-
 ncdump/ncdump.h                        |     3 +-
 ncdump/ref_ctest1_nc4.cdl              |     4 +-
 ncdump/ref_inttags.cdl                 |    15 +
 ncdump/ref_inttags4.cdl                |    24 +
 ncdump/ref_tst_solar_1.cdl             |     4 +-
 ncdump/run_back_comp_tests.sh          |     1 +
 ncdump/run_tests.sh                    |     1 +
 ncdump/run_utf8_nc4_tests.sh           |     1 +
 ncdump/run_utf8_tests.sh               |     1 +
 ncdump/tst_64bit.sh                    |     1 +
 ncdump/tst_bom.sh                      |     1 +
 ncdump/tst_calendars.sh                |     1 +
 ncdump/tst_charfill.sh                 |     1 +
 ncdump/tst_dimsizes.c                  |    80 +
 ncdump/tst_dimsizes.sh                 |    57 +
 ncdump/tst_fillbug.sh                  |     1 +
 ncdump/tst_formatx3.sh                 |     1 +
 ncdump/tst_formatx4.sh                 |     1 +
 ncdump/tst_grp_spec.sh                 |     1 +
 ncdump/tst_h_scalar.sh                 |     1 +
 ncdump/tst_inmemory_nc3.sh             |     2 +-
 ncdump/tst_inmemory_nc4.sh             |     2 +-
 ncdump/tst_inttags.sh                  |    20 +
 ncdump/tst_inttags4.sh                 |    21 +
 ncdump/tst_iter.sh                     |     1 +
 ncdump/tst_lengths.sh                  |     2 +-
 ncdump/tst_mud.sh                      |     1 +
 ncdump/tst_nccopy3.sh                  |     1 +
 ncdump/tst_nccopy4.sh                  |     1 +
 ncdump/tst_ncgen4.sh                   |     1 +
 ncdump/tst_ncgen4_classic.sh           |     1 +
 ncdump/tst_ncgen4_cycle.sh             |     1 +
 ncdump/tst_ncgen4_diff.sh              |    11 +-
 ncdump/tst_ncgen_shared.sh             |     4 +-
 ncdump/tst_netcdf4.sh                  |     2 +
 ncdump/tst_netcdf4_4.sh                |     1 +
 ncdump/tst_output.sh                   |     1 +
 ncdump/vardata.c                       |    66 +-
 ncgen/CMakeLists.txt                   |    28 +-
 ncgen/Makefile.am                      |    21 +-
 ncgen/Makefile.in                      |    34 +-
 ncgen/c0_4.cdl                         |    10 +-
 ncgen/cdata.c                          |     6 +-
 ncgen/data.c                           |     6 +
 ncgen/data.h                           |     2 +
 ncgen/genbin.c                         |    10 +-
 ncgen/genc.c                           |    59 +-
 ncgen/generr.c                         |    20 +-
 ncgen/generr.h                         |     6 +
 ncgen/genlib.h                         |     8 +-
 ncgen/getfill.c                        |     4 +-
 ncgen/main.c                           |    92 +-
 ncgen/ncf345.cdl                       |  1743 +++
 ncgen/ncgen.1                          |    14 +-
 ncgen/ncgen.l                          |   330 +-
 ncgen/ncgen.y                          |    36 +-
 ncgen/{ncgenyy.c => ncgenl.c}          |  1659 +--
 ncgen/{ncgentab.c => ncgeny.c}         |  1314 +-
 ncgen/{ncgentab.h => ncgeny.h}         |    96 +-
 ncgen/offsets.h                        |     2 +-
 ncgen/run_nc4_tests.sh                 |     5 +
 ncgen/run_tests.sh                     |     2 +-
 ncgen/semantics.c                      |   131 +-
 ncgen/util.c                           |    59 +
 ncgen/util.h                           |     7 +-
 ncgen3/Makefile.in                     |     1 -
 nctest/Makefile.in                     |     1 -
 nctest/atttests.c                      |     2 +-
 oc2/CMakeLists.txt                     |     2 +-
 oc2/Make0                              |    12 +-
 oc2/Makefile.am                        |     8 +-
 oc2/Makefile.in                        |    27 +-
 oc2/auth.html.in                       |     4 +-
 oc2/dap.y                              |     2 +-
 oc2/daplex.c                           |     2 +-
 oc2/dapparse.c                         |     2 +-
 oc2/{daptab.c => dapy.c}               |  1642 ++-
 oc2/{daptab.h => dapy.h}               |    88 +-
 oc2/oc.css                             |    39 -
 oc2/oc.h                               |     2 +-
 oc2/ochttp.c                           |     2 -
 oc2/ocinternal.c                       |     2 +-
 oc2/ocnode.c                           |   245 +-
 189 files changed, 28250 insertions(+), 24969 deletions(-)

diff --git a/.gitignore b/.gitignore
index 08ae84b..791625a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,3 @@
-#####
-# End ignored generated files.
-#####
-
 ### 'Normal' gitignore files.
 autom4te.cache
 ctest.c
diff --git a/.travis.yml b/.travis.yml
index 5c0001b..32f13ab 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,52 +1,23 @@
-sudo: false
+sudo: required
 language: c
-compiler:
-  - gcc
-  - clang
+services:
+    - docker
 
-addons:
-    apt:
-      packages:
-      - libcurl4-openssl-dev
-      - m4
-      - wget
-      - autoconf
-      - libtool
-      - gfortran
-      - git
-      - doxygen
-      - graphviz
+env:
+    matrix:
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE USE_CC=gcc   COPTS='-DCMAKE_C_FLAGS=-fsigned-char' CURHOST=docker-gcc-x64-signed
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE USE_CC=clang COPTS='-DCMAKE_C_FLAGS=-fsigned-char' CURHOST=docker-clang-x64-signed
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE USE_CC=gcc   COPTS='-DCMAKE_C_FLAGS=-fsigned-char' CURHOST=docker-gcc-x86-signed
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE USE_CC=clang COPTS='-DCMAKE_C_FLAGS=-fsigned-char' CURHOST=docker-clang-x86-signed
 
-before_install:
-
-before_script:
-
-  ###
-  # Install dependencies from a pre-built binary.
-  ###
-  - cd $HOME
-  - wget http://www.unidata.ucar.edu/downloads/netcdf/ftp/travisdeps.tar.bz2
-
-  - tar -jxf travisdeps.tar.bz2
-  - export LD_LIBRARY_PATH=$HOME/usr/lib
-  - export PATH=$HOME/usr/bin:$PATH
-  - cd -
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE USE_CC=gcc   COPTS='-DCMAKE_C_FLAGS=-funsigned-char' CURHOST=docker-gcc-x64-unsigned
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE USE_CC=clang COPTS='-DCMAKE_C_FLAGS=-funsigned-char' CURHOST=docker-clang-x64-unsigned
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE USE_CC=gcc   COPTS='-DCMAKE_C_FLAGS=-funsigned-char' CURHOST=docker-gcc-x86-unsigned
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE USE_CC=clang COPTS='-DCMAKE_C_FLAGS=-funsigned-char' CURHOST=docker-clang-x86-unsigned
 
-  - mkdir build-all
-  - mkdir build-min
-
-  - cd build-min
-  - cmake .. -DENABLE_NETCDF_4=OFF -DENABLE_DAP=OFF -DCMAKE_PREFIX_PATH=$HOME/usr-min
-  - cd ..
-
-  - cd build-all
-  - cmake .. -DENABLE_MMAP=ON -DENABLE_DOXYGEN=ON -DENABLE_EXTRA_TESTS=ON -DENABLE_HDF4=ON -DCMAKE_PREFIX_PATH=$HOME/usr
-  - cd ..
+before_install:
+    - docker pull $DOCKIMG > /dev/null
 
 script:
-  - cd build-min
-  - make -j 4
-  - make test
-  - cd ../build-all
-  - make -j 4
-  - make test
\ No newline at end of file
+
+    - docker run --rm -it -h "$CURHOST" -e USEDASH=FALSE -e RUNF=OFF -e RUNCXX=OFF -e RUNP=OFF -e RUNNCO=OFF -e USECMAKE=$USECMAKE -e USEAC=$USEAC -e COPTS=$COPTS -e CTEST_OUTPUT_ON_FAILURE=1 -v $(pwd):/netcdf-c $DOCKIMG
diff --git a/.travis.yml b/.travis.yml.old
similarity index 100%
copy from .travis.yml
copy to .travis.yml.old
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2e80546..eaa50e3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,12 +27,12 @@ set(PACKAGE "netCDF" CACHE STRING "")
 SET(NC_VERSION_MAJOR 4)
 SET(NC_VERSION_MINOR 4)
 SET(NC_VERSION_PATCH 0)
-SET(NC_VERSION_NOTE "-rc5")
+SET(NC_VERSION_NOTE "")
 SET(netCDF_VERSION ${NC_VERSION_MAJOR}.${NC_VERSION_MINOR}.${NC_VERSION_PATCH}${NC_VERSION_NOTE})
 SET(VERSION ${netCDF_VERSION})
 SET(NC_VERSION ${netCDF_VERSION})
-SET(netCDF_LIB_VERSION 7.3.0)
-SET(netCDF_SO_VERSION 7)
+SET(netCDF_LIB_VERSION 11.0.0)
+SET(netCDF_SO_VERSION 11)
 SET(PACKAGE_VERSION ${VERSION})
 
 # Get system configuration, Use it to determine osname, os release, cpu. These
@@ -172,15 +172,17 @@ INCLUDE(GenerateExportHeader)
 # Compiler Configuration
 ################################
 
+##
 # Default building shared libraries.
 # BUILD_SHARED_LIBS is provided by/used by
 # CMake directly.
+##
 OPTION(BUILD_SHARED_LIBS "Configure netCDF as a shared library." ON)
 IF(BUILD_SHARED_LIBS)
   SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
 ENDIF()
 
-OPTION(FIND_SHARED_LIBS "Find shared variants of dependent libraries" ${BUILD_SHARED_LIBS})
+OPTION(NC_FIND_SHARED_LIBS "Find dynamicly-built versions of dependent libraries" ${BUILD_SHARED_LIBS})
 
 # Set some default linux gcc & apple compiler options for
 # debug builds.
@@ -233,6 +235,14 @@ IF(MSVC)
   ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
 ENDIF()
 
+#####
+# System inspection checks
+#####
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/oc2)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/libsrc)
+SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR}/libsrc)
+
 ################################
 # End Compiler Configuration
 ################################
@@ -446,7 +456,6 @@ IF(ENABLE_NETCDF_4)
   SET(USE_NETCDF4 ON CACHE BOOL "")
   SET(ENABLE_NETCDF_4 ON CACHE BOOL "")
   SET(ENABLE_NETCDF4 ON CACHE BOOL "")
-
 ENDIF()
 
 # Option for building RPC
@@ -455,49 +464,144 @@ IF(ENABLE_RPC)
   SET(BUILD_RPC ON CACHE BOOL "")
 ENDIF()
 
+##
 # Option to Enable HDF5
+#
+# The HDF5 cmake variables differ between platform (linux/osx and Windows),
+# as well as between HDF5 versions.  As a result, this section is a bit convoluted.
+#
+# Note that the behavior seems much more stable across HDF5 versions under linux,
+# so we do not have to do as much version-based tweaking.
+#
+# At the end of it, we should have the following defined:
+#
+# * HDF5_C_LIBRARY
+# * HDF5_HL_LIBRARY
+# * HDF5_LIBRARIES
+# * HDF5_INCLUDE_DIR
+# *
+##
 OPTION(USE_HDF5 "Use HDF5." ${ENABLE_NETCDF_4})
-
 IF(USE_HDF5 OR ENABLE_NETCDF_4)
   SET(USE_HDF5 ON)
   SET(USE_NETCDF4 ON)
+  ##
   # Accommodate developers who have hdf5 libraries and
   # headers on their system, but do not have a the hdf
   # .cmake files.  If this is the case, they should
   # specify HDF5_HL_LIB, HDF5_LIB, HDF5_INCLUDE_DIR manually.
-  IF(HDF5_LIB AND HDF5_HL_LIB AND HDF5_INCLUDE_DIR)
-    SET(HDF5_LIBRARIES ${HDF5_LIB} ${HDF5_HL_LIB})
-    SET(HDF5_C_LIBRARIES ${HDF5_LIB})
-    SET(HDF5_HL_LIBRARIES ${HDF5_HL_LIB})
-    MESSAGE(STATUS "Using HDF5 Library: ${HDF5_LIB}")
-    MESSAGE(STATUS "Using HDF5_HL LIbrary: ${HDF5_HL_LIB}")
-  ELSE()
-    IF(FIND_SHARED_LIBS)
-      SET(HDF5_USE_STATIC_LIBRARIES OFF)
-    ELSE()
-      SET(HDF5_USE_STATIC_LIBRARIES ON)
-    ENDIF()
+  ##
+  IF(HDF5_C_LIBRARY AND HDF5_HL_LIBRARY AND HDF5_INCLUDE_DIR)
+    SET(HDF5_LIBRARIES ${HDF5_C_LIBRARY} ${HDF5_HL_LIBRARY})
+    MESSAGE(STATUS "Using HDF5 C Library: ${HDF5_C_LIBRARY}")
+    MESSAGE(STATUS "Using HDF5 HL LIbrary: ${HDF5_HL_LIBRARY}")
+  ELSE(HDF5_C_LIBRARY AND HDF5_HL_LIBRARY AND HDF5_INCLUDE_DIR) # We are seeking out HDF5 with Find Package.
+    ###
+    # For now we assume that if we are building netcdf
+    # as a shared library, we will use hdf5 as a shared
+    # library. If we are building netcdf statically,
+    # we will use a static library.  This can be toggled
+    # by explicitely modifying NC_FIND_SHARED_LIBS.
+    ##
+    IF(NC_FIND_SHARED_LIBS)
+      SET(NC_HDF5_LINK_TYPE "shared")
+      SET(NC_HDF5_LINK_TYPE_UPPER "SHARED")
+      ADD_DEFINITIONS(-DH5_BUILT_AS_DYNAMIC_LIB)
+    ELSE(NC_FIND_SHARED_LIBS)
+      SET(NC_HDF5_LINK_TYPE "static")
+      SET(NC_HDF5_LINK_TYPE_UPPER "STATIC")
+      ADD_DEFINITIONS(-DH5_BUILT_AS_STATIC_LIB)
+    ENDIF(NC_FIND_SHARED_LIBS)
+
+    #####
+    # First, find the C and HL libraries.
+    #
+    # This has been updated to reflect what is in the hdf5
+    # examples, even though the previous version of what we
+    # had worked.
+    #####
     IF(MSVC)
-      FIND_PACKAGE(HDF5 COMPONENTS C HL NO_MODULE REQUIRED)
-    ELSE()
+      SET(SEARCH_PACKAGE_NAME ${HDF5_PACKAGE_NAME})
+      FIND_PACKAGE(HDF5 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS C HL NO_MODULES REQUIRED ${NC_HDF5_LINK_TYPE})
+    ELSE(MSVC)
       FIND_PACKAGE(HDF5 COMPONENTS C HL REQUIRED)
+    ENDIF(MSVC)
+
+    ##
+    # Next, check the HDF5 version. This will inform which
+    # HDF5 variables we need to munge.
+    ##
+
+    ##
+    # Assert HDF5 version meets minimum required version.
+    ##
+    SET(HDF5_VERSION_REQUIRED 1.8.10)
+
+    IF(HDF5_VERSION_STRING AND NOT HDF5_VERSION)
+      SET(HDF5_VERSION ${HDF5_VERSION_STRING})
     ENDIF()
-  ENDIF()
 
-  IF(NOT MSVC)
-    # Depending on the install, either HDF5_hdf_library or
-    # HDF5_C_LIBRARIES may be defined.  We must check for either.
-    IF(HDF5_C_LIBRARIES)
-      SET(HDF5_hdf5_LIBRARY ${HDF5_C_LIBRARIES})
+    IF("${HDF5_VERSION}" STREQUAL "")
+      MESSAGE(STATUS "Unable to determine hdf5 version.  NetCDF requires at least version ${HDF5_VERSION_REQUIRED}")
+    ELSE()
+      IF(${HDF5_VERSION} VERSION_LESS ${HDF5_VERSION_REQUIRED})
+        MESSAGE(FATAL_ERROR
+	      "netCDF requires at least HDF5 ${HDF5_VERSION_REQUIRED}. Found ${HDF5_VERSION}.")
+      ELSE()
+        MESSAGE(STATUS "Found HDF5 libraries version ${HDF5_VERSION}")
+      ENDIF()
     ENDIF()
 
+    ##
+    # Include the HDF5 include directory.
+    ##
+    INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
+
+    ###
+    # This is the block where we figure out what the appropriate
+    # variables are, and we ensure that we end up with
+    # HDF5_C_LIBRARY, HDF5_HL_LIBRARY and HDF5_LIBRARIES.
+    ###
+    IF(MSVC)
+      ##
+      # HDF5 1.8.15 defined HDF5_LIBRARIES.
+      ##
+      IF(${HDF5_VERSION} VERSION_LESS "1.8.16")
+        SET(HDF5_C_LIBRARY hdf5)
+      ENDIF(${HDF5_VERSION} VERSION_LESS "1.8.16")
+
+      IF(${HDF5_VERSION} VERSION_GREATER "1.8.15")
+        IF(NOT HDF5_LIBRARIES AND HDF5_C_${NC_HDF5_LINK_TYPE_UPPER}_LIBRARY AND HDF5_HL_${NC_HDF5_LINK_TYPE_UPPER}_LIBRARY)
+          SET(HDF5_C_LIBRARY ${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")
+
+    ELSE(MSVC)
+
+      # Depending on the install, either HDF5_hdf_library or
+      # HDF5_C_LIBRARIES may be defined.  We must check for either.
+      IF(HDF5_C_LIBRARIES AND NOT HDF5_hdf5_LIBRARY)
+        SET(HDF5_hdf5_LIBRARY ${HDF5_C_LIBRARIES})
+      ENDIF()
+
+    ENDIF(MSVC)
+  ENDIF(HDF5_C_LIBRARY AND HDF5_HL_LIBRARY AND HDF5_INCLUDE_DIR)
+
+  ###
+  # The following options are not used in Windows.
+  ###
+  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 H5Pget_fapl_mpiposix "" HDF5_IS_PARALLEL_MPIPOSIX)
     CHECK_LIBRARY_EXISTS(hdf5 H5Pget_fapl_mpio "" HDF5_IS_PARALLEL_MPIO)
     IF(HDF5_IS_PARALLEL_MPIPOSIX OR HDF5_IS_PARALLEL_MPIO)
-      SET(HDF5_IS_PARALLEL ON)
+      SET(HDF5_PARALLEL ON)
+    ELSE()
+      SET(HDF5_PARALLEL OFF)
     ENDIF()
 
     IF(HDF5_IS_PARALLEL_MPIO)
@@ -512,41 +616,26 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
     IF(ENABLE_DYNAMIC_LOADING)
       SET(USE_LIBDL ON CACHE BOOL "")
     ENDIF()
-
+    SET(HDF5_C_LIBRARY hdf5)
   ENDIF(NOT MSVC)
 
-  CHECK_LIBRARY_EXISTS(hdf5 H5free_memory "" HDF5_HAS_H5FREE)
+  CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY} H5free_memory "" HDF5_HAS_H5FREE)
 
 
-  # Assert HDF5 version.
-  SET(HDF5_VERSION_REQUIRED 1.8.10)
-
-  IF(HDF5_IS_PARALLEL)
+  IF(HDF5_PARALLEL)
 	SET(HDF5_CC h5pcc)
   ELSE()
 	SET(HDF5_CC h5cc)
   ENDIF()
 
-  execute_process(COMMAND sh -c "${HDF5_CC} -showconfig | grep -i 'HDF5 version' | cut -d: -f2 | tr -d ' '"
-  OUTPUT_VARIABLE HDF5_VERSION
-  ERROR_QUIET)
+  #  execute_process(COMMAND sh -c "${HDF5_CC} -showconfig | grep -i 'HDF5 version' | cut -d: -f2 | tr -d ' '"
+  #  OUTPUT_VARIABLE HDF5_VERSION
+  #  ERROR_QUIET)
 
   # It cannot be assumed that libhdf5.settings exists.  If it doesn't,
   # the call to h5cc will have failed.  At this point we will have to
   # trust the user that they have configured their system properly.
 
-  IF("${HDF5_VERSION}" STREQUAL "")
-    MESSAGE(STATUS "Unable to determine hdf5 version.  NetCDF requires at least version ${HDF5_VERSION_REQUIRED}")
-  ELSE()
-    IF(${HDF5_VERSION} VERSION_LESS ${HDF5_VERSION_REQUIRED})
-      MESSAGE(FATAL_ERROR
-	"netCDF requires at least HDF5 ${HDF5_VERSION_REQUIRED}. Found ${HDF5_VERSION}.")
-    ELSE()
-        MESSAGE(STATUS "Found HDF5 libraries version ${HDF5_VERSION}")
-    ENDIF()
-  ENDIF()
-
-  INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
 
   # Starting with hdf5 1.8.11, dynamic loading is an option.
   # In case hdf5 has a dependency on libdl, the user must specify
@@ -596,17 +685,16 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
   # Check to see if libhdf5 contains
   # 'H5free_memory'.
   ##
-#  CHECK_C_SOURCE_COMPILES("
-#  #include <hdf5.h>
-#  int main() {H5free_memory(NULL);}" HDF5_HAS_H5FREE)
-#  CHECK_SYMBOL_EXISTS(H5free_memory "H5public.h" HDF5_HAS_H5FREE)
-# CHECK_LIBRARY_EXISTS(hdf5 H5free_memory "-L${HDF5_hdf5_LIBRARY}" HDF5_HAS_H5FREE)
-#  MESSAGE(STATUS "HDF5_HAS_H5FREE: ${HDF5_HAS_H5FREE}")
+  #  CHECK_C_SOURCE_COMPILES("
+  #  #include <hdf5.h>
+  #  int main() {H5free_memory(NULL);}" HDF5_HAS_H5FREE)
+  #  CHECK_SYMBOL_EXISTS(H5free_memory "H5public.h" HDF5_HAS_H5FREE)
+  # CHECK_LIBRARY_EXISTS(hdf5 H5free_memory "-L${HDF5_hdf5_LIBRARY}" HDF5_HAS_H5FREE)
+  #  MESSAGE(STATUS "HDF5_HAS_H5FREE: ${HDF5_HAS_H5FREE}")
 
+ENDIF(USE_HDF5 OR ENABLE_NETCDF_4)
 
 
-ENDIF()
-
 # Option to Build DAP Client
 OPTION(ENABLE_DAP "Enable DAP Client." ON)
 IF(ENABLE_DAP)
@@ -832,18 +920,20 @@ ENDIF()
 
 # Enable Parallel (different than pnetcdf).
 SET(STATUS_PARALLEL "OFF")
-OPTION(ENABLE_PARALLEL4 "Build netCDF-4 with parallel IO" "${HDF5_IS_PARALLEL}")
+OPTION(ENABLE_PARALLEL4 "Build netCDF-4 with parallel IO" "${HDF5_PARALLEL}")
 IF(ENABLE_PARALLEL4 AND ENABLE_NETCDF_4)
-  IF(NOT HDF5_IS_PARALLEL)
+  IF(NOT HDF5_PARALLEL)
     SET(USE_PARALLEL OFF CACHE BOOL "")
     MESSAGE(STATUS "Cannot find HDF5 library built with parallel support. Disabling parallel build.")
   ELSE()
+    SET(HDF5_PARALLEL ON CACHE BOOL "")
     SET(USE_PARALLEL ON CACHE BOOL "")
     SET(USE_PARALLEL4 ON CACHE BOOL "")
     SET(STATUS_PARALLEL "ON")
   ENDIF()
 ENDIF()
 
+
 # Options to enable parallel IO, tests.
 SET(STATUS_PNETCDF "OFF")
 OPTION(ENABLE_PNETCDF "Build with parallel I/O for classic and 64-bit offset files using parallel-netcdf." OFF)
@@ -986,15 +1076,22 @@ MARK_AS_ADVANCED(ENABLE_DOXYGEN_BUILD_RELEASE_DOCS DOXYGEN_ENABLE_TASKS ENABLE_D
 # Option checks
 ################################
 
-#####
-# System inspection checks
-#####
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/oc2)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/libsrc)
-SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR}/libsrc)
+####
+# Check to see if char is signed or unsigned.
+####
+
+SET(SIGNED_TEST_SOURCE "\n
+  #include <stdlib.h>\n
+  int main(void) {\n
+    char is_signed = (char) - 1;\n
+    if(is_signed < 0)\n
+      return 1;\n
+    else\n
+      return 0;\n
+}\n")
+
+CHECK_C_SOURCE_RUNS("${SIGNED_TEST_SOURCE}" __CHAR_UNSIGNED__)
 
-#
 # Library include checks
 CHECK_INCLUDE_FILE("math.h"      HAVE_MATH_H)
 CHECK_INCLUDE_FILE("unistd.h"  HAVE_UNISTD_H)
@@ -1603,6 +1700,7 @@ is_enabled(ENABLE_NETCDF_4 HAS_HDF5)
 is_enabled(USE_SZIP HAS_SZIP)
 is_enabled(STATUS_PNETCDF HAS_PNETCDF)
 is_enabled(STATUS_PARALLEL HAS_PARALLEL)
+is_enabled(ENABLE_PARALLEL4 HAS_PARALLEL4)
 is_enabled(USE_DAP HAS_DAP)
 is_enabled(USE_DISKLESS HAS_DISKLESS)
 is_enabled(USE_MMAP HAS_MMAP)
diff --git a/CONTRIBUTING.html b/CONTRIBUTING.html
new file mode 100644
index 0000000..3447562
--- /dev/null
+++ b/CONTRIBUTING.html
@@ -0,0 +1,248 @@
+<html>
+<body>
+
+<img src="http://www.unidata.ucar.edu/images/logos/thredds_tds-150x150.png"/>
+
+<h1>Welcome contributors!</h1>
+
+First off, thank you for your interest in contributing to the THREDDS project!
+This repository contains the code for both netCDF-Java and the THREDDS Data Server (TDS) projects.
+The other projects held under the THREDDS umbrella are <a href="https://github.com/unidata/rosetta>Rosetta</a> and the latest addition, <a href="https://github.com/unidata/siphon>Siphon</a> (a python interface to the TDS).
+
+<h2>Process Overview</h2>
+
+<ul>
+ <li> <a href="#gh-setup">GitHub Setup</a>
+ <ul>
+ <li> <a href="#gh-join">Join Github!</a>
+ <li> <a href="#gh-fork">Fork the Unidata THREDDS project</a>
+ <li> <a href="#gh-pull-ud-thredds">Pull down local copy of the Unidata THREDDS project</a>
+ <li> <a href="#gh-pull-personal-thredds">Add and pull down a local copy of your THREDDS project fork</a>
+ </ul>
+ <li> <a href="#gh-contrib-workflow">Contribution workflow</a>
+ <ul>
+ <li> <a href="#gh-sync-ud">Make sure you have the latest changes from Unidata THREDDS repository</a>
+ <li> <a href="#gh-branch">Make a new branch for your work and start hacking</a>
+ <li> <a href="#gh-history-cleanup">Clean up your git commit history</a>
+ <li> <a href="#gh-final-commit-for-pr">Push changes to your fork to use for the pull request</a>
+ <li> <a href="#gh-pr">Make the pull request</a>
+ </ul>
+ <li> <a href="#gh-now-what">Now what?</a>
+ </ul>
+</ul>
+
+<h2><a name="gh-setup">GitHub Setup</a></h2>
+
+<h3><a name="gh-join">Join Github!</a></h3>
+To get started contributing to the THREDDS project, the first thing you should do is <a href="https://github.com/join">signup for a free account on GitHub</a>.
+
+<h3><a name="gh-fork">Fork the Unidata THREDDS project</a></h3>
+Once you have an account, go ahead and <a href="https://github.com/unidata/thredds#fork-destination-box">fork</a> the THREDDS project.
+By forking the project, you will have a complete copy of the THREDDS project, history and all, under your personal account.
+This will allow you to make pull requests against the Unidata THREDDS repository, which is the primairy mechanism used to add new code to the project (even Unidata developers do this!).
+
+<h3><a name="gh-pull-ud-thredds">Pull down local copy of the Unidata THREDDS project</a></h3>
+After cloning the Unidata repository, you can pull down the source code to your local machine by using git:
+<pre>git clone --origin unidata git at github.com:Unidata/thredds.git (for ssh)</pre>
+or
+<pre>git clone --origin unidata https://github.com/Unidata/thredds.git (for http)</pre>
+
+Note that these commands reference the Unidata repository.
+<p>
+Normally in git, the remote repository you clone from is automatically named 'origin'.
+To help with any confusion when making pull requests, this commands above rename the remote repository to 'unidata'.
+
+<h3><a name="gh-pull-personal-thredds">Add and pull down a local copy of your THREDDS project fork</a></h3>
+
+Next, move into the source directory git has created, and add your personal fork of the THREDDS code as a remote"
+<pre>git clone --origin me git at github.com:<my-github-user-name>/thredds.git (for ssh)</pre>
+or
+<pre>git clone --origin me https://github.com/,my-github-user-name>/thredds.git (for http)</pre>
+
+Now you are all set!
+
+<h2><a name="gh-contrib-workflow">Contribution workflow</a></h2>
+
+<h3><a name="gh-sync-ud">Make sure you have the latest changes from Unidata THREDDS repository</a></h3>
+First, make sure you have the most recent changes to the THREDDS code by using git pull:
+<pre>git pull unidata master</pre>
+
+<h3><a name="gh-branch">Make a new branch for your work and start hacking</a></h3>
+Next, make a new branch where you will actually do the hacking:
+<pre>git checkout -b mywork</pre>
+As of this point, the branch 'mywork' is local.
+To make this branch part of your personal GitHub Remote repository, use the following command:
+<pre>git push -u me mywork</pre>
+
+Now git (on your local machine) is setup to a point where you can start hacking on the code and commit changes to your personal GitHub repository.
+
+At any point, you may add commits to your local copy of the repository by using:
+
+<pre>git commit</pre>
+
+If you would like these changes to be stored on your personal remote repository, simply use:
+<pre>git push me mywork</pre>
+Once you are satisified with your work, there is one last step to complete before submitting the pull request - clean up the history.
+
+<h3><a name="gh-history-cleanup">Clean up your git commit history</a></h3>
+
+Commit history can often be full of temporiariy commit messages, of commits with code changes that ultimately didn't make the final cut.
+<p>
+To clean up your history, use the <pre>git rebase -i</pre> command, which will open an editor:
+<pre>
+sarms at flip: [mywork] git rebase -i
+pick 083508e first commit of my really cool feature or bug fix!
+pick 9bcba01 Oops missed this one thing. This commit fixes that.
+
+# Rebase 083508e..9bcba01 onto 083508e (2 command(s))
+#
+# Commands:
+# p, pick = use commit
+# r, reword = use commit, but edit the commit message
+# e, edit = use commit, but stop for amending
+# s, squash = use commit, but meld into previous commit
+# f, fixup = like "squash", but discard this commit</pre>message
+# x, exec = run command (the rest of the line) using shell
+# d, drop = remove commit
+#
+# These lines can be re-ordered; they are executed from top to bottom.
+#
+# If you remove a line here THAT COMMIT WILL BE LOST.
+#
+# However, if you remove everything, the rebase will be aborted.
+#
+# Note that empty commits are commented out
+<pre>
+
+Based on my commit messages, you can see that commit </pre>1' fixed a mistake from my first commit.
+
+It would be nice to 'squash' those changes into the first commit, so that the official history does not show my mistake..uhhh...this extra commit.
+
+To do so, edit the text to change the second commits 'pick' to 'squash':
+
+<pre>h
+pick 083508e first commit of my really cool feature or bug fix!
+squash 9bcba01 Oops missed this one thing. This commit fixes that.
+
+# Rebase 083508e..9bcba01 onto 083508e (2 command(s))
+#
+# Commands:
+# p, pick = use commit
+# r, reword = use commit, but edit the commit message
+# e, edit = use commit, but stop for amending
+# s, squash = use commit, but meld into previous commit
+# f, fixup = like "squash", but discard this commit</pre>message
+# x, exec = run command (the rest of the line) using shell
+# d, drop = remove commit
+#
+# These lines can be re-ordered; they are executed from top to bottom.
+#
+# If you remove a line here THAT COMMIT WILL BE LOST.
+#
+# However, if you remove everything, the rebase will be aborted.
+#
+# Note that empty commits are commented out
+<pre>
+
+Once you have marked the commits to be squashed and exited the edit, you will prompted to change the commit message for the new, squashed, mega commit:
+
+</pre>
+# This is a combination of 2 commits.
+# The first commit's message is:
+
+first commit of my really cool feature or bug fix!
+
+# This is the 2nd commit message:
+
+Oops missed this one thing. This commit fixes that.
+
+#Please enter the commit message for your changes. Lines starting
+# with '#' will be ignored, and an empty message aborts the commit.
+#
+# Date:      Thu Oct 15 09:59:23 2015 -0600
+#
+# interactive rebase in progress; onto 083508e
+# Last commands done (2 commands done):
+#    pick 09134d5 first commit of my really cool feature or bug fix!
+#    squash 9bcba01 Oops missed this one thing. This commit fixes that.
+# No commands remaining.
+# You are currently editing a commit while rebasing branch 'mywork' on '0835    08e'.
+#
+# Changes to be committed:
+...
+<pre>
+
+Edit the two commit messages into a single message that describes the overall change:
+
+</pre>
+
+Once you have and exit, you will have a change to change the commit message for the new, squashed, mega commit:
+
+<pre>h
+
+Really cool feature or bug fix. Addresses the github issue Unidata/thredds#1
+
+#Please enter the commit message for your changes. Lines starting
+# with </pre>l be ignored, and an empty message aborts the commit.
+#
+# Date:      Thu Oct 15 09:59:23 2015 -0600
+#
+# interactive rebase in progress; onto 083508e
+# Last commands done (2 commands done):
+#    pick 09134d5 first commit of my really cool feature or bug fix!
+#    squash 9bcba01 Oops missed this one thing. This commit fixes that.
+# No commands remaining.
+# You are currently editing a commit while rebasing branch 'mywork' on '0835    08e'.
+#
+# Changes to be committed:
+...
+<pre>
+
+Now, when you look at your git commit logs, you will see:
+
+</pre>
+commit 805b4723c4a2cbbed240354332cd7af57559a1b9
+Author: Sean Arms <sarms at ucar.edu>
+Date:   Thu Oct 15 09:59:23 2015 -0600
+
+    Really cool feature or bug fix. Addresses the github issue Unidata/thredds#1
+
+<pre>
+
+Note that the commit conains the text </pre>a/thredds#1'.
+This is a cool github trick that will allow you to reference GitHub issues within your commit messages.
+When viewed on github.com, this will be turned into a hyperlink to the issue.
+While not every contribution will address an issue, please use this feature if your contribution does!
+
+
+<h3><a name="gh-final-commit-for-pr">Push changes to your fork to use for the pull request</a></h3>
+Now that you have cleaned up the history, you will need to make a final push to your personal GitHub repository.
+However, the rebase has changed the history of your local branch, which means you will need to use the '--force' flag in your push:
+
+<pre>ush --force me mywork</pre>
+
+
+<h3><a name="gh-pr">Make the pull request</a></h3>
+Finally, go to your personal remote repository on github.com and switch to your 'mywork' branch.
+Once you are on your work branch, you will see a button that says "Pull request", which will allow you to make a pull request.
+
+The github pull request page will allow you to select which repository and branch you would like to submit the pull request to (the 'base fork', which should be 'Unidata/thredds', and 'base', which should be 'master'), as well as the 'head fork' and 'compare' (which should be '<github-user-name/thredds>' and 'mywork', respectivly).
+Once this is setup, you can make the pull request.
+
+
+<h2><a name="gh-now-what">Now what?</a></h2>
+
+The Unidata THREDDS project is setup such that automated testing for all pull requests is done via TravisCI.
+The status of the tests can be seen on the pull request page.
+For example, see <a href="https://github.com/Unidata/thredds/pull/231">Unidata/thredds#231</a> by selecting the 'View Details' button.
+This pull request was tested on <a href="https://travis-ci.org/Unidata/thredds/builds/84433104">TravisCI</a> and passed on all versions of Java supported by the current master branch.
+We have setup the THREDDS repository such that changes that do not pass these tests cannot be merged.
+
+One of the Unidata THREDDS team members will work with you to make sure your work is ready for merging once the tests have passed on TravisCI.
+Note that as changes to your pull request may be required, you can simply push thos changes to your personal GitHub repository and the pull request will automatically be updated and new TravisCI tests will be initiated.
+
+If your pull request addresses a bug, we kindly ask that you include a test in your pull request.
+If you do not know how to write tests in Java, we will be more than happy to work with you!
+
+</body>
+</html>
diff --git a/Makefile.in b/Makefile.in
index b6fcf12..2d38537 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -312,7 +312,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index fd3a823..e365fb2 100755
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -5,7 +5,31 @@ Release Notes       {#RELEASE_NOTES}
 
 This file contains a high-level description of this package's evolution. Releases are in reverse chronological order (most recent first). Note that, as of netcdf 4.2, the `netcdf-c++` and `netcdf-fortran` libraries have been separated into their own libraries.
 
-## 4.4.0 Released TBD
+## 4.4.0 Released - January 13, 2016
+
+* Bumped SO version to 11.0.0.
+
+* Modified `CMakeLists.txt` to work with the re-organized cmake configuration used by the latest HDF5, `1.8.16`, on Windows. Before this fix, netCDF would fail to locate hdf5 1.8.16 when using cmake on Windows.  See [GitHub #186](https://github.com/Unidata/netcdf-c/issues/186) for more information.
+
+* Addressed an issue with `ncdump` when annotations were used.  The indices for the last row suffered from an off-by-1 error.  See [GitHub issue #181](https://github.com/Unidata/netcdf-c/issues/181) for more information.
+
+* Addressed an issue on platforms where `char` is `unsigned` by default (such as `ARM`), as well as an issue describing regarding undefined behavior, again on `ARM`.  See [GitHub issue #159](https://github.com/Unidata/netcdf-c/issues/159) for detailed information.
+
+* Fixed an ambiguity in the grammar for cdl files.  See [GitHub #178](https://github.com/Unidata/netcdf-c/issues/178) for more information.
+
+* Updated documentation for `nc_get_att_string()` to reflect the fact that it returns allocated memory which must be explicitly free'd using `nc_free_string()`. Reported by Constantine Khroulev, see [GitHub Issue 171](https://github.com/Unidata/netcdf-c/issues/171) for more information.
+
+* Modified ncgen to properly handle the L and UL suffixes for integer constants
+  to keep backward compatibility. Now it is the case the single L suffix
+  (e.g. 111L) is treated as a 32 bit integer. This makes it consistent with
+  the fact that NC_LONG (netcdf.h) is an alias for NC_INT. Existing .cdl
+  files should be examined for occurrences of the L prefix to ensure that
+  this change will not affect them.
+  (see Github issue 156[https://github.com/Unidata/netcdf-c/issues/156]).
+
+* Updated documentation to reference the new `NodeJS` interface to netcdf4, by Sven Willner.  It is available from [https://www.npmjs.com/package/netcdf4](https://www.npmjs.com/package/netcdf4) or from the GitHub repository at [https://github.com/swillner/netcdf4-js](https://github.com/swillner/netcdf4-js).
+
+* Incorporated pull request https://github.com/Unidata/netcdf-c/pull/150 from Greg Sjaardema to remove the internal hard-wired use of `NC_MAX_DIMS`, instead using a dynamic memory allocation.
 
 ### 4.4.0-RC5 Released - November 11, 2015
 
@@ -18,7 +42,7 @@ This file contains a high-level description of this package's evolution. Release
 	Major kudos to Wei-Keng Liao for all the effort he put into getting this to work.
 
     This cascaded into a number of other changes.
-  
+
     1. Renamed libsrcp5 -> libsrcp because pnetcdf can do parallel io for CDF-1, CDF-2 and CDF-5, not just CDF-5.
     2. Given #1, then the NC_PNETCDF mode flag becomes a subset of NC_MPIIO, so made NC_PNETCDF an alias for NC_MPII.
     3. NC_FORMAT_64BIT is now deprecated.  Use NC_FORMAT_64BIT_OFFSET.
@@ -27,7 +51,7 @@ Further information regarding the CDF-5 file format specifrication may be found
 
 * Modified configure.ac to provide finer control over parallel
   support. Specifically, add flags for:
-  
+
     1. HDF5_PARALLEL when hdf5 library has parallel enabled
     2. --disable-parallel4 to be used when we do not want
      netcdf-4 to use parallelism even if hdf5 has it enabled.
@@ -44,7 +68,7 @@ NC\_FORMAT\_NC\_HDF5  | NC\_FORMATX\_NC\_HDF5
 NC\_FORMAT\_NC4       | NC\_FORMATX\_NC4
 NC\_FORMAT\_NC\_HDF4  | NC\_FORMATX\_NC\_HDF4
 NC\_FORMAT\_PNETCDF   | NC\_FORMATX\_PNETCDF
-NC\_FORMAT\_DAP2      | NC\_FORMATX\_DAP2 
+NC\_FORMAT\_DAP2      | NC\_FORMATX\_DAP2
 NC\_FORMAT\_DAP4      | NC\_FORMATX\_DAP4
 NC\_FORMAT\_UNDEFINED | NC\_FORMATX\_UNDEFINED
 
diff --git a/cf b/cf
index 8594f83..a2ca1a0 100644
--- a/cf
+++ b/cf
@@ -2,13 +2,10 @@
 #NB=1
 DB=1
 #X=-x
-FAST=1
-#CYGWIN=1
-
-FAST=1
+#FAST=1
 
 #HDF5=1
-#DAP=1
+DAP=1
 #PNETCDF=1
 #PAR4=1
 
@@ -119,7 +116,7 @@ FLAGS="$FLAGS --disable-examples"
 #FLAGS="$FLAGS --disable-dap-remote-tests"
 FLAGS="$FLAGS --enable-dap-auth-tests"
 #FLAGS="$FLAGS --enable-doxygen"
-#FLAGS="$FLAGS --enable-logging"
+FLAGS="$FLAGS --enable-logging"
 #FLAGS="$FLAGS --disable-diskless"
 #FLAGS="$FLAGS --enable-mmap"
 #FLAGS="$FLAGS --with-udunits"
@@ -132,10 +129,6 @@ if test "x$PAR4" != x1 ; then
 FLAGS="$FLAGS --disable-parallel4"
 fi
 
-if test "x$CYGWIN" = x1 ; then
-FLAGS="$FLAGS --enable-workaround"
-fi
-
 if test "x${DB}" = x1 ; then
 FLAGS="$FLAGS --disable-shared"
 else
diff --git a/cf.cmake b/cf.cmake
index 92358dc..ae300f3 100644
--- a/cf.cmake
+++ b/cf.cmake
@@ -1,16 +1,62 @@
+# Is visual studio being used?
+#VS=yes
+CYGWIN=yes
+
+if test "x$VS" = x ; then
+#CC=mpicc
+CC=gcc
+fi
+
+export CC
+
+if test "x$VS" != x -a "x$CYGWIN" != x ; then
+  ZLIB=cygz.dll; H5LIB=cyghdf5.dll; H5LIB_HL=cyghdf5_hl.dll; CURLLIB=cygcurl.dll
+elif test "x$VS" = x -a "x$CYGWIN" != x ; then
+  ZLIB=libz.dll.a; H5LIB=libhdf5.dll.a; H5LIB_HL=libhdf5_hl.dll.a; CURLLIB=libcurl.dll.a
+elif test "x$VS" = x -a "x$CYGWIN" == x ; then
+  ZLIB=libz.so; H5LIB=libhdf5.so; H5LIB_HL=libhdf5_hl.so; CURLLIB=libcurl.so
+else
+  echo "cannot determine library names"
+  exit 1
+fi
+
+for p in /usr/bin /usr/local/bin /usr/local/lib /usr/lib ; do
+if test -f $p/$ZLIB ; then ZP=$p; fi
+if test -f $p/$H5LIB ; then HP=$p; fi
+if test -f $p/$CURLLIB ; then CP=$p; fi
+done
+
+if test "x$ZP" = x ; then echo "Cannot find z lib" ; exit 1; fi
+if test "x$HP" = x ; then echo "Cannot find hdf5 lib" ; exit 1; fi
+if test "x$CP" = x ; then echo "Cannot find curl lib" ; exit 1; fi
+
+if test "x$CYGWIN" != x -a "x$VS" != x; then
+ZP=`cygpath -w "$ZP"`
+HP=`cygpath -w "$HP"`
+CP=`cygpath -w "$CP"`
+fi
+
+#if test "x$VS" != x ; then USR=c:/cygwin/usr; else USR=/usr; fi
+
+ZLIB="-DZLIB_LIBRARY=${ZP}/$ZLIB -DZLIB_INCLUDE_DIR=${ZP}/include -DZLIB_INCLUDE_DIRS=${ZP}/include"
+HDF5="-DHDF5_LIB=${HP}/$H5LIB -DHDF5_HL_LIB=${HP}/$H5LIB_HL -DHDF5_INCLUDE_DIR=${HP}/include"
+CURL="-DCURL_LIBRARY=${CP}/$CURLLIB -DCURL_INCLUDE_DIR=${CP}/include -DCURL_INCLUDE_DIRS=${CP}/include"
+
+FLAGS="$FLAGS -DCMAKE_C_FLAGS='-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter'"x2
+
+#FLAGS="$FLAGS -DENABLE_DAP=false"
+#FLAGS="$FLAGS -DENABLE_NETCDF_4=false"
+
+FLAGS="$FLAGS -DCMAKE_INSTALL_PREFIX=$USR/local"
+#FLAGS="-DCMAKE_PREFIX_PATH=$PPATH"
+#FLAGS="$FLAGS -DCMAKE_PREFIX_PATH=$PPATH"
+FLAGS="$FLAGS -DENABLE_DAP_REMOTE_TESTS=true"
+#FLAGS="$FLAGS -DENABLE_DAP_AUTH_TESTS=true"
+
 rm -fr build
 mkdir build
 cd build
-UL=/usr/local
-PPATH="$UL"
-ZLIB="-DZLIB_LIBRARY=${UL}/lib/libz.so  -DZLIB_INCLUDE_DIR=${UL}/include"
-HDF5="-DHDF5_LIB=${UL}/lib/libhdf5.so -DHDF5_HL_LIB=${UL}/lib/libhdf5_hl.so -DHDF5_INCLUDE_DIR=${UL}/include"
-CURL="-DCURL_LIBRARY=${UL}/lib/libcurl.so  -DCURL_INCLUDE_DIR=${UL}/include"
-FLAGS="-DCMAKE_PREFIX_PATH=$PPATH"
-FLAGS="$FLAGS -DCMAKE_INSTALL_PREFIX=${UL}"
-FLAGS="$FLAGS -DCMAKE_PREFIX_PATH=$PPATH"
-FLAGS="$FLAGS -DENABLE_DAP_REMOTE_TESTS=true"
-FLAGS="$FLAGS -DENABLE_DAP_AUTH_TESTS=true"
+
 cmake $FLAGS ${ZLIB} ${HDF5} ${CURL} ..
-#cmake --build .
-#cmake --build . --target test
+cmake --build .
+CTEST_OUTPUT_ON_FAILURE=1 cmake --build . --target test
diff --git a/config.h.cmake.in b/config.h.cmake.in
index a1c5948..5f747d4 100644
--- a/config.h.cmake.in
+++ b/config.h.cmake.in
@@ -5,6 +5,9 @@
    POSIX naming conventions. */
 #ifdef _MSC_VER
 
+#if _MSC_VER>=1900
+  #define STDC99
+#endif
 /* Define O_BINARY so that the appropriate flags
 are set when opening a binary file on Windows. */
 
@@ -28,17 +31,21 @@ are set when opening a binary file on Windows. */
   #endif
 
 #ifdef _WIN32
-	#ifndef strcasecmp
-  		#define strcasecmp _stricmp
-		#define snprintf _snprintf
-  	#endif
+  #ifndef strcasecmp
+    #define strcasecmp _stricmp
+  #endif
+  
+  #ifndef snprintf  
+    #if _MSC_VER<1900		
+      #define snprintf _snprintf
+    #endif
+  #endif 
 #endif
 
 
   #define strdup _strdup
   #define fdopen _fdopen
   #define write _write
-  #define snprintf _snprintf
   #define strtoll _strtoi64
 #endif
 
@@ -89,6 +96,7 @@ are set when opening a binary file on Windows. */
 #cmakedefine USE_PARALLEL_POSIX 1
 #cmakedefine USE_PARALLEL_MPIO 1
 #cmakedefine HDF5_HAS_H5FREE 1
+#cmakedefine HDF5_PARALLEL 1
 #cmakedefine USE_PARALLEL 1
 #cmakedefine USE_PARALLEL4 1
 #cmakedefine USE_PNETCDF 1
@@ -208,6 +216,11 @@ are set when opening a binary file on Windows. */
 /* Define if we have filelengthi64. */
 #cmakedefine HAVE_FILE_LENGTH_I64 @HAVE_FILE_LENGTH_I64@
 
+/* Define whether char is signed by default. */
+#ifndef __CHAR_UNSIGNED__
+#cmakedefine __CHAR_UNSIGNED__
+#endif
+
 /* The size of `void*` as computed by sizeof. */
 #cmakedefine SIZEOF_VOIDSTAR @SIZEOF_VOIDSTAR@
 /* The size of `char` as computed by sizeof. */
diff --git a/config.h.in b/config.h.in
index 4ec5c5f..c3eb51b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -209,6 +209,9 @@
 /* Define to 1 if you have the `rand' function. */
 #undef HAVE_RAND
 
+/* Define to 1 if the system has the type `size_t'. */
+#undef HAVE_SIZE_T
+
 /* Define to 1 if you have the `snprintf' function. */
 #undef HAVE_SNPRINTF
 
diff --git a/configure b/configure
index ff488ee..3705213 100755
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.ac Id: configure.ac,v 1.450 2010/05/28 19:42:47 dmh Exp .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for netCDF 4.4.0-development.
+# Generated by GNU Autoconf 2.69 for netCDF 4.4.0.
 #
 # Report bugs to <support-netcdf at unidata.ucar.edu>.
 #
@@ -591,8 +591,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='netCDF'
 PACKAGE_TARNAME='netcdf'
-PACKAGE_VERSION='4.4.0-development'
-PACKAGE_STRING='netCDF 4.4.0-development'
+PACKAGE_VERSION='4.4.0'
+PACKAGE_STRING='netCDF 4.4.0'
 PACKAGE_BUGREPORT='support-netcdf at unidata.ucar.edu'
 PACKAGE_URL=''
 
@@ -666,7 +666,6 @@ HAS_SZLIB
 HAS_HDF5
 HAS_PNETCDF
 HAS_HDF4
-HAS_SZIP
 HAS_NC4
 HAS_NC2
 HAS_DAP
@@ -1496,7 +1495,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures netCDF 4.4.0-development to adapt to many kinds of systems.
+\`configure' configures netCDF 4.4.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1567,7 +1566,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of netCDF 4.4.0-development:";;
+     short | recursive ) echo "Configuration of netCDF 4.4.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1784,7 +1783,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-netCDF configure 4.4.0-development
+netCDF configure 4.4.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2493,7 +2492,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by netCDF $as_me 4.4.0-development, which was
+It was created by netCDF $as_me 4.4.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2848,7 +2847,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
  NC_VERSION_MAJOR=4
  NC_VERSION_MINOR=4
  NC_VERSION_PATCH=0
- NC_VERSION_NOTE="-rc5"
+ NC_VERSION_NOTE=""
 
 #####
 # Set some variables used to generate a libnetcdf.settings file,
@@ -2857,11 +2856,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 # Create the VERSION file, which contains the package version from
 # AC_INIT.
-echo 4.4.0-development>VERSION
+echo 4.4.0>VERSION
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: netCDF 4.4.0-development" >&5
-$as_echo "$as_me: netCDF 4.4.0-development" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: netCDF 4.4.0" >&5
+$as_echo "$as_me: netCDF 4.4.0" >&6;}
 
 # Keep libtool macros in an m4 directory.
 
@@ -3502,7 +3501,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='netcdf'
- VERSION='4.4.0-development'
+ VERSION='4.4.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -16528,6 +16527,15 @@ _ACEOF
 
 fi
 
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SIZE_T 1
+_ACEOF
+
+
+fi
 ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
 if test "x$ac_cv_type_ssize_t" = xyes; then :
 
@@ -17177,8 +17185,8 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-$SLEEPCMD
 
+$SLEEPCMD
 if test "$ac_cv_type_ushort" = yes ; then
    # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
@@ -17248,7 +17256,8 @@ _ACEOF
 
 
 fi
-sleep 3
+
+$SLEEPCMD
 if test "$ac_cv_type_uint" = yes ; then
    # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
@@ -17319,6 +17328,7 @@ _ACEOF
 
 fi
 
+$SLEEPCMD
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -17902,7 +17912,7 @@ $as_echo "#define USE_ZLIB 1" >>confdefs.h
 
    # The user may have built HDF5 with the SZLIB library.
    if test "x$ac_cv_func_H5Z_SZIP" = xyes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SZ_Compress" >&5
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SZ_Compress" >&5
 $as_echo_n "checking for library containing SZ_Compress... " >&6; }
 if ${ac_cv_search_SZ_Compress+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -18145,9 +18155,9 @@ fi
 
 # Should we suppress parallel io for netcdf-4?
 if test "x$enable_netcdf_4" = xyes ; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether parallel I/O is enabled for netcdf-4" >&5
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether parallel I/O is enabled for netcdf-4" >&5
 $as_echo_n "checking whether parallel I/O is enabled for netcdf-4... " >&6; }
-  # Check whether --enable-parallel4 was given.
+     # Check whether --enable-parallel4 was given.
 if test "${enable_parallel4+set}" = set; then :
   enableval=$enable_parallel4;
 fi
@@ -18829,7 +18839,6 @@ $as_echo "#define JNA 1" >>confdefs.h
 
 fi
 
-
 NC_LIBS=$NC_LIBS
 
 HAS_DAP=$enable_dap
@@ -18838,8 +18847,6 @@ HAS_NC2=$nc_build_v2
 
 HAS_NC4=$enable_netcdf_4
 
-HAS_SZIP=$ac_cv_func_H5Z_SZIP
-
 HAS_HDF4=$enable_hdf4
 
 HAS_PNETCDF=$enable_pnetcdf
@@ -19687,7 +19694,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by netCDF $as_me 4.4.0-development, which was
+This file was extended by netCDF $as_me 4.4.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19753,7 +19760,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-netCDF config.status 4.4.0-development
+netCDF config.status 4.4.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index cf714d4..96b6dbe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,12 +15,12 @@ AC_REVISION([$Id: configure.ac,v 1.450 2010/05/28 19:42:47 dmh Exp $])
 AC_PREREQ([2.59])
 
 # Initialize with name, version, and support email address.
-AC_INIT([netCDF], [4.4.0-development], [support-netcdf at unidata.ucar.edu])
+AC_INIT([netCDF], [4.4.0], [support-netcdf at unidata.ucar.edu])
 
 AC_SUBST([NC_VERSION_MAJOR]) NC_VERSION_MAJOR=4
 AC_SUBST([NC_VERSION_MINOR]) NC_VERSION_MINOR=4
 AC_SUBST([NC_VERSION_PATCH]) NC_VERSION_PATCH=0
-AC_SUBST([NC_VERSION_NOTE]) NC_VERSION_NOTE="-rc5"
+AC_SUBST([NC_VERSION_NOTE]) NC_VERSION_NOTE=""
 
 #####
 # Set some variables used to generate a libnetcdf.settings file,
@@ -803,7 +803,7 @@ AC_STRUCT_ST_BLKSIZE
 UD_CHECK_IEEE
 AC_TYPE_SIZE_T
 AC_TYPE_OFF_T
-AC_CHECK_TYPES([ssize_t, ptrdiff_t, uchar, longlong, ushort, uint, int64, uint64])
+AC_CHECK_TYPES([size_t, ssize_t, ptrdiff_t, uchar, longlong, ushort, uint, int64, uint64])
 AC_C_CHAR_UNSIGNED
 AC_C_BIGENDIAN
 
@@ -836,20 +836,22 @@ $SLEEPCMD
 AC_CHECK_SIZEOF(size_t)
 $SLEEPCMD
 AC_CHECK_SIZEOF(unsigned long long)
-$SLEEPCMD
 
+$SLEEPCMD
 if test "$ac_cv_type_ushort" = yes ; then
    AC_CHECK_SIZEOF(ushort)
 else
    AC_CHECK_SIZEOF(unsigned short int)
 fi
-sleep 3
+
+$SLEEPCMD
 if test "$ac_cv_type_uint" = yes ; then
    AC_CHECK_SIZEOF(uint)
 else
    AC_CHECK_SIZEOF(unsigned int)
 fi
 
+$SLEEPCMD
 AC_CHECK_SIZEOF(unsigned long long)
 
 $SLEEPCMD
@@ -930,7 +932,7 @@ if test "x$enable_netcdf_4" = xyes; then
 
    # The user may have built HDF5 with the SZLIB library.
    if test "x$ac_cv_func_H5Z_SZIP" = xyes; then
-   	AC_SEARCH_LIBS([SZ_Compress], [szip sz], [], [])
+    AC_SEARCH_LIBS([SZ_Compress], [szip sz], [], [])
   	AC_DEFINE([USE_SZIP], [1], [if true, compile in szip compression in netCDF-4 variables])
    fi
 
@@ -961,9 +963,9 @@ fi
 
 # Should we suppress parallel io for netcdf-4?
 if test "x$enable_netcdf_4" = xyes ; then
-  AC_MSG_CHECKING([whether parallel I/O is enabled for netcdf-4])
-  AC_ARG_ENABLE([parallel4], [AS_HELP_STRING([--disable-parallel4],
-                [disable parallel I/O for netcdf-4, even if it's enabled in libhdf5])])
+     AC_MSG_CHECKING([whether parallel I/O is enabled for netcdf-4])
+     AC_ARG_ENABLE([parallel4], [AS_HELP_STRING([--disable-parallel4],
+                                          [disable parallel I/O for netcdf-4, even if it's enabled in libhdf5]  )])
   test "x$enable_parallel4" = xno || enable_parallel4=yes
   AC_MSG_RESULT($enable_parallel4)
 else
@@ -1200,12 +1202,10 @@ if test "x$enable_jna" = xyes ; then
 AC_DEFINE([JNA], [1], [if true, include JNA bug fix])
 fi
 
-
 AC_SUBST(NC_LIBS,[$NC_LIBS])
 AC_SUBST(HAS_DAP,[$enable_dap])
 AC_SUBST(HAS_NC2,[$nc_build_v2])
 AC_SUBST(HAS_NC4,[$enable_netcdf_4])
-AC_SUBST(HAS_SZIP,[$ac_cv_func_H5Z_SZIP])
 AC_SUBST(HAS_HDF4,[$enable_hdf4])
 AC_SUBST(HAS_PNETCDF,[$enable_pnetcdf])
 AC_SUBST(HAS_HDF5,[$enable_netcdf_4])
diff --git a/docs/Doxyfile.developer b/docs/Doxyfile.developer
index a743dc4..520205b 100755
--- a/docs/Doxyfile.developer
+++ b/docs/Doxyfile.developer
@@ -38,7 +38,7 @@ PROJECT_NAME           = netCDF-C
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 4.4.0-RC5
+PROJECT_NUMBER         = 4.4.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/docs/Makefile.in b/docs/Makefile.in
index d8d92a4..9ab4745 100644
--- a/docs/Makefile.in
+++ b/docs/Makefile.in
@@ -237,7 +237,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/docs/images/Makefile.in b/docs/images/Makefile.in
index ed2d52f..a084288 100644
--- a/docs/images/Makefile.in
+++ b/docs/images/Makefile.in
@@ -174,7 +174,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/docs/release_header.html b/docs/release_header.html
index a98c759..7670b08 100644
--- a/docs/release_header.html
+++ b/docs/release_header.html
@@ -29,8 +29,8 @@ $extrastylesheet
 
   var $linkMenu = "<select id=\"versions\">" +
     "   <option value=\"http://www.unidata.ucar.edu/software/netcdf/docs\">Current</option>" +
-    "   <option value=\"http://www.unidata.ucar.edu/software/netcdf/documentation/$projectnumber\">$projectnumber</option>" +
-    "   <option value=\"http://www.unidata.ucar.edu/software/netcdf/documentation/historic\">Historic Documentation</option>" +
+    "   <option value=\"http://www.unidata.ucar.edu/software/netcdf/documentation/4.4.0\">4.4.0</option>" +
+    "   <option value=\"http://www.unidata.ucar.edu/software/netcdf/documentation/historic/netcdf\">Historic netCDF Documentation</option>" +
     "</select>";
 
   $("#navrow1 ul.tablist").append('<li class=\"linkMenu\"><span class="tab">' + $linkMenu + '</span></li>');
diff --git a/docs/software.md b/docs/software.md
index 2e100aa..43ec5ab 100644
--- a/docs/software.md
+++ b/docs/software.md
@@ -16,76 +16,27 @@ Freely Available Software {#freely}
 ANDX and ANAX {#ANDX}
 ------------------------------------
 
-The ARM Program has developed [ANDX (ARM NetCDF Data
-eXtract)](http://engineering.arm.gov/~sbeus/andx-web/html/), a
-command-line utility designed for routine examination and extraction of
-data from netcdf files. Data can be displayed graphically (line-plot,
-scatter-plot, overlay, color-intensity, etc.) or extracted as ASCII
-data. Whether displayed graphically or extracted as ASCII, results can
-be saved to disk or viewed on screen.
-
-[ANAX (ARM NetCDF ASCII
-eXtract)](http://science.arm.gov/~cflynn/ARM_Tested_Tools/) is a
-scaled-down version of ANDX -- it is designed to only extract ASCII
-data. All features of ANDX pertaining to non-graphic data extraction are
-included in ANAX.
+The ARM Program has developed [ANDX (ARM NetCDF Data eXtract)](http://engineering.arm.gov/~sbeus/andx-web/html/), a command-line utility designed for routine examination and extraction of data from netcdf files. Data can be displayed graphically (line-plot, scatter-plot, overlay, color-intensity, etc.) or extracted as ASCII data. Whether displayed graphically or extracted as ASCII, results can be saved to disk or viewed on screen.
+
+[ANAX (ARM NetCDF ASCII eXtract)](http://science.arm.gov/~cflynn/ARM_Tested_Tools/) is a scaled-down version of ANDX -- it is designed to only extract ASCII data. All features of ANDX pertaining to non-graphic data extraction are included in ANAX.
 
 ANTS {#ANTS}
 ---------------------------
 
-The ARM Program has developed [ANTS (ARM NetCDF Tool
-Suite)](http://science.arm.gov/~cflynn/ANTS/), a collection of netCDF
-tools and utilities providing various means of creating and modifying
-netcdf files. ANTS is based on nctools written by Chuck Denham. The
-utilities within nctools were modified to compile with version 3.5 of
-the netCDF library, the command syntax was modified for consistency with
-other tools, and changes were made to accommodate ARM standard netCDF.
-
-The original functions from nctools were intended mainly for the
-creation, definition, and copying of fundamental netCDF elements. ARM
-added others which focus on manipulation of data within existing netCDF
-files. Additional functions have special support for multi-dimensional
-data such as "slicing" cross sections from multi-dimensional variable
-data or joining lesser-dimensional fields to form multi-dimensional
-structures. Functions have been added to support execution of arithmetic
-and logical operations, bundling or splitting netCDF files, comparing
-the structure or content of files, and so on.
-
-Essentially every type of netCDF library function call is exercised in
-ANTS. In this way then, this open-source collection of tools also
-represents a library of coding examples for fundamental netCDF tasks.
-See the [website](http://science.arm.gov/~cflynn/ANTS/) for more
-information.
+The ARM Program has developed [ANTS (ARM NetCDF Tool Suite)](http://science.arm.gov/~cflynn/ANTS/), a collection of netCDF tools and utilities providing various means of creating and modifying netcdf files. ANTS is based on nctools written by Chuck Denham. The utilities within nctools were modified to compile with version 3.5 of the netCDF library, the command syntax was modified for consistency with other tools, and changes were made to accommodate ARM standard netCDF.
+
+The original functions from nctools were intended mainly for the creation, definition, and copying of fundamental netCDF elements. ARM added others which focus on manipulation of data within existing netCDF files. Additional functions have special support for multi-dimensional data such as "slicing" cross sections from multi-dimensional variable data or joining lesser-dimensional fields to form multi-dimensional structures. Functions have been added to support execution of arithmetic and [...]
+
+Essentially every type of netCDF library function call is exercised in ANTS. In this way then, this open-source collection of tools also represents a library of coding examples for fundamental netCDF tasks. See the [website](http://science.arm.gov/~cflynn/ANTS/) for more information.
 
 ARGOS {#ARGOS}
 -----------------------------
 
-[ARGOS](http://www.lapeth.ethz.ch/argos/index.html) (interActive
-thRee-dimensional Graphics ObServatory) is a new IDL-based interactive
-3D visualization tool, developed by [David N.
-Bresch](http://www.lapeth.ethz.ch/~david/index.html) and [Mark A.
-Liniger](http://www.lapeth.ethz.ch/~mark/index.html) at the Institute
-for Atmospheric Science at the Swiss Federal Institute of Technology,
-ETH, Zürich.
-
-A highly optimized graphical user interface allows quick and elegant
-creation of even complex 3D graphics (volume rendering,
-isosurfaces,...), including Z-buffered overlays (with hidden lines),
-light and data shading, Xray images, 3D trajectories, animations and
-virtual flights around your data, all documented in a full on-line
-[html-help](http://www.lapeth.ethz.ch/argos/argos_general.html). The
-netCDF data format is preferred, but any other format can be read by
-providing an IDL (or FORTRAN or C or C++) interface. Some toolboxes (for
-atmospheric model output, trajectory display, radar data) have already
-been written, others might easily be added (in IDL, FORTRAN or C code).
-All interactive activities are tracked in a script, allowing quick
-reconstruction of anything done as well as running ARGOS in batch script
-mode.
-
-Information about [copyright and licensing
-conditions](http://www.lapeth.ethz.ch/argos/argos_copyright.html) are
-available. For further information and installation, please E-mail to:
-bresch at atmos.umnw.ethz.ch
+[ARGOS](http://www.lapeth.ethz.ch/argos/index.html) (interActive thRee-dimensional Graphics ObServatory) is a new IDL-based interactive 3D visualization tool, developed by [David N. Bresch](http://www.lapeth.ethz.ch/~david/index.html) and [Mark A. Liniger](http://www.lapeth.ethz.ch/~mark/index.html) at the Institute for Atmospheric Science at the Swiss Federal Institute of Technology, ETH, Zürich.
+
+A highly optimized graphical user interface allows quick and elegant creation of even complex 3D graphics (volume rendering, isosurfaces,...), including Z-buffered overlays (with hidden lines), light and data shading, Xray images, 3D trajectories, animations and virtual flights around your data, all documented in a full on-line [html-help](http://www.lapeth.ethz.ch/argos/argos_general.html). The netCDF data format is preferred, but any other format can be read by providing an IDL (or FOR [...]
+
+Information about [copyright and licensing conditions](http://www.lapeth.ethz.ch/argos/argos_copyright.html) are available. For further information and installation, please E-mail to: bresch at atmos.umnw.ethz.ch
 
 CDAT {#CDAT}
 ---------------------------
@@ -215,10 +166,8 @@ site](http://www-c4.ucsd.edu/~cids/software/visual.html).
 CSIRO MATLAB/netCDF interface {#CSIRO-MATLAB}
 ------------------------------------------------------------
 
-The [CSIRO MATLAB/netCDF
-interface](http://www.marine.csiro.au/sw/matlab-netcdf.html) is now
-available from the [CSIRO Marine
-Laboratories](http://www.marine.csiro.au).
+The [CSIRO MATLAB/netCDF interface](http://www.marine.csiro.au/sw/matlab-netcdf.html) is now
+available from the [CSIRO Marine Laboratories](http://www.marine.csiro.au).
 The CSIRO MATLAB/netCDF interface is run from within MATLAB and has a
 simple syntax. It has options for automatically handling missing values,
 scale factors, and permutation of hyperslabs. It is, however, limited to
@@ -1203,6 +1152,10 @@ The source may be downloaded from <ftp://cirrus.ucsd.edu/pub/ncview/>.
 For more information, please contact the author, David W. Pierce at
 <dpierce at ucsd.edu>.
 
+netcdf4-js {#netcdf4-js}
+-------------------------------
+[netcdf4-js](https://www.npmjs.com/package/netcdf4) is a NodeJS addon for reading and writing the files in the Network Common Data Form (NetCDF) version <= 4, built upon the C-library for netcdf. It isavailable from npmjs at the link above, or directly from the [GitHub Repository](https://github.com/swillner/netcdf4-js).
+
 NetCDF Toolbox for MATLAB-5 {#matlab5}
 ----------------------------------------------------
 
@@ -1827,6 +1780,32 @@ The SDS project is in beta phase and keeps evolving. You are welcome to
 join discussions or report issues at the CodePlex site:
 <http://sds.codeplex.com>.
 
+sciNetCDF {#scinetcdf}
+-------------------------------------------------------------
+[sciNetCDF](https://atoms.scilab.org/toolboxes/scinetcdf)
+
+In the context of the IASI-NG project, CNES is responsible for the development
+of a Scilab/NetCDF4 interface, which CNES wanted to make available to the entire
+scientific community.
+
+The toolbox sciNetCDF is the result of this collaboration. It can read and write
+NetCDF files of any version (version 4 of the format is used by default for
+writing).
+
+The toolbox provides high level functions to read/write NetCDF files natively in
+Scilab in a friendly manner (data is converted automatically from Scilab to
+NetCDF and inversely).
+These functions are:
+- nccreate
+- ncwrite
+- ncread
+- ncwriteatt
+- ncreadatt
+- ncdisp
+
+It provides also a low level interface to all the NetCDF C library functions
+
+
 Apache Spatial Information System (SIS) {#SIS}
 -------------------------------------------------------------
 
@@ -2383,6 +2362,8 @@ implement a MATLAB/netCDF interface are available:
 reader](http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=15177&objectType=file),
 and [fanmat](/software/netcdf/Contrib.html).
 
+
+
 Noesys {#Neosys}
 -------------------------------
 
diff --git a/docs/tutorial.dox b/docs/tutorial.dox
index 4b3adf6..b546ff0 100644
--- a/docs/tutorial.dox
+++ b/docs/tutorial.dox
@@ -786,35 +786,19 @@ with nc_get_vara()/nc_put_vara().
 
 \page parallel_io Parallel I/O with NetCDF-4
 
-NetCDF-4 provides access to HDF5 parallel I/O features for
-netCDF-4/HDF5 files. NetCDF classic and 64-bit offset format may not
-be opened or created for use with parallel I/O. (They may be opened
-and created, but parallel I/O is not available.)
-
-A few functions have been added to the netCDF C API to handle parallel
-I/O.
-
-You must build netCDF-4 properly to take advantage of parallel
+NetCDF-4 provides access to HDF5 parallel I/O features for netCDF-4/HDF5 files. NetCDF classic and 64-bit offset format may not be opened or created for use with HDF5-based parallel I/O. (They may be opened and created, but parallel I/O is not available.)  They may be opened or created for use with parallel-netcdf-based parallel I/O. A few functions have been added to the netCDF C API to handle parallel I/O. You must build netCDF-4 properly to take advantage of parallel
 features (see \ref build_parallel).
 
 The nc_open_par() and nc_create_par() functions are used to
 create/open a netCDF file with parallel access.
 
-The parallel access associated with these functions is not a
-characteristic of the data file, but the way it was opened.
+\note The parallel access associated with these functions is not a characteristic of the data file, but the way it was opened.
 
 \section collective_independent Collective/Independent Access
 
 Parallel file access is either collective (all processors must
 participate) or independent (any processor may access the data without
-waiting for others).
-
-All netCDF metadata writing operations are collective. That is, all
-creation of groups, types, variables, dimensions, or attributes.
-
-Data reads and writes (ex. calls to nc_put_vara_int() and
-nc_get_vara_int()) may be independent (the default) or collective. To
-make writes to a variable collective, call nc_var_par_access().
+waiting for others). All netCDF metadata writing operations are collective. That is, all creation of groups, types, variables, dimensions, or attributes. Data reads and writes (ex. calls to nc_put_vara_int() and nc_get_vara_int()) may be independent (the default) or collective. To make writes to a variable collective, call nc_var_par_access().
 
 \page tutorial_ncids Numbering of NetCDF IDs
 
diff --git a/docs/windows-binaries.md b/docs/windows-binaries.md
index 2cf7062..15fd414 100644
--- a/docs/windows-binaries.md
+++ b/docs/windows-binaries.md
@@ -32,14 +32,14 @@ The included dependencies and versions are as follows:
 * `libcurl`: 7.35.0
 * `zlib`:    1.2.8
 
-## Latest Release (netCDF-C 4.4.0-rc5) {#msvc-latest-release}
+## Latest Release (netCDF-C 4.4.0) {#msvc-latest-release}
 
 Configuration		| 32-bit 						| 64-bit |
 :-------------------|:--------							|:-------|
-netCDF 3		| [netCDF4.4.0-rc5-NC3-32.exe][r1]		| [netCDF4.4.0-rc5-NC3-64.exe][r6]
-netCDF3+DAP		| [netCDF4.4.0-rc5-NC3-DAP-32.exe][r2]	| [netCDF4.4.0-rc5-NC3-DAP-64.exe][r6]
-netCDF4			| [netCDF4.4.0-rc5-NC4-32.exe][r3]		| [netCDF4.4.0-rc5-NC4-64.exe][r7]
-netCDF4+DAP		| [netCDF4.4.0-rc5-NC4-DAP-32.exe][r4]	| [netCDF4.4.0-rc5-NC4-DAP-64.exe][r8]
+netCDF 3		| [netCDF4.4.0-NC3-32.exe][r1]		| [netCDF4.4.0-NC3-64.exe][r6]
+netCDF3+DAP		| [netCDF4.4.0-NC3-DAP-32.exe][r2]	| [netCDF4.4.0-NC3-DAP-64.exe][r6]
+netCDF4			| [netCDF4.4.0-NC4-32.exe][r3]		| [netCDF4.4.0-NC4-64.exe][r7]
+netCDF4+DAP		| [netCDF4.4.0-NC4-DAP-32.exe][r4]	| [netCDF4.4.0-NC4-DAP-64.exe][r8]
 
 # Using the netCDF-C Libraries with Visual Studio {#msvc-using}
 
@@ -60,11 +60,11 @@ When installed, the netCDF libraries are placed in the specified locations, alon
 1. When building the netCDF-C libraries with netCDF4 support, using the `Debug` libraries may cause extraneous warnings. These warnings are related to cross-dll memory management, and appear to be harmless. You can safely ignore them by using the `Release` libraries. [NCF-220]
 
 
-[r1]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-rc5-NC3-32.exe
-[r2]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-rc5-NC3-DAP-32.exe
-[r3]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-rc5-NC4-32.exe
-[r4]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-rc5-NC4-DAP-32.exe
-[r6]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-rc5-NC3-64.exe
-[r6]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-rc5-NC3-DAP-64.exe
-[r7]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-rc5-NC4-64.exe
-[r8]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-rc5-NC4-DAP-64.exe
+[r1]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-NC3-32.exe
+[r2]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-NC3-DAP-32.exe
+[r3]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-NC4-32.exe
+[r4]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-NC4-DAP-32.exe
+[r6]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-NC3-64.exe
+[r6]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-NC3-DAP-64.exe
+[r7]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-NC4-64.exe
+[r8]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.4.0-NC4-DAP-64.exe
diff --git a/examples/C/Makefile.in b/examples/C/Makefile.in
index 6b5fd4b..89dca55 100644
--- a/examples/C/Makefile.in
+++ b/examples/C/Makefile.in
@@ -505,7 +505,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/examples/C/simple_xy_nc4_rd.c b/examples/C/simple_xy_nc4_rd.c
index 6c7ddd2..e3c2bc5 100644
--- a/examples/C/simple_xy_nc4_rd.c
+++ b/examples/C/simple_xy_nc4_rd.c
@@ -22,8 +22,8 @@ http://www.unidata.ucar.edu/netcdf/docs
 #define FILE_NAME "simple_xy_nc4.nc"
 
 /* We are reading 2D data, a 6 x 12 grid. */
-#define NX 60
-#define NY 120
+#define NX 6
+#define NY 12
 
 /* Handle errors by printing an error message and exiting with a
  * non-zero status. */
diff --git a/examples/C/simple_xy_nc4_wr.c b/examples/C/simple_xy_nc4_wr.c
index 60c17c2..42e621c 100644
--- a/examples/C/simple_xy_nc4_wr.c
+++ b/examples/C/simple_xy_nc4_wr.c
@@ -21,8 +21,8 @@ http://www.unidata.ucar.edu/netcdf/docs
 
 /* We are writing 2D data, a 6 x 12 grid. */
 #define NDIMS 2
-#define NX 60
-#define NY 120
+#define NX 6
+#define NY 12
 
 /* Handle errors by printing an error message and exiting with a
  * non-zero status. */
@@ -89,4 +89,3 @@ main()
    printf("*** SUCCESS writing example file simple_xy_nc4.nc!\n");
    return 0;
 }
-
diff --git a/examples/CDL/Makefile.in b/examples/CDL/Makefile.in
index b046497..fe20cca 100644
--- a/examples/CDL/Makefile.in
+++ b/examples/CDL/Makefile.in
@@ -384,7 +384,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/examples/Makefile.in b/examples/Makefile.in
index c2ed9b5..154c835 100644
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -240,7 +240,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/h5_test/Makefile.in b/h5_test/Makefile.in
index 5dd8e65..7f4d23c 100644
--- a/h5_test/Makefile.in
+++ b/h5_test/Makefile.in
@@ -570,7 +570,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/include/Makefile.in b/include/Makefile.in
index a8ab3b4..eb56945 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -238,7 +238,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/include/nc.h b/include/nc.h
index e07a095..4261eb8 100644
--- a/include/nc.h
+++ b/include/nc.h
@@ -19,7 +19,7 @@
     * netcdf-4 files. The ext_ncid contains the ncid for the root
     * group (i.e. group zero). */
 
-/* Common Shared Structure for all Dispatched Objects */ 
+/* Common Shared Structure for all Dispatched Objects */
 typedef struct NC {
 	int ext_ncid;
 	int int_ncid;
@@ -39,7 +39,12 @@ typedef struct NC {
 typedef struct {
 	/* all xdr'd */
 	size_t nchars;
-	char *cp;
+#ifdef __arm__
+  signed char *cp;
+#else
+  char *cp;
+#endif
+
 } NC_string;
 
 /* Define functions that are used across multiple dispatchers */
@@ -51,11 +56,18 @@ 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/netcdf.h b/include/netcdf.h
index 4dd1e94..f298916 100644
--- a/include/netcdf.h
+++ b/include/netcdf.h
@@ -177,8 +177,8 @@ Use this in mode flags for both nc_create() and nc_open(). */
    Note that the name in the contributed code
    NC_FORMAT_64BIT was renamed to NC_FORMAT_CDF2
 */
-#define NC_FORMAT_64BIT           (2) /**< \deprecated Saved for compatibility.  Use NC_FORMAT_64BIT_OFFSET or NC_FORMAT_64BIT_DATA, from netCDF 4.4.0 onwards. */
 #define NC_FORMAT_64BIT_OFFSET    (2)
+#define NC_FORMAT_64BIT           (NC_FORMAT_64BIT_OFFSET) /**< \deprecated Saved for compatibility.  Use NC_FORMAT_64BIT_OFFSET or NC_FORMAT_64BIT_DATA, from netCDF 4.4.0 onwards. */
 #define NC_FORMAT_NETCDF4         (3)
 #define NC_FORMAT_NETCDF4_CLASSIC (4)
 #define NC_FORMAT_64BIT_DATA      (5)
@@ -345,7 +345,12 @@ The specified corner indices were out of range for the rank of the
 specified variable. For example, a negative index or an index that is
 larger than the corresponding dimension length will cause an error. */
 #define	NC_EINVALCOORDS	(-40)
-#define	NC_EMAXDIMS	(-41)	   /**< NC_MAX_DIMS exceeded */
+
+/** NC_MAX_DIMS exceeded. Max number of dimensions exceeded in a
+classic or 64-bit offset file, or an netCDF-4 file with
+::NC_CLASSIC_MODEL on. */
+#define	NC_EMAXDIMS	(-41)
+
 #define	NC_ENAMEINUSE	(-42)	   /**< String match to name in use */
 #define NC_ENOTATT	(-43)	   /**< Attribute not found */
 #define	NC_EMAXATTS	(-44)	   /**< NC_MAX_ATTRS exceeded */
@@ -986,7 +991,6 @@ nc_del_att(int ncid, int varid, const char *name);
 
 /* End _att */
 /* Begin {put,get}_att */
-
 EXTERNL int
 nc_put_att_text(int ncid, int varid, const char *name,
 		size_t len, const char *op);
@@ -995,6 +999,13 @@ EXTERNL int
 nc_get_att_text(int ncid, int varid, const char *name, char *ip);
 
 EXTERNL int
+nc_put_att_string(int ncid, int varid, const char *name,
+		  size_t len, const char **op);
+
+EXTERNL int
+nc_get_att_string(int ncid, int varid, const char *name, char **ip);
+
+EXTERNL int
 nc_put_att_uchar(int ncid, int varid, const char *name, nc_type xtype,
 		 size_t len, const unsigned char *op);
 
@@ -1072,12 +1083,6 @@ EXTERNL int
 nc_get_att_ulonglong(int ncid, int varid, const char *name,
 		     unsigned long long *ip);
 
-EXTERNL int
-nc_put_att_string(int ncid, int varid, const char *name,
-		  size_t len, const char **op);
-
-EXTERNL int
-nc_get_att_string(int ncid, int varid, const char *name, char **ip);
 
 /* End {put,get}_att */
 /* Begin _var */
diff --git a/include/onstack.h b/include/onstack.h
index 28414eb..a85e00b 100644
--- a/include/onstack.h
+++ b/include/onstack.h
@@ -11,15 +11,15 @@
  * "allocate" arrays on the stack where possible.
  * (Where not possible, malloc and free are used.)
  *
- * The macro ALLOC_ONSTACK(name, type, nelems) is used to declare 
+ * The macro ALLOC_ONSTACK(name, type, nelems) is used to declare
  * an array of 'type' named 'name' which is 'nelems' long.
  * FREE_ONSTACK(name) is placed at the end of the scope of 'name'
  * to call 'free' if necessary.
- * 
+ *
  * The macro ALLOC_ONSTACK wraps a call to alloca() on most systems.
  */
 
-#ifdef _MSC_VER 
+#ifdef _WIN32
 #ifdef HAVE_MALLOC_H
 #undef HAVE_ALLOCA
 #define HAVE_ALLOCA 1
@@ -80,5 +80,5 @@
 	free(name)
 
 #endif
-	
+
 #endif /* _ONSTACK_H_ */
diff --git a/libdap2/Makefile.in b/libdap2/Makefile.in
index abef9f7..e487192 100644
--- a/libdap2/Makefile.in
+++ b/libdap2/Makefile.in
@@ -264,7 +264,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/libdap2/ncd2dispatch.c b/libdap2/ncd2dispatch.c
index b33f211..66c7bc9 100644
--- a/libdap2/ncd2dispatch.c
+++ b/libdap2/ncd2dispatch.c
@@ -1160,19 +1160,21 @@ fprintf(stderr,"conflict: %s[%lu] %s[%lu]\n",
     /* Verify unique and defined names for dimensions*/
     for(i=0;i<nclistlength(basedims);i++) {
 	CDFnode* dim1 = (CDFnode*)nclistget(basedims,i);
+        CDFnode* dim2 = NULL;
 	if(dim1->dim.basedim != NULL) PANIC1("nonbase basedim: %s\n",dim1->ncbasename);
 	if(dim1->ncbasename == NULL || dim1->ncfullname == NULL)
 	    PANIC1("missing dim names: %s",dim1->ocname);
 	/* search backward so we can delete duplicates */
 	for(j=nclistlength(basedims)-1;j>i;j--) {
-	    CDFnode* dim2 = (CDFnode*)nclistget(basedims,j);
-	    if(strcmp(dim1->ncfullname,dim2->ncfullname)==0) {
+      if(!dim1->ncfullname) continue;
+      dim2 = (CDFnode*)nclistget(basedims,j);
+      if(strcmp(dim1->ncfullname,dim2->ncfullname)==0) {
 		/* complain and suppress one of them */
 		fprintf(stderr,"duplicate dim names: %s[%lu] %s[%lu]\n",
-			dim1->ncfullname,(unsigned long)dim1->dim.declsize,
-			dim2->ncfullname,(unsigned long)dim2->dim.declsize);
+                dim1->ncfullname,(unsigned long)dim1->dim.declsize,
+                dim2->ncfullname,(unsigned long)dim2->dim.declsize);
 		nclistremove(basedims,j);
-	    }
+      }
 	}
     }
 
diff --git a/libdispatch/Makefile.in b/libdispatch/Makefile.in
index edf9956..6d28941 100644
--- a/libdispatch/Makefile.in
+++ b/libdispatch/Makefile.in
@@ -287,7 +287,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/libdispatch/dattget.c b/libdispatch/dattget.c
index 4f79e8c..a6967e2 100644
--- a/libdispatch/dattget.c
+++ b/libdispatch/dattget.c
@@ -23,7 +23,7 @@ be used to get attributes of user-defined type. We recommend that they
 type safe versions of this function be used where possible.
 
 \param ncid NetCDF or group ID, from a previous call to nc_open(),
-nc_create(), nc_def_grp(), or associated inquiry functions such as 
+nc_create(), nc_def_grp(), or associated inquiry functions such as
 nc_inq_ncid().
 
 \param varid Variable ID of the attribute's variable, or ::NC_GLOBAL
@@ -36,6 +36,9 @@ elements of the vector of attribute values are returned, so you must
 allocate enough space to hold them. Before using the value as a C
 string, make sure it is null-terminated. Call nc_inq_attlen() first to
 find out the length of the attribute.
+
+\note See documentation for nc_get_att_string() regarding a special case where memory must be explicitly released.
+
 */
 int
 nc_get_att(int ncid, int varid, const char *name, void *value)
@@ -53,7 +56,7 @@ nc_get_att(int ncid, int varid, const char *name, void *value)
 
    return ncp->dispatch->get_att(ncid, varid, name, value, xtype);
 }
-/*! \} */ 
+/*! \} */
 
 /*!
 \ingroup attributes
@@ -67,7 +70,7 @@ file is opened with nc_open(). Getting an attribute copies the value
 from the in-memory store, and does not incure any file I/O penalties.
 
 \param ncid NetCDF or group ID, from a previous call to nc_open(),
-nc_create(), nc_def_grp(), or associated inquiry functions such as 
+nc_create(), nc_def_grp(), or associated inquiry functions such as
 nc_inq_ncid().
 
 \param varid Variable ID of the attribute's variable, or ::NC_GLOBAL
@@ -96,14 +99,14 @@ the length of the attributes.
 \code
      #include <netcdf.h>
         ...
-     int  status;         
-     int  ncid;           
-     int  rh_id;          
-     int  vr_len, t_len;  
-     double *vr_val;      
-     char *title;         
+     int  status;
+     int  ncid;
+     int  rh_id;
+     int  vr_len, t_len;
+     double *vr_val;
+     char *title;
      extern char *malloc()
-     
+
         ...
      status = nc_open("foo.nc", NC_NOWRITE, &ncid);
      if (status != NC_NOERR) handle_error(status);
@@ -115,19 +118,20 @@ the length of the attributes.
      if (status != NC_NOERR) handle_error(status);
      status = nc_inq_attlen (ncid, NC_GLOBAL, "title", &t_len);
      if (status != NC_NOERR) handle_error(status);
-     
+
      vr_val = (double *) malloc(vr_len * sizeof(double));
-     title = (char *) malloc(t_len + 1); 
-     
+     title = (char *) malloc(t_len + 1);
+
      status = nc_get_att_double(ncid, rh_id, "valid_range", vr_val);
      if (status != NC_NOERR) handle_error(status);
      status = nc_get_att_text(ncid, NC_GLOBAL, "title", title);
      if (status != NC_NOERR) handle_error(status);
-     title[t_len] = '\0';  
+     title[t_len] = '\0';
         ...
 \endcode
 */
 /*! \{ */
+
 int
 nc_get_att_text(int ncid, int varid, const char *name, char *value)
 {
@@ -244,13 +248,88 @@ nc_get_att_ulonglong(int ncid, int varid, const char *name, unsigned long long *
    if(stat != NC_NOERR) return stat;
    return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UINT64);
 }
+/*! \} */
+
+/*!
+\ingroup attributes
+Get a variable-length string attribute.
+
+This function gets an attribute from netCDF file. Thhe nc_get_att() function works with any type of data including user defined types, but this function will retrieve attributes which are of type variable-length string.
+
+\note Note that unlike most other nc_get_att functions, nc_get_att_string() allocates a chunk of memory which is returned to the calling function.  This chunk of memory must be specifically deallocated with nc_free_string() to avoid any memory leaks.  Also note that you must still preallocate the memory needed for the array of pointers passed to nc_get_att_string().
+
+\param ncid NetCDF or group ID, from a previous call to nc_open(),
+nc_create(), nc_def_grp(), or associated inquiry functions such as
+nc_inq_ncid().
+
+\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL
+for a global attribute.
+
+\param name Attribute \ref object_name.
+
+\param value Pointer to location for returned attribute value(s). All
+elements of the vector of attribute values are returned, so you must
+allocate enough space to hold them. If you don't know how much
+space to reserve, call nc_inq_attlen() first to find out the length of
+the attribute.
+
+\section nc_get_att_string_example Example
+
+\code{.c}
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <netcdf.h>
+
+void check(int stat) {
+  if (stat != NC_NOERR) {
+    printf("NetCDF error: %s\n", nc_strerror(stat));
+    exit(1);
+  }
+}
+
+int main(int argc, char ** argv) {
+  int stat = 0;
+
+  int ncid = 0;
+  stat = nc_open("test.nc", NC_NOWRITE, &ncid); check(stat);
+
+  int varid = 0;
+  stat = nc_inq_varid(ncid, "variable", &varid); check(stat);
+
+  size_t attlen = 0;
+  stat = nc_inq_attlen(ncid, varid, "attribute", &attlen); check(stat);
+
+  char **string_attr = (char**)malloc(attlen * sizeof(char*));
+  memset(string_attr, 0, attlen * sizeof(char*));
+
+  stat = nc_get_att_string(ncid, varid, "attribute", string_attr); check(stat);
+
+  for (size_t k = 0; k < attlen; ++k) {
+    printf("variable:attribute[%d] = %s\n", k, string_attr[k]);
+  }
+
+  stat = nc_free_string(attlen, string_attr); check(stat);
+
+  free(string_attr);
+
+  stat = nc_close(ncid); check(stat);
+
+  return 0;
+}
+\endcode
+
+
+*/
 
 int
 nc_get_att_string(int ncid, int varid, const char *name, char **value)
+
 {
     NC *ncp;
     int stat = NC_check_id(ncid, &ncp);
     if(stat != NC_NOERR) return stat;
     return ncp->dispatch->get_att(ncid,varid,name,(void*)value, NC_STRING);
 }
-/*! \} */ 
+/*! \} */
diff --git a/libdispatch/dattput.c b/libdispatch/dattput.c
index 272d1f6..712375d 100644
--- a/libdispatch/dattput.c
+++ b/libdispatch/dattput.c
@@ -23,7 +23,7 @@ available in netCDF-4/HDF5 files, when ::NC_CLASSIC_MODEL has not been
 used in nc_create().
 
 \param ncid NetCDF or group ID, from a previous call to nc_open(),
-nc_create(), nc_def_grp(), or associated inquiry functions such as 
+nc_create(), nc_def_grp(), or associated inquiry functions such as
 nc_inq_ncid().
 
 \param varid Variable ID of the variable to which the attribute will
@@ -44,6 +44,8 @@ apply.
 \returns ::NC_ELATEFILL Fill values must be written while the file
 is still in initial define mode.
 */
+
+
 int
 nc_put_att_string(int ncid, int varid, const char *name,
 		  size_t len, const char** value)
@@ -51,7 +53,7 @@ nc_put_att_string(int ncid, int varid, const char *name,
     NC* ncp;
     int stat = NC_check_id(ncid, &ncp);
     if(stat != NC_NOERR) return stat;
-    return ncp->dispatch->put_att(ncid, varid, name, NC_STRING, 
+    return ncp->dispatch->put_att(ncid, varid, name, NC_STRING,
 				  len, (void*)value, NC_STRING);
 }
 
@@ -61,7 +63,7 @@ Write a text attribute.
 
 Add or change a text attribute. If this attribute is new,
 or if the space required to store the attribute is greater than
-before, the netCDF dataset must be in define mode.  
+before, the netCDF dataset must be in define mode.
 
 Although it's possible to create attributes of all types, text and
 double attributes are adequate for most purposes.
@@ -71,7 +73,7 @@ including user-defined types. We recommend using the type safe
 versions of this function whenever possible.
 
 \param ncid NetCDF or group ID, from a previous call to nc_open(),
-nc_create(), nc_def_grp(), or associated inquiry functions such as 
+nc_create(), nc_def_grp(), or associated inquiry functions such as
 nc_inq_ncid().
 
 \param varid Variable ID of the variable to which the attribute will
@@ -106,16 +108,16 @@ netCDF dataset named foo.nc:
 \code
      #include <netcdf.h>
         ...
-     int  status;        
-     int  ncid;          
-     int  rh_id;         
+     int  status;
+     int  ncid;
+     int  rh_id;
      static double rh_range[] = {0.0, 100.0};
      static char title[] = "example netCDF dataset";
         ...
      status = nc_open("foo.nc", NC_WRITE, &ncid);
      if (status != NC_NOERR) handle_error(status);
         ...
-     status = nc_redef(ncid);                
+     status = nc_redef(ncid);
      if (status != NC_NOERR) handle_error(status);
      status = nc_inq_varid (ncid, "rh", &rh_id);
      if (status != NC_NOERR) handle_error(status);
@@ -127,22 +129,23 @@ netCDF dataset named foo.nc:
                                strlen(title), title)
      if (status != NC_NOERR) handle_error(status);
         ...
-     status = nc_enddef(ncid);               
+     status = nc_enddef(ncid);
      if (status != NC_NOERR) handle_error(status);
 \endcode
 */
-int
-nc_put_att_text(int ncid, int varid, const char *name,
+
+
+int nc_put_att_text(int ncid, int varid, const char *name,
 		size_t len, const char *value)
 {
    NC* ncp;
    int stat = NC_check_id(ncid, &ncp);
    if(stat != NC_NOERR) return stat;
-   return ncp->dispatch->put_att(ncid, varid, name, NC_CHAR, len, 
+   return ncp->dispatch->put_att(ncid, varid, name, NC_CHAR, len,
 				 (void *)value, NC_CHAR);
 }
 
-/*! \} */ 
+/*! \} */
 /*!
 \ingroup attributes
 Write an attribute.
@@ -150,7 +153,7 @@ Write an attribute.
 The function nc_put_att_ type adds or changes a variable attribute or
 global attribute of an open netCDF dataset. If this attribute is new,
 or if the space required to store the attribute is greater than
-before, the netCDF dataset must be in define mode.  
+before, the netCDF dataset must be in define mode.
 
 With netCDF-4 files, nc_put_att will notice if you are writing a
 _FillValue attribute, and will tell the HDF5 layer to use the
@@ -163,7 +166,7 @@ Although it's possible to create attributes of all types, text and
 double attributes are adequate for most purposes.
 
 \param ncid NetCDF or group ID, from a previous call to nc_open(),
-nc_create(), nc_def_grp(), or associated inquiry functions such as 
+nc_create(), nc_def_grp(), or associated inquiry functions such as
 nc_inq_ncid().
 
 \param varid Variable ID of the variable to which the attribute will
@@ -196,16 +199,16 @@ netCDF dataset named foo.nc:
 \code
      #include <netcdf.h>
         ...
-     int  status;        
-     int  ncid;          
-     int  rh_id;         
+     int  status;
+     int  ncid;
+     int  rh_id;
      static double rh_range[] = {0.0, 100.0};
      static char title[] = "example netCDF dataset";
         ...
      status = nc_open("foo.nc", NC_WRITE, &ncid);
      if (status != NC_NOERR) handle_error(status);
         ...
-     status = nc_redef(ncid);                
+     status = nc_redef(ncid);
      if (status != NC_NOERR) handle_error(status);
      status = nc_inq_varid (ncid, "rh", &rh_id);
      if (status != NC_NOERR) handle_error(status);
@@ -217,7 +220,7 @@ netCDF dataset named foo.nc:
                                strlen(title), title)
      if (status != NC_NOERR) handle_error(status);
         ...
-     status = nc_enddef(ncid);               
+     status = nc_enddef(ncid);
      if (status != NC_NOERR) handle_error(status);
 \endcode
 */
@@ -229,7 +232,7 @@ nc_put_att(int ncid, int varid, const char *name, nc_type xtype,
    NC* ncp;
    int stat = NC_check_id(ncid, &ncp);
    if(stat != NC_NOERR) return stat;
-   return ncp->dispatch->put_att(ncid, varid, name, xtype, len, 
+   return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
 				 value, xtype);
 }
 
@@ -240,7 +243,7 @@ nc_put_att_schar(int ncid, int varid, const char *name,
    NC *ncp;
    int stat = NC_check_id(ncid, &ncp);
    if(stat != NC_NOERR) return stat;
-   return ncp->dispatch->put_att(ncid, varid, name, xtype, len, 
+   return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
 				 (void *)value, NC_BYTE);
 }
 
@@ -262,7 +265,7 @@ nc_put_att_short(int ncid, int varid, const char *name,
    NC* ncp;
    int stat = NC_check_id(ncid, &ncp);
    if(stat != NC_NOERR) return stat;
-   return ncp->dispatch->put_att(ncid, varid, name, xtype, len, 
+   return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
 				 (void *)value, NC_SHORT);
 }
 
@@ -345,7 +348,7 @@ nc_put_att_uint(int ncid, int varid, const char *name,
 
 int
 nc_put_att_longlong(int ncid, int varid, const char *name,
-		    nc_type xtype, size_t len, 
+		    nc_type xtype, size_t len,
 		    const long long *value)
 {
    NC* ncp;
@@ -357,7 +360,7 @@ nc_put_att_longlong(int ncid, int varid, const char *name,
 
 int
 nc_put_att_ulonglong(int ncid, int varid, const char *name,
-		     nc_type xtype, size_t len, 
+		     nc_type xtype, size_t len,
 		     const unsigned long long *value)
 {
    NC* ncp;
@@ -366,4 +369,3 @@ nc_put_att_ulonglong(int ncid, int varid, const char *name,
    return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
 				 (void *)value, NC_UINT64);
 }
-
diff --git a/libdispatch/dstring.c b/libdispatch/dstring.c
index 32f21d2..d251fe4 100644
--- a/libdispatch/dstring.c
+++ b/libdispatch/dstring.c
@@ -35,7 +35,7 @@ free_NC_string(NC_string *ncstrp)
 }
 
 
-static int 
+static int
 nextUTF8(const char* cp)
 {
     /*  The goal here is to recognize the length of each
@@ -54,15 +54,15 @@ nextUTF8(const char* cp)
                  | (\xF0[\x90-\xBF][\x80-\xBF][\x80-\xBF])        \
                  | ([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]) \
                  | (\xF4[\x80-\x8F][\x80-\xBF][\x80-\xBF])        \
-        
+
         2. partially relaxed:
             UTF8 ([\xC0-\xDF][\x80-\xBF])
                  |([\xE0-\xEF][\x80-\xBF][\x80-\xBF])
                  |([\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF])
-        
+
         3. The most relaxed version of UTF8:
             UTF8 ([\xC0-\xD6].)|([\xE0-\xEF]..)|([\xF0-\xF7]...)
-        
+
         We use #2 here.
 
 	The tests are derived from the table at
@@ -72,7 +72,7 @@ nextUTF8(const char* cp)
 /* Define a test macro to test against a range */
 #define RANGE(c,lo,hi) (((uchar)c) >= lo && ((uchar)c) <= hi)
 /* Define a common RANGE */
-#define RANGE0(c) RANGE(c,0x80,0xBF) 
+#define RANGE0(c) RANGE(c,0x80,0xBF)
 
     int ch0;
 
@@ -124,7 +124,7 @@ nextUTF8(const char* cp)
 	        int ch3 = (uchar)cp[3];
 	        if(ch3 != 0 && RANGE0(ch3)) skip = 4;
 	    }
-	}    
+	}
     } else if((ch0 == 0xF4)) {/* plane 16 */
 	int ch1 = (uchar)cp[1];
 	if(ch1 != 0 && RANGE0(ch1)) {
@@ -133,7 +133,7 @@ nextUTF8(const char* cp)
 	        int ch3 = (uchar)cp[3];
 	        if(ch3 != 0 && RANGE0(ch3)) skip = 4;
 	    }
-	}    
+	}
     } else if(RANGE(ch0,0xF1,0xF3) { /* planes 4-15 */
 	int ch1 = (uchar)cp[1];
 	if(ch1 != 0 && RANGE0(ch1)) {
@@ -178,7 +178,7 @@ NC_check_name(const char *name)
 	if(*name == 0		/* empty names disallowed */
 	   || strchr(cp, '/'))	/* '/' can't be in a name */
 		goto fail;
-	
+
 	/* check validity of any UTF-8 */
 	utf8_stat = utf8proc_check((const unsigned char *)name);
 	if (utf8_stat < 0)
@@ -186,15 +186,15 @@ NC_check_name(const char *name)
 
 	/* First char must be [a-z][A-Z][0-9]_ | UTF8 */
 	ch = (uchar)*cp;
-	if(ch <= 0x7f) { 
-	    if(   !('A' <= ch && ch <= 'Z') 
-	       && !('a' <= ch && ch <= 'z') 
+	if(ch <= 0x7f) {
+	    if(   !('A' <= ch && ch <= 'Z')
+	       && !('a' <= ch && ch <= 'z')
 	       && !('0' <= ch && ch <= '9')
 	       && ch != '_' )
 		goto fail;
 	    cp++;
 	} else {
-	    if((skip = nextUTF8(cp)) < 0) 
+	    if((skip = nextUTF8(cp)) < 0)
 		goto fail;
 	    cp += skip;
 	}
@@ -202,7 +202,7 @@ NC_check_name(const char *name)
 	while(*cp != 0) {
 	    ch = (uchar)*cp;
 	    /* handle simple 0x00-0x7f characters here */
-	    if(ch <= 0x7f) { 
+	    if(ch <= 0x7f) {
                 if( ch < ' ' || ch > 0x7E) /* control char or DEL */
 		  goto fail;
 		cp++;
@@ -227,8 +227,14 @@ fail:
  * Formerly
 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;
@@ -236,7 +242,7 @@ new_NC_string(size_t slen, const char *str)
 #if 0
 	sz = _RNDUP(sz, X_ALIGN);
 #endif
-		
+
 	ncstrp = (NC_string *)malloc(sz);
 	if( ncstrp == NULL )
 		return NULL;
@@ -251,7 +257,7 @@ new_NC_string(size_t slen, const char *str)
 		(void) strncpy(ncstrp->cp, str, ncstrp->nchars +1);
 		ncstrp->cp[ncstrp->nchars] = 0;
 	}
-	
+
 	return(ncstrp);
 }
 
@@ -262,9 +268,15 @@ new_NC_string(size_t slen, const char *str)
  * Formerly
 NC_re_string()
  */
-int
-set_NC_string(NC_string *ncstrp, const char *str)
-{
+
+#ifdef __arm__
+ int
+   set_NC_string(NC_string *ncstrp, const signed char *str)
+#else
+ int
+   set_NC_string(NC_string *ncstrp, const char *str)
+#endif
+ {
 	size_t slen;
 
 	assert(str != NULL && *str != 0);
diff --git a/libdispatch/dvar.c b/libdispatch/dvar.c
index 021f6a6..a273a03 100644
--- a/libdispatch/dvar.c
+++ b/libdispatch/dvar.c
@@ -346,13 +346,24 @@ NC_inq_recvar(int ncid, int varid, int* nrecdimsp, int *is_recdim)
 #ifdef USE_NETCDF4
    {
      int nunlimdims;
-     int unlimids[NC_MAX_DIMS];
+     int *unlimids;
      int recdim;
-     status = nc_inq_unlimdims(ncid, &nunlimdims, unlimids); /* for group or file, not variable */
+     status = nc_inq_unlimdims(ncid, &nunlimdims, NULL); /* for group or file, not variable */
      if(status != NC_NOERR) return status;
      if(nunlimdims == 0) return status;
+
+     if (!(unlimids = malloc(nunlimdims * sizeof(int))))
+       return NC_ENOMEM;
+     status = nc_inq_unlimdims(ncid, &nunlimdims, unlimids); /* for group or file, not variable */
+     if(status != NC_NOERR) {
+       free(unlimids);
+       return status;
+     }
      status = nc_inq_vardimid(ncid, varid, dimset);
-     if(status != NC_NOERR) return status;
+     if(status != NC_NOERR) {
+       free(unlimids);
+       return status;
+     }
      for (dim = 0; dim < nvardims; dim++) { /* netCDF-4 rec dims need not be first dim for a rec var */
        for(recdim = 0; recdim < nunlimdims; recdim++) {
 	 if(dimset[dim] == unlimids[recdim]) {
@@ -361,6 +372,7 @@ NC_inq_recvar(int ncid, int varid, int* nrecdimsp, int *is_recdim)
 	 }		
        }
      }
+     free(unlimids);
    }
 #else
    status = nc_inq_vardimid(ncid, varid, dimset);
diff --git a/liblib/Makefile.am b/liblib/Makefile.am
index be53dab..b24664f 100755
--- a/liblib/Makefile.am
+++ b/liblib/Makefile.am
@@ -19,7 +19,7 @@ lib_LTLIBRARIES = libnetcdf.la
 # for information regarding incrementing `-version-info`.
 ##
 
-libnetcdf_la_LDFLAGS = -version-info 10:0:3 ${NOUNDEFINED}
+libnetcdf_la_LDFLAGS = -version-info 11:0:0 ${NOUNDEFINED}
 
 libnetcdf_la_CPPFLAGS = ${AM_CPPFLAGS}
 libnetcdf_la_LIBADD =
@@ -68,4 +68,4 @@ endif #USE_NETCDF4
 
 # We need at least one source file
 libnetcdf_la_SOURCES = nc_initialize.c
-EXTRA_DIST=CMakeLists.txt 
+EXTRA_DIST=CMakeLists.txt
diff --git a/liblib/Makefile.in b/liblib/Makefile.in
index 3897af4..d92ea97 100644
--- a/liblib/Makefile.in
+++ b/liblib/Makefile.in
@@ -298,7 +298,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
@@ -429,7 +428,7 @@ lib_LTLIBRARIES = libnetcdf.la
 # Note: version-info of "9:0:2" results in soname of libnetcdf.so.7 -> libnetcdf.so.7.2.0
 # See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning
 # for information regarding incrementing `-version-info`.
-libnetcdf_la_LDFLAGS = -version-info 10:0:3 ${NOUNDEFINED} \
+libnetcdf_la_LDFLAGS = -version-info 11:0:0 ${NOUNDEFINED} \
 	$(am__append_3)
 libnetcdf_la_CPPFLAGS = ${AM_CPPFLAGS} $(am__append_4)
 
@@ -446,7 +445,7 @@ CLEANFILES =
 
 # We need at least one source file
 libnetcdf_la_SOURCES = nc_initialize.c
-EXTRA_DIST = CMakeLists.txt 
+EXTRA_DIST = CMakeLists.txt
 all: all-am
 
 .SUFFIXES:
diff --git a/libnetcdf.settings.in b/libnetcdf.settings.in
index 32f565e..5d7f5e0 100644
--- a/libnetcdf.settings.in
+++ b/libnetcdf.settings.in
@@ -25,13 +25,10 @@ Extra libraries:	@LIBS@
 # Features
 --------
 NetCDF-2 API:		@HAS_NC2@
-NetCDF-4 API:		@HAS_NC4@
-CDF-5 Support:		yes
 HDF4 Support:		@HAS_HDF4@
-HDF5 Support:		@HAS_HDF5@
-HDF5/SZIP Support:      @HAS_SZIP@
-PNetCDF Support:	@HAS_PNETCDF@
+NetCDF-4 API:		@HAS_NC4@
 NC-4 Parallel Support:	@HAS_PARALLEL4@
+PNetCDF Support:	@HAS_PNETCDF@
 DAP Support:		@HAS_DAP@
 Diskless Support:	@HAS_DISKLESS@
 MMap Support:		@HAS_MMAP@
diff --git a/libsrc/Makefile.in b/libsrc/Makefile.in
index bb29fcd..c26efaf 100644
--- a/libsrc/Makefile.in
+++ b/libsrc/Makefile.in
@@ -303,7 +303,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/libsrc/dim.c b/libsrc/dim.c
index 890d4d8..2386ee8 100644
--- a/libsrc/dim.c
+++ b/libsrc/dim.c
@@ -339,12 +339,13 @@ NC3_def_dim(int ncid, const char *name, size_t size, int *dimidp)
 	if(status != NC_NOERR)
 		return status;
 
-	if ((ncp->flags & NC_64BIT_OFFSET) && sizeof(off_t) > 4) {
-	    /* CDF2 format and LFS */
-	    if(size > X_UINT_MAX - 3) /* "- 3" handles rounded-up size */
+	if(ncp->flags & NC_64BIT_DATA) {/*CDF-5*/
+	    if((sizeof(size_t) > 4) && (size > X_UINT64_MAX - 3)) /* "- 3" handles rounded-up size */
 		return NC_EDIMSIZE;
-	} else {
-	    /* CDF1 format */
+	} else if(ncp->flags & NC_64BIT_OFFSET) {/* CDF2 format and LFS */
+	    if((sizeof(size_t) > 4) && (size > X_UINT_MAX - 3)) /* "- 3" handles rounded-up size */
+		return NC_EDIMSIZE;
+	} else {/*CDF-1*/
 	    if(size > X_INT_MAX - 3)
 		return NC_EDIMSIZE;
 	}
diff --git a/libsrc/ncx.h b/libsrc/ncx.h
index 3e4d0b6..e414e3f 100644
--- a/libsrc/ncx.h
+++ b/libsrc/ncx.h
@@ -16,14 +16,14 @@
  *
  * This started out as a general replacement for ONC XDR,
  * specifically, the xdrmem family of functions.
- * 
+ *
  * We eventually realized that we could write more portable
  * code if we decoupled any association between the 'C' types
  * and the external types. (XDR has this association between the 'C'
  * types and the external representations, like xdr_int() takes
- * an int argument and goes to an external int representation.) 
+ * an int argument and goes to an external int representation.)
  * So, now there is a matrix of functions.
- * 
+ *
  */
 
 #include <config.h> /* output of 'configure' */
@@ -80,7 +80,7 @@
  * For now, netcdf is limited to 32 bit sizes,
  * If compiled with support for "large files", then
  * netcdf will use a 64 bit off_t and it can then write a file
- * using 64 bit offsets. 
+ * using 64 bit offsets.
  *  see also X_SIZE_MAX, X_OFF_MAX below
  */
 #define X_SIZEOF_OFF_T		(sizeof(off_t))
@@ -112,7 +112,7 @@
 #define X_DOUBLE_MAX    1.79769313486230e+308
 #else
 /* scalb(1. - scalb(.5 , -52), 1024) */
-#define X_DOUBLE_MAX	1.7976931348623157e+308 
+#define X_DOUBLE_MAX	1.7976931348623157e+308
 #endif
 #define X_DOUBLE_MIN	(-X_DOUBLE_MAX)
 #define X_DBL_MAX	X_DOUBLE_MAX	/* alias compatible with limits.h */
@@ -124,7 +124,7 @@
 /* Begin ncx_len */
 
 /*
- * ncx_len_xxx() interfaces are defined as macros below, 
+ * ncx_len_xxx() interfaces are defined as macros below,
  * These give the length of an array of nelems of the type.
  * N.B. The 'char' and 'short' interfaces give the X_ALIGNED length.
  */
@@ -165,13 +165,13 @@
 
 /* End ncx_len */
 
-#if __CHAR_UNSIGNED__
+#ifdef __CHAR_UNSIGNED__
 	/* 'char' is unsigned, declare ncbyte as 'signed char' */
 typedef signed char schar;
 
 #else
 	/* 'char' is signed */
-typedef signed char schar;
+typedef char schar;
 
 #endif	/* __CHAR_UNSIGNED__ */
 
@@ -200,7 +200,7 @@ typedef signed char schar;
  *		uint
  *		float
  *		double
- *		longlong == int64 
+ *		longlong == int64
  *	        ulonglong == uint64
  *
  * Not all combinations make sense.
@@ -320,7 +320,7 @@ extern int ncx_put_int_int(void *xp, const int *ip);
  * The `ip' argument should point to an array of `nelems' of
  * internal_type.
  *
- * Range errors (NC_ERANGE) for a individual values in the array 
+ * Range errors (NC_ERANGE) for a individual values in the array
  * DO NOT terminate the array conversion. All elements are converted,
  * with some having undefined values.
  * If any range error occurs, the function returns NC_ERANGE.
@@ -396,7 +396,7 @@ extern int
 ncx_putn_schar_longlong (void **xpp, size_t nelems, const longlong  *ip);
 extern int
 ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip);
- 
+
 extern int
 ncx_pad_putn_schar_schar (void **xpp, size_t nelems, const schar  *ip);
 extern int
@@ -489,7 +489,7 @@ extern int
 ncx_putn_uchar_longlong (void **xpp, size_t nelems, const longlong  *ip);
 extern int
 ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip);
- 
+
 extern int
 ncx_pad_putn_uchar_schar (void **xpp, size_t nelems, const schar  *ip);
 extern int
@@ -582,7 +582,7 @@ extern int
 ncx_putn_short_longlong (void **xpp, size_t nelems, const longlong  *ip);
 extern int
 ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *ip);
- 
+
 extern int
 ncx_pad_putn_short_schar (void **xpp, size_t nelems, const schar  *ip);
 extern int
@@ -675,7 +675,7 @@ extern int
 ncx_putn_ushort_longlong (void **xpp, size_t nelems, const longlong  *ip);
 extern int
 ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *ip);
- 
+
 extern int
 ncx_pad_putn_ushort_schar (void **xpp, size_t nelems, const schar  *ip);
 extern int
@@ -749,7 +749,7 @@ extern int
 ncx_putn_int_longlong (void **xpp, size_t nelems, const longlong  *ip);
 extern int
 ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *ip);
- 
+
 /*---- uint -----------------------------------------------------------------*/
 extern int
 ncx_getn_uint_schar (const void **xpp, size_t nelems, schar  *ip);
@@ -800,7 +800,7 @@ extern int
 ncx_putn_uint_longlong (void **xpp, size_t nelems, const longlong  *ip);
 extern int
 ncx_putn_uint_ulonglong(void **xpp, size_t nelems, const ulonglong *ip);
- 
+
 /*---- float ----------------------------------------------------------------*/
 extern int
 ncx_getn_float_schar (const void **xpp, size_t nelems, schar  *ip);
@@ -847,7 +847,7 @@ extern int
 ncx_putn_float_longlong (void **xpp, size_t nelems, const longlong  *ip);
 extern int
 ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *ip);
- 
+
 /*---- double ---------------------------------------------------------------*/
 extern int
 ncx_getn_double_schar (const void **xpp, size_t nelems, schar  *ip);
@@ -988,13 +988,28 @@ extern int
 ncx_putn_ulonglong_longlong (void **xpp, size_t nelems, const longlong  *ip);
 extern int
 ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *ip);
- 
+
 
 /*
  * Other aggregate conversion functions.
  */
 
 /* 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
@@ -1006,6 +1021,8 @@ 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)
 #define ncx_putn_char_char(xpp, nelems, fillp) ncx_putn_text(xpp, nelems, fillp)
diff --git a/libsrc/ncx.m4 b/libsrc/ncx.m4
index 986ebc6..31b785f 100644
--- a/libsrc/ncx.m4
+++ b/libsrc/ncx.m4
@@ -592,7 +592,7 @@ ncx_put_short_schar(void *xp, const schar *ip)
 		*cp++ = 0xff;
 	else
 		*cp++ = 0;
-	*cp = (uchar)*ip;
+	*cp = (uchar)(signed)*ip;
 	return ENOERR;
 }
 
@@ -648,7 +648,7 @@ get_ix_ushort(const void *xp, ix_ushort *ip)
 		*ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
 	}
 #endif
-	*ip |= *cp; 
+	*ip |= *cp;
 }
 
 static void
@@ -678,7 +678,7 @@ ncx_put_ushort_schar(void *xp, const schar *ip)
 		*cp++ = 0xff;
 	else
 		*cp++ = 0;
-	*cp = (uchar)*ip;
+	*cp = (uchar)(signed)*ip;
         if (*ip < 0) return NC_ERANGE;
 
 	return ENOERR;
@@ -777,7 +777,7 @@ ncx_put_int_schar(void *xp, const schar *ip)
 		*cp++ = 0x00;
 		*cp++ = 0x00;
 	}
-	*cp = (uchar)*ip;
+	*cp = (uchar)(signed)*ip;
 	return ENOERR;
 }
 
@@ -829,7 +829,7 @@ get_ix_uint(const void *xp, ix_uint *ip)
 	*ip = *cp++ << 24;
 	*ip |= (*cp++ << 16);
 	*ip |= (*cp++ << 8);
-	*ip |= *cp; 
+	*ip |= *cp;
 }
 
 static void
@@ -864,7 +864,7 @@ ncx_put_uint_schar(void *xp, const schar *ip)
 	*cp++ = 0x00;
 	*cp++ = 0x00;
 	*cp++ = 0x00;
-	*cp = (uchar)*ip;
+	*cp = (uchar)(signed)*ip;
 
 	if (*ip < 0) return NC_ERANGE;
 
@@ -2109,7 +2109,7 @@ dnl
 define(`NCX_GETN_Byte_Body',dnl
 `dnl
 	(void) memcpy(tp, *xpp, nelems);
-	*xpp = (void *)((char *)(*xpp) + nelems);
+	*xpp = (void *)((schar *)(*xpp) + nelems);
 	return ENOERR;
 ')dnl
 dnl dnl dnl
@@ -2348,7 +2348,7 @@ ncx_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp)
 	{
 		if(*tp > Xmax($1) ifelse(index(`$2',`u'), 0, , `ifelse(index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')'))
 			status = NC_ERANGE;
-		*xp++ = ($1) *tp++;
+		*xp++ = ($1) (signed)*tp++;
 	}
 
 	*xpp = (void *)xp;
@@ -2375,7 +2375,7 @@ ncx_pad_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp)
 	{
 		if(*tp > Xmax($1) ifelse(index(`$2',`u'), 0, , `ifelse(index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')'))
 			status = NC_ERANGE;
-		*xp++ = ($1) *tp++;
+		*xp++ = ($1) (signed) *tp++;
 	}
 
 
@@ -3323,27 +3323,45 @@ 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
 {
 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
 {
 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
 {
 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
 {
 NCX_PAD_PUTN_Byte_Body
 }
diff --git a/libsrc/posixio.c b/libsrc/posixio.c
index 24b52c2..f64915e 100644
--- a/libsrc/posixio.c
+++ b/libsrc/posixio.c
@@ -687,7 +687,11 @@ done:
 	pxp->bf_rflags |= rflags;
 	pxp->bf_refcount++;
 
+#ifndef __CHAR_UNSIGNED__
     *vpp = (void *)((char *)pxp->bf_base + diff);
+#else
+    *vpp = (void *)((signed char*)pxp->bf_base + diff);
+#endif
 	return ENOERR;
 }
 
diff --git a/libsrc/putget.m4 b/libsrc/putget.m4
index 7b0d08b..e351744 100644
--- a/libsrc/putget.m4
+++ b/libsrc/putget.m4
@@ -1165,8 +1165,12 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start,
 
     case CASE(NC_CHAR,NC_CHAR):
     case CASE(NC_CHAR,NC_UBYTE):
-        return getNCvx_char_char(ncp,varp,start,nelems,(char*)value);
-	break;
+#ifndef __CHAR_UNSIGNED__
+       return getNCvx_char_char(ncp,varp,start,nelems,(char*)value);
+#else
+    return getNCvx_schar_schar(ncp,varp,start,nelems,(signed char*)value);
+#endif
+    break;
     case CASE(NC_BYTE,NC_BYTE):
         return getNCvx_schar_schar(ncp,varp,start,nelems,(signed char*)value);
 	break;
@@ -1208,13 +1212,13 @@ readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start,
 	break;
     case CASE(NC_SHORT,NC_INT):
         return getNCvx_short_int(ncp,varp,start,nelems,(int*)value);
-	break; 
+	break;
    case CASE(NC_SHORT,NC_FLOAT):
         return getNCvx_short_float(ncp,varp,start,nelems,(float*)value);
 	break;
     case CASE(NC_SHORT,NC_DOUBLE):
         return getNCvx_short_double(ncp,varp,start,nelems,(double*)value);
-	break;	
+	break;
     case CASE(NC_SHORT,NC_INT64):
         return getNCvx_short_longlong(ncp,varp,start,nelems,(long long*)value);
    	break;
@@ -1818,7 +1822,7 @@ NC3_get_vara(int ncid, int varid,
     int ii;
     size_t iocount;
     size_t memtypelen;
-    char* value = (char*) value0; /* legally allow ptr arithmetic */
+    signed char* value = (signed char*) value0; /* legally allow ptr arithmetic */
     const size_t* edges = edges0; /* so we can modify for special cases */
     size_t modedges[NC_MAX_VAR_DIMS];
 
@@ -1945,7 +1949,7 @@ NC3_put_vara(int ncid, int varid,
     int ii;
     size_t iocount;
     size_t memtypelen;
-    char* value = (char*) value0; /* legally allow ptr arithmetic */
+    signed char* value = (signed char*) value0; /* legally allow ptr arithmetic */
     const size_t* edges = edges0; /* so we can modify for special cases */
     size_t modedges[NC_MAX_VAR_DIMS];
 
diff --git a/libsrc/v1hpg.c b/libsrc/v1hpg.c
index 904ffc6..b4f186b 100644
--- a/libsrc/v1hpg.c
+++ b/libsrc/v1hpg.c
@@ -15,8 +15,8 @@
 /*
  * This module defines the external representation
  * of the "header" of a netcdf version one file and
- * the version two variant that uses 64-bit file 
- * offsets instead of the 32-bit file offsets in version 
+ * the version two variant that uses 64-bit file
+ * offsets instead of the 32-bit file offsets in version
  * one files.
  * For each of the components of the NC structure,
  * There are (static) ncx_len_XXX(), v1h_put_XXX()
@@ -85,15 +85,19 @@ fault_v1hs(v1hs *gsp, size_t extent)
 
 	if(gsp->base != NULL)
 	{
-		const ptrdiff_t incr = (char *)gsp->pos - (char *)gsp->base;
+#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
 		status = rel_v1hs(gsp);
 		if(status)
 			return status;
 		gsp->offset += incr;
 	}
-	
+
 	if(extent > gsp->extent)
-		gsp->extent = extent;	
+		gsp->extent = extent;
 
 	status = ncio_get(gsp->nciop,
 		 	gsp->offset, gsp->extent,
@@ -102,8 +106,12 @@ fault_v1hs(v1hs *gsp, size_t extent)
 		return status;
 
 	gsp->pos = gsp->base;
-	gsp->end = (char *)gsp->base + gsp->extent;
 
+#ifdef __arm__
+	gsp->end = (signed char *)gsp->base + gsp->extent;
+#else
+    gsp->end = (char *)gsp->base + gsp->extent;
+#endif
 	return ENOERR;
 }
 
@@ -120,10 +128,15 @@ fprintf(stderr, "nextread %lu, remaining %lu\n",
 	(unsigned long)nextread,
 	(unsigned long)((char *)gsp->end - (char *)gsp->pos));
 #endif
-
-	if((char *)gsp->pos + nextread <= (char *)gsp->end)
+#ifdef __arm__
+if((signed char *)gsp->pos + nextread <= (signed char *)gsp->end)
+		return ENOERR;
+#else
+ if((char *)gsp->pos + nextread <= (char *)gsp->end)
 		return ENOERR;
-	return fault_v1hs(gsp, nextread);
+#endif
+
+    return fault_v1hs(gsp, nextread);
 }
 
 /* End v1hs */
@@ -179,8 +192,14 @@ v1h_put_nc_type(v1hs *psp, const nc_type *typep)
 	if(status != ENOERR)
 		return status;
 	status =  ncx_put_int_int(psp->pos, &itype);
-	psp->pos = (void *)((char *)psp->pos + X_SIZEOF_INT);
-	return status;
+
+#ifdef __arm__
+	psp->pos = (void *)((signed char *)psp->pos + X_SIZEOF_INT);
+#else
+    psp->pos = (void *)((char *)psp->pos + X_SIZEOF_INT);
+#endif
+
+    return status;
 }
 
 
@@ -193,7 +212,11 @@ v1h_get_nc_type(v1hs *gsp, nc_type *typep)
 	if(status != ENOERR)
 		return status;
 	status =  ncx_get_int_int(gsp->pos, &type);
-	gsp->pos = (void *)((char *)gsp->pos + X_SIZEOF_INT);
+#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 != ENOERR)
 		return status;
 
@@ -230,8 +253,12 @@ v1h_put_NCtype(v1hs *psp, NCtype type)
 	if(status != ENOERR)
 		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);
-	return status;
+#endif
+    return status;
 }
 
 /* Read a NCtype from the header */
@@ -243,8 +270,13 @@ v1h_get_NCtype(v1hs *gsp, NCtype *typep)
 	if(status != ENOERR)
 		return status;
 	status =  ncx_get_int_int(gsp->pos, &type);
-	gsp->pos = (void *)((char *)gsp->pos + X_SIZEOF_INT);
-	if(status != ENOERR)
+
+#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 != ENOERR)
 		return status;
 	/* else */
 	*typep = (NCtype) type;
@@ -266,7 +298,7 @@ ncx_len_NC_string(const NC_string *ncstrp, int version)
 
 	assert(ncstrp != NULL);
 
-	if(ncstrp->nchars != 0) 
+	if(ncstrp->nchars != 0)
 	{
 #if 0
 		assert(ncstrp->nchars % X_ALIGN == 0);
@@ -327,7 +359,7 @@ v1h_get_NC_string(v1hs *gsp, NC_string **ncstrpp)
 	assert(ncstrp->nchars % X_ALIGN == 0);
 	status = check_v1hs(gsp, ncstrp->nchars);
 #else
-	
+
 	status = check_v1hs(gsp, _RNDUP(ncstrp->nchars, X_ALIGN));
 #endif
 	if(status != ENOERR)
@@ -345,7 +377,7 @@ v1h_get_NC_string(v1hs *gsp, NC_string **ncstrpp)
 unwind_alloc:
 	free_NC_string(ncstrp);
 	return status;
-	
+
 }
 
 /* End NC_string */
@@ -517,7 +549,7 @@ v1h_get_NC_dimarray(v1hs *gsp, NC_dimarray *ncap)
 	status = v1h_get_size_t(gsp, &ncap->nelems);
 	if(status != ENOERR)
 		return status;
-	
+
 	if(ncap->nelems == 0)
 		return ENOERR;
 	/* else */
@@ -588,24 +620,29 @@ 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;
 
 	assert(psp->extent % X_ALIGN == 0);
-	
+
 	do {
 		nbytes = MIN(perchunk, remaining);
-	
+
 		status = check_v1hs(psp, nbytes);
 		if(status != ENOERR)
 			return status;
-	
+
 		(void) memcpy(psp->pos, value, nbytes);
 
-		psp->pos = (void *)((char *)psp->pos + 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);
 		value = (void *)((char *)value + nbytes);
-		remaining -= nbytes;
+#endif
+        remaining -= nbytes;
 
-	} while(remaining != 0); 
+	} while(remaining != 0);
 
 	return ENOERR;
 }
@@ -648,22 +685,27 @@ 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;
 
 	do {
 		nget = MIN(perchunk, remaining);
-	
+
 		status = check_v1hs(gsp, nget);
 		if(status != ENOERR)
 			return status;
-	
-		(void) memcpy(value, gsp->pos, nget);
 
-		gsp->pos = (void *)((char *)gsp->pos + nget);
+		(void) memcpy(value, gsp->pos, nget);
+#ifdef __arm__
+		gsp->pos = (void *)((signed char *)gsp->pos + nget);
+		value = (void *)((signed char *)value + nget);
+#else
+        gsp->pos = (void *)((char *)gsp->pos + nget);
 		value = (void *)((char *)value + nget);
-		remaining -= nget;
+#endif
+
+        remaining -= nget;
 
-	} while(remaining != 0); 
+	} while(remaining != 0);
 
 	return ENOERR;
 }
@@ -697,7 +739,7 @@ v1h_get_NC_attr(v1hs *gsp, NC_attr **attrpp)
 		status = NC_ENOMEM;
 		goto unwind_name;
 	}
-	
+
 	status = v1h_get_NC_attrV(gsp, attrp);
 	if(status != ENOERR)
 	{
@@ -808,7 +850,7 @@ v1h_get_NC_attrarray(v1hs *gsp, NC_attrarray *ncap)
 	status = v1h_get_size_t(gsp, &ncap->nelems);
 	if(status != ENOERR)
 		return status;
-	
+
 	if(ncap->nelems == 0)
 		return ENOERR;
 	/* else */
@@ -988,7 +1030,7 @@ v1h_get_NC_var(v1hs *gsp, NC_var **varpp)
 			       &varp->begin, gsp->version == 1 ? 4 : 8);
 	if(status != ENOERR)
 		 goto unwind_alloc;
-	
+
 	*varpp = varp;
 	return ENOERR;
 
@@ -1092,11 +1134,11 @@ v1h_get_NC_vararray(v1hs *gsp, NC_vararray *ncap)
 	status = v1h_get_NCtype(gsp, &type);
 	if(status != ENOERR)
 		return status;
-	
+
 	status = v1h_get_size_t(gsp, &ncap->nelems);
 	if(status != ENOERR)
 		return status;
-	
+
 	if(ncap->nelems == 0)
 		return ENOERR;
 	/* else */
@@ -1153,16 +1195,16 @@ NC_computeshapes(NC3_INFO* ncp)
 
 	if(ncp->vars.nelems == 0)
 		return(0);
-	
+
 	for( /*NADA*/; vpp < end; vpp++)
 	{
 		status = NC_var_shape(*vpp, &ncp->dims);
 		if(status != ENOERR)
 			return(status);
 
-	  	if(IS_RECVAR(*vpp))	
+	  	if(IS_RECVAR(*vpp))
 		{
-	  		if(first_rec == NULL)	
+	  		if(first_rec == NULL)
 				first_rec = *vpp;
 			if((*vpp)->len == UINT32_MAX &&
                            fIsSet(ncp->flags, NC_64BIT_OFFSET)) /* Flag for large last record */
@@ -1229,7 +1271,7 @@ ncx_len_NC(const NC3_INFO* ncp, size_t sizeof_off_t)
 	xlen += ncx_len_NC_dimarray(&ncp->dims, version);
 	xlen += ncx_len_NC_attrarray(&ncp->attrs, version);
 	xlen += ncx_len_NC_vararray(&ncp->vars, sizeof_off_t, version);
-	
+
 	return xlen;
 }
 
@@ -1252,7 +1294,7 @@ ncx_put_NC(const NC3_INFO* ncp, void **xpp, off_t offset, size_t extent)
 	  ps.version = 5;
 	else if (ncp->flags & NC_64BIT_OFFSET)
 	  ps.version = 2;
-	else 
+	else
 	  ps.version = 1;
 
 	if(xpp == NULL)
@@ -1272,7 +1314,7 @@ ncx_put_NC(const NC3_INFO* ncp, void **xpp, off_t offset, size_t extent)
 		}
 		else if(extent > ncp->chunk)
 		    extent = ncp->chunk;
-		
+
 		ps.offset = 0;
 		ps.extent = extent;
 		ps.base = NULL;
@@ -1356,7 +1398,7 @@ nc_get_NC(NC3_INFO* ncp)
 		 */
 	        off_t filesize;
 		size_t extent = ncp->xsz;
-		
+
 		if(extent <= ((fIsSet(ncp->flags, NC_64BIT_DATA))?MIN_NC5_XSZ:MIN_NC3_XSZ))
 		{
 		        status = ncio_filesize(ncp->nciop, &filesize);
@@ -1403,7 +1445,7 @@ nc_get_NC(NC3_INFO* ncp)
 			(const void **)(&gs.pos), sizeof(magic), magic);
 		if(status != ENOERR)
 			goto unwind_get;
-	
+
 		if(memcmp(magic, ncmagic, sizeof(ncmagic)-1) != 0)
 		{
 			status = NC_ENOTNC;
@@ -1429,7 +1471,7 @@ nc_get_NC(NC3_INFO* ncp)
 			goto unwind_get;
 		}
 	}
-	
+
 	{
 	size_t nrecs = 0;
        	if (gs.version == 5) {
@@ -1444,8 +1486,11 @@ nc_get_NC(NC3_INFO* ncp)
 	NC_set_numrecs(ncp, nrecs);
 	}
 
-	assert((char *)gs.pos < (char *)gs.end);
-
+#ifdef __arm__
+	assert((signed char *)gs.pos < (signed char *)gs.end);
+#else
+    assert((char *)gs.pos < (char *)gs.end);
+#endif
 	status = v1h_get_NC_dimarray(&gs, &ncp->dims);
 	if(status != ENOERR)
 		goto unwind_get;
@@ -1457,7 +1502,7 @@ nc_get_NC(NC3_INFO* ncp)
 	status = v1h_get_NC_vararray(&gs, &ncp->vars);
 	if(status != ENOERR)
 		goto unwind_get;
-		
+
 	ncp->xsz = ncx_len_NC(ncp, (gs.version == 1) ? 4 : 8);
 
 	status = NC_computeshapes(ncp);
diff --git a/libsrc4/Makefile.in b/libsrc4/Makefile.in
index 366d18d..cfafb38 100644
--- a/libsrc4/Makefile.in
+++ b/libsrc4/Makefile.in
@@ -249,7 +249,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/libsrc4/nc4var.c b/libsrc4/nc4var.c
index 2d30f51..ac216b9 100644
--- a/libsrc4/nc4var.c
+++ b/libsrc4/nc4var.c
@@ -52,13 +52,13 @@ nc4_reopen_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 #ifdef EXTRA_TESTS
       num_plists++;
 #endif
-      if (H5Pset_chunk_cache(access_pid, var->chunk_cache_nelems, 
-			     var->chunk_cache_size, 
+      if (H5Pset_chunk_cache(access_pid, var->chunk_cache_nelems,
+			     var->chunk_cache_size,
 			     var->chunk_cache_preemption) < 0)
 	 return NC_EHDFERR;
       if (H5Dclose(var->hdf_datasetid) < 0)
 	 return NC_EHDFERR;
-      if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->name, 
+      if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->name,
 					 access_pid)) < 0)
 	 return NC_EHDFERR;
       if (H5Pclose(access_pid) < 0)
@@ -67,17 +67,17 @@ nc4_reopen_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
       num_plists--;
 #endif
    }
-   
+
    return NC_NOERR;
 }
 
 /* Set chunk cache size for a variable. */
 int
-NC4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, 
+NC4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
 			float preemption)
 {
    NC *nc;
-   NC_GRP_INFO_T *grp; 
+   NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
    NC_VAR_INFO_T *var;
    int retval;
@@ -118,7 +118,7 @@ NC4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
 /* Need this version for fortran. Accept negative numbers to leave
  * settings as they are. */
 int
-nc_set_var_chunk_cache_ints(int ncid, int varid, int size, int nelems, 
+nc_set_var_chunk_cache_ints(int ncid, int varid, int size, int nelems,
 			    int preemption)
 {
    size_t real_size = H5D_CHUNK_CACHE_NBYTES_DEFAULT;
@@ -133,18 +133,18 @@ nc_set_var_chunk_cache_ints(int ncid, int varid, int size, int nelems,
 
    if (preemption >= 0)
       real_preemption = preemption / 100.;
-	 
-   return NC4_set_var_chunk_cache(ncid, varid, real_size, real_nelems, 
+
+   return NC4_set_var_chunk_cache(ncid, varid, real_size, real_nelems,
 				 real_preemption);
 }
 
 /* Get chunk cache size for a variable. */
 int
-NC4_get_var_chunk_cache(int ncid, int varid, size_t *sizep, 
+NC4_get_var_chunk_cache(int ncid, int varid, size_t *sizep,
 			size_t *nelemsp, float *preemptionp)
 {
    NC *nc;
-   NC_GRP_INFO_T *grp; 
+   NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
    NC_VAR_INFO_T *var;
    int retval;
@@ -180,17 +180,17 @@ NC4_get_var_chunk_cache(int ncid, int varid, size_t *sizep,
 
 /* Get chunk cache size for a variable. */
 int
-nc_get_var_chunk_cache_ints(int ncid, int varid, int *sizep, 
+nc_get_var_chunk_cache_ints(int ncid, int varid, int *sizep,
 			    int *nelemsp, int *preemptionp)
 {
    size_t real_size, real_nelems;
    float real_preemption;
    int ret;
 
-   if ((ret = NC4_get_var_chunk_cache(ncid, varid, &real_size, 
+   if ((ret = NC4_get_var_chunk_cache(ncid, varid, &real_size,
 				     &real_nelems, &real_preemption)))
       return ret;
-   
+
    if (sizep)
       *sizep = real_size / MEGABYTE;
    if (nelemsp)
@@ -209,7 +209,7 @@ check_chunksizes(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, const size_t *chunksize
    size_t type_len;
    int d;
    int retval;
-   
+
    if ((retval = nc4_get_typelen_mem(grp->nc4_info, var->type_info->nc_typeid, 0, &type_len)))
       return retval;
    if (var->type_info->nc_type_class == NC_VLEN)
@@ -222,7 +222,7 @@ check_chunksizes(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, const size_t *chunksize
 	 return NC_EINVAL;
       dprod *= (double) chunksizes[d];
    }
-   
+
    if (dprod > (double) NC_MAX_UINT)
       return NC_EBADCHUNK;
 
@@ -231,7 +231,7 @@ check_chunksizes(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, const size_t *chunksize
 
 /* Find the default chunk nelems (i.e. length of chunk along each
  * dimension). */
-static int 
+static int
 nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 {
    int d;
@@ -239,7 +239,7 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
    float num_values = 1, num_unlim = 0;
    int retval;
    size_t suggested_size;
-#ifdef LOGGING   
+#ifdef LOGGING
    double total_chunk_size;
 #endif
 
@@ -248,7 +248,7 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
    else
       type_size = var->type_info->size;
 
-#ifdef LOGGING   
+#ifdef LOGGING
    /* Later this will become the total number of bytes in the default
     * chunk. */
    total_chunk_size = (double) type_size;
@@ -259,7 +259,7 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
    for (d = 0; d < var->ndims; d++)
    {
       assert(var->dim[d]);
-      if (! var->dim[d]->unlimited) 
+      if (! var->dim[d]->unlimited)
 	 num_values *= (float)var->dim[d]->len;
       else {
 	  num_unlim++;
@@ -296,7 +296,7 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
    for (d = 0; d < var->ndims; d++)
       if (!var->chunksizes[d])
       {
-	 suggested_size = (pow((double)DEFAULT_CHUNK_SIZE/(num_values * type_size), 
+	 suggested_size = (pow((double)DEFAULT_CHUNK_SIZE/(num_values * type_size),
 			       1.0/(double)(var->ndims - num_unlim)) * var->dim[d]->len - .5);
 	 if (suggested_size > var->dim[d]->len)
 	    suggested_size = var->dim[d]->len;
@@ -305,13 +305,13 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 	      "chunksize %ld", __func__, var->name, d, DEFAULT_CHUNK_SIZE, num_values, type_size, var->chunksizes[d]));
       }
 
-#ifdef LOGGING   
+#ifdef LOGGING
    /* Find total chunk size. */
    for (d = 0; d < var->ndims; d++)
        total_chunk_size *= (double) var->chunksizes[d];
    LOG((4, "total_chunk_size %f", total_chunk_size));
 #endif
-   
+
    /* But did this result in a chunk that is too big? */
    retval = check_chunksizes(grp, var, var->chunksizes);
    if (retval)
@@ -346,8 +346,8 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 
 /* This is called when a new netCDF-4 variable is defined. Break it
  * down! */
-static int 
-nc_def_var_nc4(int ncid, const char *name, nc_type xtype, 
+static int
+nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
                int ndims, const int *dimidsp, int *varidp)
 {
    NC_GRP_INFO_T *grp;
@@ -381,7 +381,7 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
    /* Not a Type is, well, not a type.*/
    if (xtype == NC_NAT)
       BAIL(NC_EBADTYPE);
-   
+
    /* For classic files, only classic types are allowed. */
    if (h5->cmode & NC_CLASSIC_MODEL && xtype > NC_DOUBLE)
       BAIL(NC_ESTRICTNC3);
@@ -428,7 +428,7 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
    var->varid = grp->nvars++;
    var->ndims = ndims;
    var->is_new_var = NC_TRUE;
-   
+
    /* If this is a user-defined type, there is a type_info struct with
     * all the type information. For atomic types, fake up a type_info
     * struct. */
@@ -438,13 +438,13 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
 	 BAIL(NC_ENOMEM);
       type_info->nc_typeid = xtype;
       type_info->endianness = NC_ENDIAN_NATIVE;
-      if ((retval = nc4_get_hdf_typeid(h5, xtype, &type_info->hdf_typeid, 
+      if ((retval = nc4_get_hdf_typeid(h5, xtype, &type_info->hdf_typeid,
 				       type_info->endianness)))
 	 BAIL(retval);
-      if ((type_info->native_hdf_typeid = H5Tget_native_type(type_info->hdf_typeid, 
+      if ((type_info->native_hdf_typeid = H5Tget_native_type(type_info->hdf_typeid,
 							      H5T_DIR_DEFAULT)) < 0)
          BAIL(NC_EHDFERR);
-      if ((retval = nc4_get_typelen_mem(h5, type_info->nc_typeid, 0, 
+      if ((retval = nc4_get_typelen_mem(h5, type_info->nc_typeid, 0,
 					&type_info->size)))
 	 BAIL(retval);
 
@@ -571,17 +571,17 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
     * because the dimension will cause a HDF5 dataset to be created,
     * and this var has the same name. */
    for (dim = grp->dim; dim; dim = dim->l.next)
-      if (!strcmp(dim->name, norm_name) && 
+      if (!strcmp(dim->name, norm_name) &&
 	  (!var->ndims || dimidsp[0] != dim->dimid))
       {
 	 /* Set a different hdf5 name for this variable to avoid name
 	  * clash. */
 	 if (strlen(norm_name) + strlen(NON_COORD_PREPEND) > NC_MAX_NAME)
 	    BAIL(NC_EMAXNAME);
-	 if (!(var->hdf5_name = malloc((strlen(NON_COORD_PREPEND) + 
+	 if (!(var->hdf5_name = malloc((strlen(NON_COORD_PREPEND) +
 					strlen(norm_name) + 1) * sizeof(char))))
 	    BAIL(NC_ENOMEM);
-	 
+
 	 sprintf(var->hdf5_name, "%s%s", NON_COORD_PREPEND, norm_name);
       }
 
@@ -609,7 +609,7 @@ exit:
 /* Create a new variable to hold user data. This is what it's all
  * about baby! */
 int
-NC4_def_var(int ncid, const char *name, nc_type xtype, int ndims, 
+NC4_def_var(int ncid, const char *name, nc_type xtype, int ndims,
            const int *dimidsp, int *varidp)
 {
    NC *nc;
@@ -632,7 +632,7 @@ NC4_def_var(int ncid, const char *name, nc_type xtype, int ndims,
    {
       int ret;
 
-      ret = ncmpi_def_var(nc->int_ncid, name, xtype, ndims, 
+      ret = ncmpi_def_var(nc->int_ncid, name, xtype, ndims,
 			  dimidsp, varidp);
       h5->pnetcdf_ndims[*varidp] = ndims;
       return ret;
@@ -646,16 +646,16 @@ NC4_def_var(int ncid, const char *name, nc_type xtype, int ndims,
 /* Get all the information about a variable. Pass NULL for whatever
  * you don't care about. This is an internal function, not exposed to
  * the user. */
-int 
-NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep, 
-               int *ndimsp, int *dimidsp, int *nattsp, 
+int
+NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
+               int *ndimsp, int *dimidsp, int *nattsp,
                int *shufflep, int *deflatep, int *deflate_levelp,
-               int *fletcher32p, int *contiguousp, size_t *chunksizesp, 
-               int *no_fill, void *fill_valuep, int *endiannessp, 
+               int *fletcher32p, int *contiguousp, size_t *chunksizesp,
+               int *no_fill, void *fill_valuep, int *endiannessp,
 	       int *options_maskp, int *pixels_per_blockp)
 {
    NC *nc;
-   NC_GRP_INFO_T *grp; 
+   NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
    NC_VAR_INFO_T *var;
    NC_ATT_INFO_T *att;
@@ -675,7 +675,7 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
 #if 0 /*def USE_PNETCDF*/
    /* Take care of files created/opened with parallel-netcdf library. */
    if (h5->pnetcdf_file)
-      return ncmpi_inq_var(nc->int_ncid, varid, name, xtypep, ndimsp, 
+      return ncmpi_inq_var(nc->int_ncid, varid, name, xtypep, ndimsp,
 			   dimidsp, nattsp);
 #endif /* USE_PNETCDF */
 
@@ -697,11 +697,11 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
    for (var = grp->var; var; var = var->l.next)
       if (var->varid == varid)
          break;
-   
+
    /* Oh no! Maybe we couldn't find it (*sob*)! */
    if (!var)
       return NC_ENOTVAR;
-   
+
    /* Copy the data to the user's data buffers. */
    if (name)
       strcpy(name, var->name);
@@ -718,7 +718,7 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
          natts++;
       *nattsp = natts;
    }
-   
+
    /* Chunking stuff. */
    if (!var->contiguous && chunksizesp)
       for (d = 0; d < var->ndims; d++)
@@ -756,19 +756,22 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
    if (!var->no_fill && fill_valuep)
    {
       /* Do we have a fill value for this var? */
-      if (var->fill_value)
-      {
+     if (var->fill_value)
+       {
          if (var->type_info->nc_type_class == NC_STRING)
-         {
-            if (!(fill_valuep = calloc(1, sizeof(char *))))
-               return NC_ENOMEM;
-            if (*(char **)var->fill_value)
+           {
+             if (*(char **)var->fill_value) {
+
+               if (!(fill_valuep = calloc(1, sizeof(char *))))
+                 return NC_ENOMEM;
+
                if (!(*(char **)fill_valuep = strdup(*(char **)var->fill_value)))
-               {
+                 {
                    free(fill_valuep);
-                  return NC_ENOMEM;
-               }
-         }
+                   return NC_ENOMEM;
+                 }
+             }
+           }
          else {
              assert(var->type_info->size);
              memcpy(fill_valuep, var->fill_value, var->type_info->size);
@@ -780,7 +783,7 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
          {
             if (!(fill_valuep = calloc(1, sizeof(char *))))
                return NC_ENOMEM;
-	    
+
             if ((retval = nc4_get_default_fill_value(var->type_info, (char **)fill_valuep)))
             {
                free(fill_valuep);
@@ -809,13 +812,13 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
    internal function, deliberately hidden from the user so that we can
    change the prototype of this functions without changing the API. */
 static int
-nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate, 
-		 int *deflate_level, int *fletcher32, int *contiguous, 
-		 const size_t *chunksizes, int *no_fill, 
+nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
+		 int *deflate_level, int *fletcher32, int *contiguous,
+		 const size_t *chunksizes, int *no_fill,
                  const void *fill_value, int *endianness)
 {
    NC *nc;
-   NC_GRP_INFO_T *grp; 
+   NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
    NC_VAR_INFO_T *var;
    NC_DIM_INFO_T *dim;
@@ -844,14 +847,14 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
    for (var = grp->var; var; var = var->l.next)
       if (var->varid == varid)
          break;
-   
+
    /* Oh no! Maybe we couldn't find it (*sob*)! */
    if (!var)
       return NC_ENOTVAR;
 
    /* Can't turn on contiguous and deflate/fletcher32/szip. */
    if (contiguous)
-      if ((*contiguous != NC_CHUNKED && deflate) || 
+      if ((*contiguous != NC_CHUNKED && deflate) ||
 	  (*contiguous != NC_CHUNKED && fletcher32))
 	 return NC_EINVAL;
 
@@ -862,8 +865,8 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
 
    /* Check compression options. */
    if (deflate && !deflate_level)
-      return NC_EINVAL;      
-       
+      return NC_EINVAL;
+
    /* Valid deflate level? */
    if (deflate && deflate_level)
    {
@@ -898,7 +901,7 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
       var->fletcher32 = *fletcher32;
       var->contiguous = NC_FALSE;
    }
-   
+
    /* Does the user want a contiguous dataset? Not so fast! Make sure
     * that there are no unlimited dimensions, and no filters in use
     * for this data. */
@@ -906,7 +909,7 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
    {
       if (var->deflate || var->fletcher32 || var->shuffle)
 	 return NC_EINVAL;
-      
+
      if (!ishdf4) {
       for (d = 0; d < var->ndims; d++)
       {
@@ -969,7 +972,7 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
    if (fill_value && !var->no_fill)
    {
       /* Copy the fill_value. */
-      LOG((4, "Copying fill value into metadata for variable %s", 
+      LOG((4, "Copying fill value into metadata for variable %s",
            var->name));
 
       /* If there's a _FillValue attribute, delete it. */
@@ -993,10 +996,10 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
  * better. Must be called after nc_def_var and before nc_enddef or any
  * functions which writes data to the file. */
 int
-NC4_def_var_deflate(int ncid, int varid, int shuffle, int deflate, 
+NC4_def_var_deflate(int ncid, int varid, int shuffle, int deflate,
                    int deflate_level)
 {
-   return nc_def_var_extra(ncid, varid, &shuffle, &deflate, 
+   return nc_def_var_extra(ncid, varid, &shuffle, &deflate,
                            &deflate_level, NULL, NULL, NULL, NULL, NULL, NULL);
 }
 
@@ -1005,23 +1008,23 @@ NC4_def_var_deflate(int ncid, int varid, int shuffle, int deflate,
 int
 NC4_def_var_fletcher32(int ncid, int varid, int fletcher32)
 {
-   return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, &fletcher32, 
+   return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, &fletcher32,
                            NULL, NULL, NULL, NULL, NULL);
 }
-   
+
 /* Define chunking stuff for a var. This must be done after nc_def_var
-   and before nc_enddef. 
+   and before nc_enddef.
 
    Chunking is required in any dataset with one or more unlimited
    dimensions in HDF5, or any dataset using a filter.
 
    Where chunksize is a pointer to an array of size ndims, with the
-   chunksize in each dimension. 
+   chunksize in each dimension.
 */
 int
 NC4_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksizesp)
 {
-   return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL, 
+   return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL,
                            &contiguous, chunksizesp, NULL, NULL, NULL);
 }
 
@@ -1032,7 +1035,7 @@ int
 nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp)
 {
    NC *nc;
-   NC_GRP_INFO_T *grp; 
+   NC_GRP_INFO_T *grp;
    NC_VAR_INFO_T *var;
    NC_HDF5_FILE_INFO_T *h5;
 
@@ -1047,13 +1050,13 @@ nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp
    /* Find var cause I need the number of dims. */
    if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var)))
       return retval;
-   
+
    /* Allocate space for the size_t copy of the chunksizes array. */
    if (var->ndims)
       if (!(cs = malloc(var->ndims * sizeof(size_t))))
 	 return NC_ENOMEM;
-   
-   retval = NC4_inq_var_all(ncid, varid, NULL, NULL, NULL, NULL, NULL, 
+
+   retval = NC4_inq_var_all(ncid, varid, NULL, NULL, NULL, NULL, NULL,
                            NULL, NULL, NULL, NULL, contiguousp, cs, NULL,
                            NULL, NULL, NULL, NULL);
 
@@ -1079,7 +1082,7 @@ int
 nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp)
 {
    NC *nc;
-   NC_GRP_INFO_T *grp; 
+   NC_GRP_INFO_T *grp;
    NC_VAR_INFO_T *var;
    NC_HDF5_FILE_INFO_T *h5;
    size_t *cs = NULL;
@@ -1093,22 +1096,22 @@ nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp)
 #ifdef USE_HDF4
    if(h5->hdf4)
 	return NC_NOERR;
-#endif  
+#endif
 
    /* Find var cause I need the number of dims. */
    if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var)))
       return retval;
-   
+
    /* Allocate space for the size_t copy of the chunksizes array. */
    if (var->ndims)
       if (!(cs = malloc(var->ndims * sizeof(size_t))))
 	 return NC_ENOMEM;
-   
+
    /* Copy to size_t array. */
    for (i = 0; i < var->ndims; i++)
       cs[i] = chunksizesp[i];
 
-   retval = nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL, 
+   retval = nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL,
                              &contiguous, cs, NULL, NULL, NULL);
 
    if (var->ndims)
@@ -1121,7 +1124,7 @@ nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp)
 int
 NC4_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
 {
-   return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL, NULL, 
+   return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL, NULL,
                            NULL, &no_fill, fill_value, NULL);
 }
 
@@ -1139,21 +1142,21 @@ int
 NC4_inq_varid(int ncid, const char *name, int *varidp)
 {
    NC *nc;
-   NC_GRP_INFO_T *grp; 
+   NC_GRP_INFO_T *grp;
    NC_VAR_INFO_T *var;
    char norm_name[NC_MAX_NAME + 1];
    int retval;
 #if 0 /*def USE_PNETCDF*/
    NC_HDF5_FILE_INFO_T *h5;
 #endif
-   
+
    if (!name)
       return NC_EINVAL;
    if (!varidp)
       return NC_NOERR;
 
    LOG((2, "%s: ncid 0x%x name %s", __func__, ncid, name));
-   
+
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, NULL)))
       return retval;
@@ -1167,7 +1170,7 @@ NC4_inq_varid(int ncid, const char *name, int *varidp)
      return ncmpi_inq_varid(nc->int_ncid, name, varidp);
    }
 #endif /* USE_PNETCDF */
-   
+
    /* Normalize name. */
    if ((retval = nc4_normalize_name(name, norm_name)))
       return retval;
@@ -1184,25 +1187,25 @@ NC4_inq_varid(int ncid, const char *name, int *varidp)
 }
 
 /* Rename a var to "bubba," for example.
-   
+
    According to the netcdf-3.5 docs: If the new name is longer than
    the old name, the netCDF dataset must be in define mode.  */
 int
 NC4_rename_var(int ncid, int varid, const char *name)
 {
    NC *nc;
-   NC_GRP_INFO_T *grp; 
+   NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
    NC_VAR_INFO_T *var, *tmp_var;
    int retval = NC_NOERR;
 
-   LOG((2, "%s: ncid 0x%x varid %d name %s", 
+   LOG((2, "%s: ncid 0x%x varid %d name %s",
         __func__, ncid, varid, name));
 
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
       return retval;
-   
+
    assert(h5);
 
 #if 0 /*def USE_PNETCDF*/
@@ -1229,7 +1232,7 @@ NC4_rename_var(int ncid, int varid, const char *name)
    for (var = grp->var; var; var = var->l.next)
    {
       if (!strncmp(var->name, name, NC_MAX_NAME))
-         return NC_ENAMEINUSE;   
+         return NC_ENAMEINUSE;
       if (var->varid == varid)
          tmp_var = var;
    }
@@ -1295,23 +1298,23 @@ NC4_rename_var(int ncid, int varid, const char *name)
 
 
 int
-NC4_var_par_access(int ncid, int varid, int par_access) 
+NC4_var_par_access(int ncid, int varid, int par_access)
 {
 #ifndef USE_PARALLEL4
    return NC_ENOPAR;
 #else
-   NC *nc; 
-   NC_GRP_INFO_T *grp; 
+   NC *nc;
+   NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
    NC_VAR_INFO_T *var;
    int retval;
 
-   LOG((1, "%s: ncid 0x%x varid %d par_access %d", __func__, ncid, 
+   LOG((1, "%s: ncid 0x%x varid %d par_access %d", __func__, ncid,
         varid, par_access));
 
    if (par_access != NC_INDEPENDENT && par_access != NC_COLLECTIVE)
       return NC_EINVAL;
-   
+
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
       return retval;
@@ -1329,8 +1332,8 @@ NC4_var_par_access(int ncid, int varid, int par_access)
       else
 	 return ncmpi_end_indep_data(nc->int_ncid);
    }
-#endif /* USE_PNETCDF */   
-   
+#endif /* USE_PNETCDF */
+
    /* This function only for files opened with nc_open_par or nc_create_par. */
    if (!h5->parallel)
       return NC_ENOPAR;
@@ -1342,7 +1345,7 @@ NC4_var_par_access(int ncid, int varid, int par_access)
    if (!var)
       return NC_ENOTVAR;
 
-   if (par_access) 
+   if (par_access)
       var->parallel_access = NC_COLLECTIVE;
    else
       var->parallel_access = NC_INDEPENDENT;
@@ -1351,7 +1354,7 @@ NC4_var_par_access(int ncid, int varid, int par_access)
 }
 
 static int
-nc4_put_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long, 
+nc4_put_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long,
                 const size_t *startp, const size_t *countp, const void *op)
 {
    NC *nc;
@@ -1359,8 +1362,8 @@ nc4_put_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long,
 #if 0 /*def USE_PNETCDF*/
    NC_HDF5_FILE_INFO_T *h5;
 #endif
-   
-   LOG((2, "%s: ncid 0x%x varid %d mem_type %d mem_type_is_long %d", 
+
+   LOG((2, "%s: ncid 0x%x varid %d mem_type %d mem_type_is_long %d",
         __func__, ncid, varid, mem_type, mem_type_is_long));
 
    if (!(nc = nc4_find_nc_file(ncid,NULL)))
@@ -1376,14 +1379,14 @@ nc4_put_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long,
      MPI_Offset *mpi_start;
      MPI_Offset *mpi_count;
      int d;
-     
+
      mpi_start = (MPI_Offset*)alloca(sizeof(MPI_Offset)*h5->pnetcdf_ndims[varid]);
      mpi_count = (MPI_Offset*)alloca(sizeof(MPI_Offset)*h5->pnetcdf_ndims[varid]);
 
       /* No NC_LONGs for parallel-netcdf library! */
       if (mem_type_is_long)
 	 return NC_EINVAL;
-      
+
       /* We must convert the start, count, and stride arrays to
        * MPI_Offset type. */
       for (d = 0; d < h5->pnetcdf_ndims[varid]; d++)
@@ -1441,16 +1444,16 @@ nc4_put_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long,
 
       return NC_EBADTYPE;
    }
-   
-#endif /* USE_PNETCDF */   
-   
-   return nc4_put_vara(nc, ncid, varid, startp, countp, mem_type, 
+
+#endif /* USE_PNETCDF */
+
+   return nc4_put_vara(nc, ncid, varid, startp, countp, mem_type,
                        mem_type_is_long, (void *)op);
 }
 
-#ifdef USE_HDF4   
-static int 
-nc4_get_hdf4_vara(NC *nc, int ncid, int varid, const size_t *startp, 
+#ifdef USE_HDF4
+static int
+nc4_get_hdf4_vara(NC *nc, int ncid, int varid, const size_t *startp,
 		  const size_t *countp, nc_type mem_nc_type, int is_long, void *data)
 {
    NC_GRP_INFO_T *grp;
@@ -1461,20 +1464,20 @@ nc4_get_hdf4_vara(NC *nc, int ncid, int varid, const size_t *startp,
 #if 0
    NC_GRP_INFO_T *g;
    NC_DIM_INFO_T *dim;
-#endif   
+#endif
    /* Find our metadata for this file, group, and var. */
    assert(nc);
    if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var)))
       return retval;
    h5 = NC4_DATA(nc);
    assert(grp && h5 && var && var->name);
-   
+
    for (d = 0; d < var->ndims; d++)
    {
       start32[d] = startp[d];
       edge32[d] = countp[d];
    }
-   
+
    if (SDreaddata(var->sdsid, start32, NULL, edge32, data))
       return NC_EHDFERR;
 
@@ -1490,12 +1493,12 @@ nc4_get_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long,
    NC *nc;
    NC_HDF5_FILE_INFO_T* h5;
 
-   LOG((2, "%s: ncid 0x%x varid %d mem_type %d mem_type_is_long %d", 
+   LOG((2, "%s: ncid 0x%x varid %d mem_type %d mem_type_is_long %d",
         __func__, ncid, varid, mem_type, mem_type_is_long));
 
    if (!(nc = nc4_find_nc_file(ncid,&h5)))
       return NC_EBADID;
-   
+
 #if 0 /*def USE_PNETCDF*/
    /* Handle files opened/created with the parallel-netcdf library. */
    if (h5->pnetcdf_file)
@@ -1506,7 +1509,7 @@ nc4_get_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long,
       /* No NC_LONGs for parallel-netcdf library! */
       if (mem_type_is_long)
 	 return NC_EINVAL;
-      
+
       /* We must convert the start, count, and stride arrays to
        * MPI_Offset type. */
       for (d = 0; d < h5->pnetcdf_ndims[varid]; d++)
@@ -1537,7 +1540,7 @@ nc4_get_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long,
 	    default:
 	       return NC_EBADTYPE;
 	 }
-      } 
+      }
       else
       {
 	 switch(mem_type)
@@ -1562,22 +1565,22 @@ nc4_get_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long,
 	 }
       }
    }
-#endif /* USE_PNETCDF */   
-   
-#ifdef USE_HDF4   
+#endif /* USE_PNETCDF */
+
+#ifdef USE_HDF4
    /* Handle HDF4 cases. */
    if (h5->hdf4)
-      return nc4_get_hdf4_vara(nc, ncid, varid, startp, countp, mem_type, 
+      return nc4_get_hdf4_vara(nc, ncid, varid, startp, countp, mem_type,
 			       mem_type_is_long, (void *)ip);
 #endif /* USE_HDF4 */
-   
+
    /* Handle HDF5 cases. */
-   return nc4_get_vara(nc, ncid, varid, startp, countp, mem_type, 
+   return nc4_get_vara(nc, ncid, varid, startp, countp, mem_type,
                        mem_type_is_long, (void *)ip);
 }
 
 int
-NC4_put_vara(int ncid, int varid, const size_t *startp, 
+NC4_put_vara(int ncid, int varid, const size_t *startp,
             const size_t *countp, const void *op, int memtype)
 {
    return nc4_put_vara_tc(ncid, varid, memtype, 0, startp, countp, op);
@@ -1586,7 +1589,7 @@ NC4_put_vara(int ncid, int varid, const size_t *startp,
 
 /* Read an array of values. */
 int
-NC4_get_vara(int ncid, int varid, const size_t *startp, 
+NC4_get_vara(int ncid, int varid, const size_t *startp,
             const size_t *countp, void *ip, int memtype)
 {
    return nc4_get_vara_tc(ncid, varid, memtype, 0, startp, countp, ip);
diff --git a/libsrcp/Makefile.in b/libsrcp/Makefile.in
index b20eb9b..2682b23 100644
--- a/libsrcp/Makefile.in
+++ b/libsrcp/Makefile.in
@@ -247,7 +247,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/nc_test/CMakeLists.txt b/nc_test/CMakeLists.txt
index 0f84673..2d7a7c1 100644
--- a/nc_test/CMakeLists.txt
+++ b/nc_test/CMakeLists.txt
@@ -14,6 +14,7 @@ SET (nc_test_SRC
   test_write.c
   util.c
   )
+
 ADD_EXECUTABLE(nc_test ${nc_test_SRC})
 TARGET_LINK_LIBRARIES(nc_test
   netcdf
diff --git a/nc_test/Makefile.in b/nc_test/Makefile.in
index fbdc0ec..1fbc22b 100644
--- a/nc_test/Makefile.in
+++ b/nc_test/Makefile.in
@@ -621,7 +621,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/nc_test/nc_test.c b/nc_test/nc_test.c
index bb1d1dd..5e779e3 100644
--- a/nc_test/nc_test.c
+++ b/nc_test/nc_test.c
@@ -19,16 +19,16 @@ int numTypes;  /* number of netCDF data types to test */
  * The read-only tests read files:
  *     test.nc (see below)
  *     tests.h (used merely as an example of a non-netCDF file)
- * 
- * The write tests 
- *     read test.nc (see below) 
+ *
+ * The write tests
+ *     read test.nc (see below)
  *     write scratch.nc (deleted after each test)
- * 
+ *
  * The file test.nc is created by running nc_test with the -c (create) option.
  * It is described by the following global variables.
  */
 
-/* 
+/*
  * global variables (defined by function init_gvars) describing file test.nc
  */
 char dim_name[NDIMS][3];
@@ -47,13 +47,13 @@ nc_type gatt_type[NGATTS];
 size_t att_len[NVARS][MAX_NATTS];
 size_t gatt_len[NGATTS];
 
-/* 
+/*
  * command-line options
  */
 int  verbose;		/* if 1, print details of tests */
 int  max_nmpt;		/* max. number of messages per test */
 
-/* 
+/*
  * Misc. global variables
  */
 int  nfails;		/* number of failures in specific test */
@@ -118,7 +118,7 @@ main(int argc, char *argv[])
        numVars  = 136;
        numTypes = 6;
 
-       switch (i) 
+       switch (i)
        {
 	  case NC_FORMAT_CLASSIC:
 	     nc_set_default_format(NC_FORMAT_CLASSIC, NULL);
@@ -374,4 +374,3 @@ main(int argc, char *argv[])
     exit(0);
     return 0;
 }
-
diff --git a/nc_test/test_get.c b/nc_test/test_get.c
index 241bf85..3429213 100644
--- a/nc_test/test_get.c
+++ b/nc_test/test_get.c
@@ -1,9331 +1,9331 @@
-/* Do not edit this file. It is produced from the corresponding .m4 source */
-/*********************************************************************
- *   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 <mpi.h>
-#endif
-
-
-#include "tests.h"
-
-
-void
-test_nc_get_var1_text(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    text value;
-
-    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_TEXT == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_text(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_text(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_text(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_TEXT );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_text(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_text(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_TEXT)) {
-		    if (expect >= text_min && expect <= text_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_TEXT)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_uchar(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    uchar value;
-
-    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_UCHAR == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_uchar(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_uchar(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_uchar(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_UCHAR );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_uchar(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_uchar(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_UCHAR)) {
-		    if (expect >= uchar_min && expect <= uchar_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_UCHAR)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_schar(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    schar value;
-
-    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_SCHAR == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_schar(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_schar(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_schar(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_SCHAR );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_schar(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_schar(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_SCHAR)) {
-		    if (expect >= schar_min && expect <= schar_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_SCHAR)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_short(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    short value;
-
-    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_SHORT == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_short(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_short(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_short(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_SHORT );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_short(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_short(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_SHORT)) {
-		    if (expect >= short_min && expect <= short_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_SHORT)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_int(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    int value;
-
-    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_INT == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_int(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_int(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_int(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_INT );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_int(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_int(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_INT)) {
-		    if (expect >= int_min && expect <= int_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_INT)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_long(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    long value;
-
-    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_LONG == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_long(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_long(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_long(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_LONG );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_long(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_long(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_LONG)) {
-		    if (expect >= long_min && expect <= long_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_LONG)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_float(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    float value;
-
-    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_FLOAT == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_float(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_float(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_float(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_FLOAT );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_float(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_float(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_FLOAT)) {
-		    if (expect >= float_min && expect <= float_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_FLOAT)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_double(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    double value;
-
-    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_DOUBLE == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_double(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_double(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_double(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_DOUBLE );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_double(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_double(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_DOUBLE)) {
-		    if (expect >= double_min && expect <= double_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_DOUBLE)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_ushort(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    ushort value;
-
-    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_USHORT == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_ushort(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_ushort(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_ushort(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_USHORT );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_ushort(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_ushort(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_USHORT)) {
-		    if (expect >= ushort_min && expect <= ushort_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_USHORT)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_uint(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    uint value;
-
-    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_UINT == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_uint(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_uint(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_uint(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_UINT );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_uint(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_uint(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_UINT)) {
-		    if (expect >= uint_min && expect <= uint_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_UINT)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_longlong(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    longlong value;
-
-    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_LONGLONG == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_longlong(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_longlong(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_longlong(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_LONGLONG );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_longlong(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_longlong(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_LONGLONG)) {
-		    if (expect >= longlong_min && expect <= longlong_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_LONGLONG)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var1_ulonglong(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    int nok = 0;      /* count of valid comparisons */
-    size_t index[MAX_RANK];
-    double expect;
-    int canConvert;     /* Both text or both numeric */
-    ulonglong value;
-
-    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_ULONGLONG == NCT_TEXT);
-	for (j = 0; j < var_rank[i]; j++)
-	    index[j] = 0;
-        err = nc_get_var1_ulonglong(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var1_ulonglong(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_ulonglong(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_ULONGLONG );
-	    if (var_rank[i] == 0 && i%2 )
-		err = nc_get_var1_ulonglong(ncid, i, NULL, &value);
-	    else
-		err = nc_get_var1_ulonglong(ncid, i, index, &value);
-            if (canConvert) {
-		if (inRange3(expect,var_type[i], NCT_ULONGLONG)) {
-		    if (expect >= ulonglong_min && expect <= ulonglong_max) {
-			IF (err) {
-			    error("%s", nc_strerror(err));
-			} else {
-			    IF (!equal(value,expect,var_type[i],NCT_ULONGLONG)) {
-				error("expected: %G, got: %G", expect,
-				    (double) value);
-			    } else {
-				nok++;
-			    }
-			}
-		    } 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);
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-
-
-
-void
-test_nc_get_var_text(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    text value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_TEXT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_text(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_text(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_TEXT);
-	    if (inRange3(expect[j],var_type[i], NCT_TEXT)) {
-		allInIntRange = allInIntRange && expect[j] >= text_min
-			    && expect[j] <= text_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_text(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_TEXT)
-			&& expect[j] >= text_min && expect[j] <= text_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_TEXT)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_uchar(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    uchar value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_UCHAR == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_uchar(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_uchar(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_UCHAR);
-	    if (inRange3(expect[j],var_type[i], NCT_UCHAR)) {
-		allInIntRange = allInIntRange && expect[j] >= uchar_min
-			    && expect[j] <= uchar_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_uchar(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_UCHAR)
-			&& expect[j] >= uchar_min && expect[j] <= uchar_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_UCHAR)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_schar(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    schar value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_SCHAR == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_schar(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_schar(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_SCHAR);
-	    if (inRange3(expect[j],var_type[i], NCT_SCHAR)) {
-		allInIntRange = allInIntRange && expect[j] >= schar_min
-			    && expect[j] <= schar_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_schar(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_SCHAR)
-			&& expect[j] >= schar_min && expect[j] <= schar_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_SCHAR)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_short(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    short value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_SHORT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_short(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_short(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_SHORT);
-	    if (inRange3(expect[j],var_type[i], NCT_SHORT)) {
-		allInIntRange = allInIntRange && expect[j] >= short_min
-			    && expect[j] <= short_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_short(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_SHORT)
-			&& expect[j] >= short_min && expect[j] <= short_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_SHORT)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_int(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    int value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_INT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_int(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_int(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_INT);
-	    if (inRange3(expect[j],var_type[i], NCT_INT)) {
-		allInIntRange = allInIntRange && expect[j] >= int_min
-			    && expect[j] <= int_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_int(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_INT)
-			&& expect[j] >= int_min && expect[j] <= int_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_INT)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_long(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    long value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_LONG == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_long(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_long(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_LONG);
-	    if (inRange3(expect[j],var_type[i], NCT_LONG)) {
-		allInIntRange = allInIntRange && expect[j] >= long_min
-			    && expect[j] <= long_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_long(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_LONG)
-			&& expect[j] >= long_min && expect[j] <= long_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_LONG)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_float(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    float value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_FLOAT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_float(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_float(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_FLOAT);
-	    if (inRange3(expect[j],var_type[i], NCT_FLOAT)) {
-		allInIntRange = allInIntRange && expect[j] >= float_min
-			    && expect[j] <= float_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_float(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_FLOAT)
-			&& expect[j] >= float_min && expect[j] <= float_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_FLOAT)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_double(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    double value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_DOUBLE == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_double(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_double(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_DOUBLE);
-	    if (inRange3(expect[j],var_type[i], NCT_DOUBLE)) {
-		allInIntRange = allInIntRange && expect[j] >= double_min
-			    && expect[j] <= double_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_double(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_DOUBLE)
-			&& expect[j] >= double_min && expect[j] <= double_max) {
-		    IF (!equal(value[j],expect[j],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[j]);
-			    error("got: %g", (double) value[j]);
-			}
-		    } else {
-			nok++;
-		    }
-		}
-	    }
-	} else {
-	    IF (nels > 0 && err != NC_ECHAR)
-		error("wrong type: status = %d", err);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_ushort(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    ushort value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_USHORT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_ushort(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_ushort(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_USHORT);
-	    if (inRange3(expect[j],var_type[i], NCT_USHORT)) {
-		allInIntRange = allInIntRange && expect[j] >= ushort_min
-			    && expect[j] <= ushort_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_ushort(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_USHORT)
-			&& expect[j] >= ushort_min && expect[j] <= ushort_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_USHORT)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_uint(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    uint value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_UINT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_uint(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_uint(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_UINT);
-	    if (inRange3(expect[j],var_type[i], NCT_UINT)) {
-		allInIntRange = allInIntRange && expect[j] >= uint_min
-			    && expect[j] <= uint_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_uint(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_UINT)
-			&& expect[j] >= uint_min && expect[j] <= uint_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_UINT)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_longlong(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    longlong value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_LONGLONG == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_longlong(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_longlong(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_LONGLONG);
-	    if (inRange3(expect[j],var_type[i], NCT_LONGLONG)) {
-		allInIntRange = allInIntRange && expect[j] >= longlong_min
-			    && expect[j] <= longlong_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_longlong(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_LONGLONG)
-			&& expect[j] >= longlong_min && expect[j] <= longlong_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_LONGLONG)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_var_ulonglong(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    ulonglong value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_ULONGLONG == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_get_var_ulonglong(BAD_ID, i, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_var_ulonglong(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_ULONGLONG);
-	    if (inRange3(expect[j],var_type[i], NCT_ULONGLONG)) {
-		allInIntRange = allInIntRange && expect[j] >= ulonglong_min
-			    && expect[j] <= ulonglong_max;
-	    } else {
-		allInExtRange = 0;
-	    }
-	}
-	err = nc_get_var_ulonglong(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_ULONGLONG)
-			&& expect[j] >= ulonglong_min && expect[j] <= ulonglong_max) {
-		    IF (!equal(value[j],expect[j],var_type[i],NCT_ULONGLONG)){
-			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);
-	}
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-
-
-
-void
-test_nc_get_vara_text(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    text value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_TEXT == 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_text(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_text(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_text(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_text(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_text(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_text(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_get_vara_text(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_text(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_TEXT);
-		if (inRange3(expect[j],var_type[i], NCT_TEXT)) {
-		    allInIntRange = allInIntRange && expect[j] >= text_min
-				&& expect[j] <= text_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_text(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_text(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_TEXT)
-			    && expect[j] >= text_min && expect[j] <= text_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_TEXT)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_uchar(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    uchar value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_UCHAR == 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_uchar(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_uchar(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_uchar(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_uchar(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_uchar(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_uchar(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_get_vara_uchar(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_uchar(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_UCHAR);
-		if (inRange3(expect[j],var_type[i], NCT_UCHAR)) {
-		    allInIntRange = allInIntRange && expect[j] >= uchar_min
-				&& expect[j] <= uchar_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_uchar(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_uchar(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_UCHAR)
-			    && expect[j] >= uchar_min && expect[j] <= uchar_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_UCHAR)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_schar(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    schar value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_SCHAR == 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_schar(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_schar(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_schar(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_schar(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_schar(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_schar(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_get_vara_schar(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_schar(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_SCHAR);
-		if (inRange3(expect[j],var_type[i], NCT_SCHAR)) {
-		    allInIntRange = allInIntRange && expect[j] >= schar_min
-				&& expect[j] <= schar_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_schar(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_schar(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_SCHAR)
-			    && expect[j] >= schar_min && expect[j] <= schar_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_SCHAR)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_short(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    short value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_SHORT == 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_short(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_short(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_short(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_short(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_short(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_short(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_get_vara_short(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_short(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_SHORT);
-		if (inRange3(expect[j],var_type[i], NCT_SHORT)) {
-		    allInIntRange = allInIntRange && expect[j] >= short_min
-				&& expect[j] <= short_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_short(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_short(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_SHORT)
-			    && expect[j] >= short_min && expect[j] <= short_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_SHORT)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_int(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    int value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_INT == 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_int(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_int(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_int(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_int(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_int(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_int(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_get_vara_int(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_int(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_INT);
-		if (inRange3(expect[j],var_type[i], NCT_INT)) {
-		    allInIntRange = allInIntRange && expect[j] >= int_min
-				&& expect[j] <= int_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_int(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_int(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_INT)
-			    && expect[j] >= int_min && expect[j] <= int_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_INT)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_long(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    long value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_LONG == 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_long(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_long(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_long(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_long(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_long(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_long(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_get_vara_long(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_long(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_LONG);
-		if (inRange3(expect[j],var_type[i], NCT_LONG)) {
-		    allInIntRange = allInIntRange && expect[j] >= long_min
-				&& expect[j] <= long_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_long(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_long(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_LONG)
-			    && expect[j] >= long_min && expect[j] <= long_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_LONG)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_float(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    float value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_FLOAT == 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_float(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_float(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_float(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_float(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_float(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_float(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_get_vara_float(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_float(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_FLOAT);
-		if (inRange3(expect[j],var_type[i], NCT_FLOAT)) {
-		    allInIntRange = allInIntRange && expect[j] >= float_min
-				&& expect[j] <= float_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_float(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_float(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_FLOAT)
-			    && expect[j] >= float_min && expect[j] <= float_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_FLOAT)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_double(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    double value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_DOUBLE == 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_double(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_double(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_double(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_double(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_double(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_double(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_get_vara_double(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_double(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_DOUBLE);
-		if (inRange3(expect[j],var_type[i], NCT_DOUBLE)) {
-		    allInIntRange = allInIntRange && expect[j] >= double_min
-				&& expect[j] <= double_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_double(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_double(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_DOUBLE)
-			    && expect[j] >= double_min && expect[j] <= double_max) {
-			IF (!equal(value[j],expect[j],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[j]);
-				error("got: %g", (double) value[j]);
-			    }
-			} else {
-			    nok++;
-			}
-		    }
-		}
-            } else {
-                IF (nels > 0 && err != NC_ECHAR)
-                    error("wrong type: status = %d", err);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_ushort(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    ushort value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_USHORT == 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_ushort(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_ushort(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_ushort(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_ushort(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_ushort(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_ushort(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_get_vara_ushort(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_ushort(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_USHORT);
-		if (inRange3(expect[j],var_type[i], NCT_USHORT)) {
-		    allInIntRange = allInIntRange && expect[j] >= ushort_min
-				&& expect[j] <= ushort_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_ushort(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_ushort(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_USHORT)
-			    && expect[j] >= ushort_min && expect[j] <= ushort_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_USHORT)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_uint(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    uint value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_UINT == 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_uint(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_uint(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_uint(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_uint(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_uint(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_uint(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_get_vara_uint(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_uint(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_UINT);
-		if (inRange3(expect[j],var_type[i], NCT_UINT)) {
-		    allInIntRange = allInIntRange && expect[j] >= uint_min
-				&& expect[j] <= uint_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_uint(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_uint(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_UINT)
-			    && expect[j] >= uint_min && expect[j] <= uint_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_UINT)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_longlong(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    longlong value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_LONGLONG == 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_longlong(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_longlong(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_longlong(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_longlong(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_longlong(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_longlong(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_get_vara_longlong(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_longlong(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_LONGLONG);
-		if (inRange3(expect[j],var_type[i], NCT_LONGLONG)) {
-		    allInIntRange = allInIntRange && expect[j] >= longlong_min
-				&& expect[j] <= longlong_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_longlong(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_longlong(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_LONGLONG)
-			    && expect[j] >= longlong_min && expect[j] <= longlong_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_LONGLONG)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vara_ulonglong(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    ulonglong value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_ULONGLONG == 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_ulonglong(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID)
-	    error("bad ncid: status = %d", err);
-        err = nc_get_vara_ulonglong(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_ulonglong(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_ulonglong(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_ulonglong(BAD_ID, i, start, edge, value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_vara_ulonglong(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_get_vara_ulonglong(ncid, i, start, edge, value);
-		    IF (canConvert && err != NC_EINVALCOORDS)
-			error("bad start: status = %d", err);
-		    start[j] = 0;
-		}
-	    }
-	    err = nc_get_vara_ulonglong(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 */
-        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];
-            }
-	    allInExtRange = allInIntRange = 1;
-            for (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];
-                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ULONGLONG);
-		if (inRange3(expect[j],var_type[i], NCT_ULONGLONG)) {
-		    allInIntRange = allInIntRange && expect[j] >= ulonglong_min
-				&& expect[j] <= ulonglong_max;
-		} else {
-		    allInExtRange = 0;
-		}
-	    }
-            if (var_rank[i] == 0 && i%2)
-		err = nc_get_vara_ulonglong(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_get_vara_ulonglong(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_ULONGLONG)
-			    && expect[j] >= ulonglong_min && expect[j] <= ulonglong_max) {
-			IF (!equal(value[j],expect[j],var_type[i],NCT_ULONGLONG)){
-			    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);
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-
-
-
-void
-test_nc_get_vars_text(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    text value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_TEXT == 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_get_vars_text(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_text(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_text(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_text(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_text(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_TEXT);
-		    if (inRange3(expect[j],var_type[i],NCT_TEXT)) {
-			allInIntRange = allInIntRange && expect[j] >= text_min
-			    && expect[j] <= text_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_text(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_text(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_TEXT)
-				&& expect[j] >= text_min && expect[j] <= text_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_TEXT)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_uchar(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    uchar value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_UCHAR == 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_get_vars_uchar(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_uchar(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_uchar(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_uchar(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_uchar(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_UCHAR);
-		    if (inRange3(expect[j],var_type[i],NCT_UCHAR)) {
-			allInIntRange = allInIntRange && expect[j] >= uchar_min
-			    && expect[j] <= uchar_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_uchar(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_uchar(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_UCHAR)
-				&& expect[j] >= uchar_min && expect[j] <= uchar_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_UCHAR)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_schar(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    schar value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_SCHAR == 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_get_vars_schar(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_schar(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_schar(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_schar(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_schar(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_SCHAR);
-		    if (inRange3(expect[j],var_type[i],NCT_SCHAR)) {
-			allInIntRange = allInIntRange && expect[j] >= schar_min
-			    && expect[j] <= schar_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_schar(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_schar(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_SCHAR)
-				&& expect[j] >= schar_min && expect[j] <= schar_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_SCHAR)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_short(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    short value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_SHORT == 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_get_vars_short(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_short(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_short(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_short(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_short(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_SHORT);
-		    if (inRange3(expect[j],var_type[i],NCT_SHORT)) {
-			allInIntRange = allInIntRange && expect[j] >= short_min
-			    && expect[j] <= short_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_short(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_short(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_SHORT)
-				&& expect[j] >= short_min && expect[j] <= short_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_SHORT)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_int(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    int value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_INT == 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_get_vars_int(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_int(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_int(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_int(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_int(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_INT);
-		    if (inRange3(expect[j],var_type[i],NCT_INT)) {
-			allInIntRange = allInIntRange && expect[j] >= int_min
-			    && expect[j] <= int_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_int(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_int(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_INT)
-				&& expect[j] >= int_min && expect[j] <= int_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_INT)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_long(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    long value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_LONG == 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_get_vars_long(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_long(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_long(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_long(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_long(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_LONG);
-		    if (inRange3(expect[j],var_type[i],NCT_LONG)) {
-			allInIntRange = allInIntRange && expect[j] >= long_min
-			    && expect[j] <= long_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_long(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_long(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_LONG)
-				&& expect[j] >= long_min && expect[j] <= long_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_LONG)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_float(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    float value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_FLOAT == 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_get_vars_float(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_float(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_float(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_float(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_float(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_FLOAT);
-		    if (inRange3(expect[j],var_type[i],NCT_FLOAT)) {
-			allInIntRange = allInIntRange && expect[j] >= float_min
-			    && expect[j] <= float_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_float(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_float(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_FLOAT)
-				&& expect[j] >= float_min && expect[j] <= float_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_FLOAT)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_double(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    double value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_DOUBLE == 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_get_vars_double(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_double(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_double(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_double(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_double(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_DOUBLE);
-		    if (inRange3(expect[j],var_type[i],NCT_DOUBLE)) {
-			allInIntRange = allInIntRange && expect[j] >= double_min
-			    && expect[j] <= double_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_double(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_double(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_DOUBLE)
-				&& expect[j] >= double_min && expect[j] <= double_max) {
-			    IF (!equal(value[j],expect[j],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[j]);
-				    error("got: %g", (double) value[j]);
-				}
-			    } else {
-				nok++;
-			    }
-			}
-		    }
-		} else {
-		    IF (nels > 0 && err != NC_ECHAR)
-			error("wrong type: status = %d", err);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_ushort(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    ushort value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_USHORT == 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_get_vars_ushort(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_ushort(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_ushort(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_ushort(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_ushort(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_USHORT);
-		    if (inRange3(expect[j],var_type[i],NCT_USHORT)) {
-			allInIntRange = allInIntRange && expect[j] >= ushort_min
-			    && expect[j] <= ushort_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_ushort(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_ushort(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_USHORT)
-				&& expect[j] >= ushort_min && expect[j] <= ushort_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_USHORT)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_uint(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    uint value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_UINT == 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_get_vars_uint(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_uint(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_uint(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_uint(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_uint(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_UINT);
-		    if (inRange3(expect[j],var_type[i],NCT_UINT)) {
-			allInIntRange = allInIntRange && expect[j] >= uint_min
-			    && expect[j] <= uint_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_uint(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_uint(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_UINT)
-				&& expect[j] >= uint_min && expect[j] <= uint_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_UINT)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_longlong(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    longlong value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_LONGLONG == 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_get_vars_longlong(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_longlong(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_longlong(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_longlong(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_longlong(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_LONGLONG);
-		    if (inRange3(expect[j],var_type[i],NCT_LONGLONG)) {
-			allInIntRange = allInIntRange && expect[j] >= longlong_min
-			    && expect[j] <= longlong_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_longlong(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_longlong(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_LONGLONG)
-				&& expect[j] >= longlong_min && expect[j] <= longlong_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_LONGLONG)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_vars_ulonglong(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    ulonglong value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_ULONGLONG == 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_get_vars_ulonglong(BAD_ID, i, start, edge, stride, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_vars_ulonglong(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_vars_ulonglong(ncid, i, start, edge, stride, value);
-	  if(!canConvert) {
-		IF (err != NC_ECHAR)
-               	    error("conversion: status = %d", err);
-	  } else {
-            IF (err != NC_EINVALCOORDS)
-                error("bad index: status = %d", err);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_vars_ulonglong(ncid, i, start, edge, stride, value);
-            IF (err != NC_EEDGE)
-                error("bad edge: status = %d", err);
-            edge[j] = 1;
-            stride[j] = 0;
-            err = nc_get_vars_ulonglong(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 */
-            /* 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;
-                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];
-                    }
-                }
-*/
-		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_ULONGLONG);
-		    if (inRange3(expect[j],var_type[i],NCT_ULONGLONG)) {
-			allInIntRange = allInIntRange && expect[j] >= ulonglong_min
-			    && expect[j] <= ulonglong_max;
-		    } else {
-			allInExtRange = 0;
-		    }
-		}
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_vars_ulonglong(ncid, i, NULL, NULL, NULL, value);
-                else
-                    err = nc_get_vars_ulonglong(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_ULONGLONG)
-				&& expect[j] >= ulonglong_min && expect[j] <= ulonglong_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_ULONGLONG)){
-				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);
-		}
-	    }
-	}
-
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-
-
-
-void
-test_nc_get_varm_text(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    text value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_TEXT == 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_get_varm_text(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_text(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_text(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_text(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_get_varm_text(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_TEXT);
-                    if (inRange3(expect[j],var_type[i],NCT_TEXT)) {
-                        allInIntRange = allInIntRange && expect[j] >= text_min
-                            && expect[j] <= text_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_text(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_text(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);
-                        }
-                    } 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_TEXT)
-                                && expect[j] >= text_min 
-				&& expect[j] <= text_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_TEXT)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_uchar(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    uchar value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_UCHAR == 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_get_varm_uchar(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_uchar(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_uchar(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_uchar(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_get_varm_uchar(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_UCHAR);
-                    if (inRange3(expect[j],var_type[i],NCT_UCHAR)) {
-                        allInIntRange = allInIntRange && expect[j] >= uchar_min
-                            && expect[j] <= uchar_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_uchar(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_uchar(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);
-                        }
-                    } 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_UCHAR)
-                                && expect[j] >= uchar_min 
-				&& expect[j] <= uchar_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_UCHAR)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_schar(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    schar value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_SCHAR == 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_get_varm_schar(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_schar(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_schar(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_schar(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_get_varm_schar(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_SCHAR);
-                    if (inRange3(expect[j],var_type[i],NCT_SCHAR)) {
-                        allInIntRange = allInIntRange && expect[j] >= schar_min
-                            && expect[j] <= schar_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_schar(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_schar(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);
-                        }
-                    } 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_SCHAR)
-                                && expect[j] >= schar_min 
-				&& expect[j] <= schar_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_SCHAR)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_short(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    short value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_SHORT == 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_get_varm_short(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_short(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_short(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_short(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_get_varm_short(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_SHORT);
-                    if (inRange3(expect[j],var_type[i],NCT_SHORT)) {
-                        allInIntRange = allInIntRange && expect[j] >= short_min
-                            && expect[j] <= short_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_short(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_short(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);
-                        }
-                    } 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_SHORT)
-                                && expect[j] >= short_min 
-				&& expect[j] <= short_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_SHORT)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_int(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    int value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_INT == 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_get_varm_int(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_int(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_int(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_int(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_get_varm_int(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_INT);
-                    if (inRange3(expect[j],var_type[i],NCT_INT)) {
-                        allInIntRange = allInIntRange && expect[j] >= int_min
-                            && expect[j] <= int_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_int(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_int(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);
-                        }
-                    } 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_INT)
-                                && expect[j] >= int_min 
-				&& expect[j] <= int_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_INT)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_long(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    long value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_LONG == 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_get_varm_long(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_long(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_long(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_long(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_get_varm_long(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_LONG);
-                    if (inRange3(expect[j],var_type[i],NCT_LONG)) {
-                        allInIntRange = allInIntRange && expect[j] >= long_min
-                            && expect[j] <= long_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_long(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_long(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);
-                        }
-                    } 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_LONG)
-                                && expect[j] >= long_min 
-				&& expect[j] <= long_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_LONG)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_float(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    float value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_FLOAT == 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_get_varm_float(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_float(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_float(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_float(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_get_varm_float(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_FLOAT);
-                    if (inRange3(expect[j],var_type[i],NCT_FLOAT)) {
-                        allInIntRange = allInIntRange && expect[j] >= float_min
-                            && expect[j] <= float_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_float(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_float(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);
-                        }
-                    } 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_FLOAT)
-                                && expect[j] >= float_min 
-				&& expect[j] <= float_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_FLOAT)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_double(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    double value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_DOUBLE == 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_get_varm_double(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_double(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_double(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_double(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_get_varm_double(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_DOUBLE);
-                    if (inRange3(expect[j],var_type[i],NCT_DOUBLE)) {
-                        allInIntRange = allInIntRange && expect[j] >= double_min
-                            && expect[j] <= double_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_double(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_double(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);
-                        }
-                    } 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_DOUBLE)
-                                && expect[j] >= double_min 
-				&& expect[j] <= double_max) {
-			    IF (!equal(value[j],expect[j],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[j]);
-                                    error("got: %g", (double) value[j]);
-                                }
-                            } else {
-                                nok++;
-                            }
-                        }
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_ushort(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    ushort value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_USHORT == 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_get_varm_ushort(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_ushort(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_ushort(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_ushort(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_get_varm_ushort(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_USHORT);
-                    if (inRange3(expect[j],var_type[i],NCT_USHORT)) {
-                        allInIntRange = allInIntRange && expect[j] >= ushort_min
-                            && expect[j] <= ushort_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_ushort(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_ushort(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);
-                        }
-                    } 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_USHORT)
-                                && expect[j] >= ushort_min 
-				&& expect[j] <= ushort_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_USHORT)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_uint(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    uint value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_UINT == 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_get_varm_uint(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_uint(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_uint(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_uint(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_get_varm_uint(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_UINT);
-                    if (inRange3(expect[j],var_type[i],NCT_UINT)) {
-                        allInIntRange = allInIntRange && expect[j] >= uint_min
-                            && expect[j] <= uint_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_uint(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_uint(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);
-                        }
-                    } 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_UINT)
-                                && expect[j] >= uint_min 
-				&& expect[j] <= uint_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_UINT)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_longlong(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    longlong value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_LONGLONG == 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_get_varm_longlong(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_longlong(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_longlong(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_longlong(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_get_varm_longlong(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_LONGLONG);
-                    if (inRange3(expect[j],var_type[i],NCT_LONGLONG)) {
-                        allInIntRange = allInIntRange && expect[j] >= longlong_min
-                            && expect[j] <= longlong_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_longlong(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_longlong(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);
-                        }
-                    } 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_LONGLONG)
-                                && expect[j] >= longlong_min 
-				&& expect[j] <= longlong_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_LONGLONG)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_varm_ulonglong(void)
-{
-    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 canConvert;     /* Both text or both numeric */
-    ulonglong value[MAX_NELS];
-    double expect[MAX_NELS];
-
-    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_ULONGLONG == 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_get_varm_ulonglong(BAD_ID, i, start, edge, stride, imap, value);
-        IF (err != NC_EBADID)
-            error("bad ncid: status = %d", err);
-        err = nc_get_varm_ulonglong(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++) {
-            start[j] = var_shape[i][j];
-            err = nc_get_varm_ulonglong(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);
-            start[j] = 0;
-            edge[j] = var_shape[i][j] + 1;
-            err = nc_get_varm_ulonglong(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_get_varm_ulonglong(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 */
-            /* 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;
-                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) {
-		    j = var_rank[i] - 1;
-		    imap[j] = 1;
-		    for (; j > 0; j--)
-			imap[j-1] = imap[j] * count[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_ULONGLONG);
-                    if (inRange3(expect[j],var_type[i],NCT_ULONGLONG)) {
-                        allInIntRange = allInIntRange && expect[j] >= ulonglong_min
-                            && expect[j] <= ulonglong_max;
-                    } else {
-                        allInExtRange = 0;
-                    }
-                }
-                if (var_rank[i] == 0 && i%2 )
-                    err = nc_get_varm_ulonglong(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_get_varm_ulonglong(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);
-                        }
-                    } 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_ULONGLONG)
-                                && expect[j] >= ulonglong_min 
-				&& expect[j] <= ulonglong_max) {
-			    IF (!equal(value[j],expect[j],var_type[i], NCT_ULONGLONG)){
-                                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);
-                }
-            }
-        }
-    }
-    err = nc_close(ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-
-
-
-void
-test_nc_get_att_text(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    text value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
-	    err = nc_get_att_text(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_text(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_text(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_TEXT);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_TEXT)) {
-                    allInIntRange = allInIntRange && expect[k] >= text_min
-                                && expect[k] <= text_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_text(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_TEXT)
-                            && expect[k] >= text_min && expect[k] <= text_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_TEXT)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_uchar(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    uchar value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
-	    err = nc_get_att_uchar(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_uchar(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_uchar(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_UCHAR);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UCHAR)) {
-                    allInIntRange = allInIntRange && expect[k] >= uchar_min
-                                && expect[k] <= uchar_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_uchar(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UCHAR)
-                            && expect[k] >= uchar_min && expect[k] <= uchar_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_UCHAR)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_schar(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    schar value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
-	    err = nc_get_att_schar(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_schar(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_schar(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_SCHAR);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SCHAR)) {
-                    allInIntRange = allInIntRange && expect[k] >= schar_min
-                                && expect[k] <= schar_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_schar(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SCHAR)
-                            && expect[k] >= schar_min && expect[k] <= schar_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_SCHAR)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_short(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    short value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
-	    err = nc_get_att_short(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_short(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_short(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_SHORT);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SHORT)) {
-                    allInIntRange = allInIntRange && expect[k] >= short_min
-                                && expect[k] <= short_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_short(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SHORT)
-                            && expect[k] >= short_min && expect[k] <= short_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_SHORT)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_int(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    int value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_INT == NCT_TEXT);
-	    err = nc_get_att_int(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_int(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_int(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_INT);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_INT)) {
-                    allInIntRange = allInIntRange && expect[k] >= int_min
-                                && expect[k] <= int_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_int(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_INT)
-                            && expect[k] >= int_min && expect[k] <= int_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_INT)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_long(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    long value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_LONG == NCT_TEXT);
-	    err = nc_get_att_long(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_long(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_long(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_LONG);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONG)) {
-                    allInIntRange = allInIntRange && expect[k] >= long_min
-                                && expect[k] <= long_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_long(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONG)
-                            && expect[k] >= long_min && expect[k] <= long_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_LONG)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_float(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    float value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
-	    err = nc_get_att_float(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_float(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_float(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_FLOAT);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_FLOAT)) {
-                    allInIntRange = allInIntRange && expect[k] >= float_min
-                                && expect[k] <= float_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_float(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_FLOAT)
-                            && expect[k] >= float_min && expect[k] <= float_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_FLOAT)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_double(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    double value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
-	    err = nc_get_att_double(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_double(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_double(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_DOUBLE);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_DOUBLE)) {
-                    allInIntRange = allInIntRange && expect[k] >= double_min
-                                && expect[k] <= double_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_double(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_DOUBLE)
-                            && expect[k] >= double_min && expect[k] <= double_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_DOUBLE)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_ushort(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    ushort value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_USHORT == NCT_TEXT);
-	    err = nc_get_att_ushort(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_ushort(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_ushort(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_USHORT);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_USHORT)) {
-                    allInIntRange = allInIntRange && expect[k] >= ushort_min
-                                && expect[k] <= ushort_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_ushort(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_USHORT)
-                            && expect[k] >= ushort_min && expect[k] <= ushort_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_USHORT)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_uint(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    uint value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_UINT == NCT_TEXT);
-	    err = nc_get_att_uint(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_uint(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_uint(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_UINT);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UINT)) {
-                    allInIntRange = allInIntRange && expect[k] >= uint_min
-                                && expect[k] <= uint_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_uint(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UINT)
-                            && expect[k] >= uint_min && expect[k] <= uint_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_UINT)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_longlong(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    longlong value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_LONGLONG == NCT_TEXT);
-	    err = nc_get_att_longlong(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_longlong(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_longlong(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_LONGLONG);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONGLONG)) {
-                    allInIntRange = allInIntRange && expect[k] >= longlong_min
-                                && expect[k] <= longlong_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_longlong(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONGLONG)
-                            && expect[k] >= longlong_min && expect[k] <= longlong_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_LONGLONG)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-void
-test_nc_get_att_ulonglong(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int allInExtRange;
-    int allInIntRange;
-    int canConvert;     /* Both text or both numeric */
-    ulonglong value[MAX_NELS];
-    double expect[MAX_NELS];
-    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++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_ULONGLONG == NCT_TEXT);
-	    err = nc_get_att_ulonglong(BAD_ID, i, ATT_NAME(i,j), value);
-	    IF (err != NC_EBADID) 
-		error("bad ncid: status = %d", err);
-	    err = nc_get_att_ulonglong(ncid, BAD_VARID, ATT_NAME(i,j), value);
-	    IF (err != NC_ENOTVAR) 
-		error("bad var id: status = %d", err);
-	    err = nc_get_att_ulonglong(ncid, i, "noSuch", value);
-	    IF (err != NC_ENOTATT) 
-		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_ULONGLONG);
-                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_ULONGLONG)) {
-                    allInIntRange = allInIntRange && expect[k] >= ulonglong_min
-                                && expect[k] <= ulonglong_max;
-                } else {
-                    allInExtRange = 0;
-                }
-	    }
-	    err = nc_get_att_ulonglong(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));
-                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
-		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_ULONGLONG)
-                            && expect[k] >= ulonglong_min && expect[k] <= ulonglong_max) {
-			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_ULONGLONG)){
-			    error("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++;
-                        }
-		    }
-		}
-	    } else {
-		IF (err != NC_ECHAR)
-		    error("wrong type: status = %d", err);
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err)
-	error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+/*********************************************************************
+ *   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 <mpi.h>
+#endif
+
+
+#include "tests.h"
+
+
+void
+test_nc_get_var1_text(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    text value;
+
+    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_TEXT == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_text(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_text(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_text(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_TEXT );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_text(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_text(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_TEXT)) {
+		    if (expect >= text_min && expect <= text_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_TEXT)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_uchar(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    uchar value;
+
+    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_UCHAR == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_uchar(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_uchar(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_uchar(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_UCHAR );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_uchar(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_uchar(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_UCHAR)) {
+		    if (expect >= uchar_min && expect <= uchar_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_UCHAR)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_schar(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    schar value;
+
+    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_SCHAR == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_schar(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_schar(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_schar(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_SCHAR );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_schar(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_schar(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_SCHAR)) {
+		    if (expect >= schar_min && expect <= schar_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_SCHAR)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_short(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    short value;
+
+    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_SHORT == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_short(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_short(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_short(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_SHORT );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_short(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_short(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_SHORT)) {
+		    if (expect >= short_min && expect <= short_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_SHORT)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_int(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    int value;
+
+    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_INT == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_int(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_int(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_int(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_INT );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_int(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_int(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_INT)) {
+		    if (expect >= int_min && expect <= int_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_INT)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_long(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    long value;
+
+    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_LONG == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_long(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_long(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_long(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_LONG );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_long(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_long(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_LONG)) {
+		    if (expect >= long_min && expect <= long_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_LONG)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_float(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    float value;
+
+    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_FLOAT == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_float(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_float(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_float(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_FLOAT );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_float(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_float(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_FLOAT)) {
+		    if (expect >= float_min && expect <= float_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_FLOAT)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_double(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    double value;
+
+    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_DOUBLE == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_double(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_double(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_double(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_DOUBLE );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_double(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_double(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_DOUBLE)) {
+		    if (expect >= double_min && expect <= double_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_DOUBLE)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_ushort(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    ushort value;
+
+    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_USHORT == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_ushort(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_ushort(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_ushort(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_USHORT );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_ushort(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_ushort(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_USHORT)) {
+		    if (expect >= ushort_min && expect <= ushort_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_USHORT)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_uint(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    uint value;
+
+    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_UINT == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_uint(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_uint(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_uint(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_UINT );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_uint(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_uint(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_UINT)) {
+		    if (expect >= uint_min && expect <= uint_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_UINT)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_longlong(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    longlong value;
+
+    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_LONGLONG == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_longlong(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_longlong(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_longlong(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_LONGLONG );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_longlong(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_longlong(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_LONGLONG)) {
+		    if (expect >= longlong_min && expect <= longlong_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_LONGLONG)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var1_ulonglong(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    int nok = 0;      /* count of valid comparisons */
+    size_t index[MAX_RANK];
+    double expect;
+    int canConvert;     /* Both text or both numeric */
+    ulonglong value;
+
+    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_ULONGLONG == NCT_TEXT);
+	for (j = 0; j < var_rank[i]; j++)
+	    index[j] = 0;
+        err = nc_get_var1_ulonglong(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var1_ulonglong(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_ulonglong(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_ULONGLONG );
+	    if (var_rank[i] == 0 && i%2 )
+		err = nc_get_var1_ulonglong(ncid, i, NULL, &value);
+	    else
+		err = nc_get_var1_ulonglong(ncid, i, index, &value);
+            if (canConvert) {
+		if (inRange3(expect,var_type[i], NCT_ULONGLONG)) {
+		    if (expect >= ulonglong_min && expect <= ulonglong_max) {
+			IF (err) {
+			    error("%s", nc_strerror(err));
+			} else {
+			    IF (!equal(value,expect,var_type[i],NCT_ULONGLONG)) {
+				error("expected: %G, got: %G", expect,
+				    (double) value);
+			    } else {
+				nok++;
+			    }
+			}
+		    } 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);
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+
+
+
+void
+test_nc_get_var_text(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    text value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_TEXT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_text(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_text(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_TEXT);
+	    if (inRange3(expect[j],var_type[i], NCT_TEXT)) {
+		allInIntRange = allInIntRange && expect[j] >= text_min
+			    && expect[j] <= text_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_text(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_TEXT)
+			&& expect[j] >= text_min && expect[j] <= text_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_TEXT)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_uchar(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    uchar value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_UCHAR == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_uchar(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_uchar(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_UCHAR);
+	    if (inRange3(expect[j],var_type[i], NCT_UCHAR)) {
+		allInIntRange = allInIntRange && expect[j] >= uchar_min
+			    && expect[j] <= uchar_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_uchar(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_UCHAR)
+			&& expect[j] >= uchar_min && expect[j] <= uchar_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_UCHAR)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_schar(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    schar value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_SCHAR == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_schar(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_schar(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_SCHAR);
+	    if (inRange3(expect[j],var_type[i], NCT_SCHAR)) {
+		allInIntRange = allInIntRange && expect[j] >= schar_min
+			    && expect[j] <= schar_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_schar(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_SCHAR)
+			&& expect[j] >= schar_min && expect[j] <= schar_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_SCHAR)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));

+    print_nok(nok);
+}
+
+void
+test_nc_get_var_short(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    short value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_SHORT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_short(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_short(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_SHORT);
+	    if (inRange3(expect[j],var_type[i], NCT_SHORT)) {
+		allInIntRange = allInIntRange && expect[j] >= short_min
+			    && expect[j] <= short_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_short(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_SHORT)
+			&& expect[j] >= short_min && expect[j] <= short_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_SHORT)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_int(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    int value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_INT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_int(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_int(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_INT);
+	    if (inRange3(expect[j],var_type[i], NCT_INT)) {
+		allInIntRange = allInIntRange && expect[j] >= int_min
+			    && expect[j] <= int_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_int(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_INT)
+			&& expect[j] >= int_min && expect[j] <= int_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_INT)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_long(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    long value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_LONG == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_long(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_long(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_LONG);
+	    if (inRange3(expect[j],var_type[i], NCT_LONG)) {
+		allInIntRange = allInIntRange && expect[j] >= long_min
+			    && expect[j] <= long_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_long(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_LONG)
+			&& expect[j] >= long_min && expect[j] <= long_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_LONG)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_float(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    float value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_FLOAT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_float(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_float(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_FLOAT);
+	    if (inRange3(expect[j],var_type[i], NCT_FLOAT)) {
+		allInIntRange = allInIntRange && expect[j] >= float_min
+			    && expect[j] <= float_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_float(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_FLOAT)
+			&& expect[j] >= float_min && expect[j] <= float_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_FLOAT)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_double(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    double value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_DOUBLE == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_double(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_double(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_DOUBLE);
+	    if (inRange3(expect[j],var_type[i], NCT_DOUBLE)) {
+		allInIntRange = allInIntRange && expect[j] >= double_min
+			    && expect[j] <= double_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_double(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_DOUBLE)
+			&& expect[j] >= double_min && expect[j] <= double_max) {
+		    IF (!equal(value[j],expect[j],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[j]);
+			    error("got: %g", (double) value[j]);
+			}
+		    } else {
+			nok++;
+		    }
+		}
+	    }
+	} else {
+	    IF (nels > 0 && err != NC_ECHAR)
+		error("wrong type: status = %d", err);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_ushort(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    ushort value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_USHORT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_ushort(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_ushort(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_USHORT);
+	    if (inRange3(expect[j],var_type[i], NCT_USHORT)) {
+		allInIntRange = allInIntRange && expect[j] >= ushort_min
+			    && expect[j] <= ushort_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_ushort(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_USHORT)
+			&& expect[j] >= ushort_min && expect[j] <= ushort_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_USHORT)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_uint(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    uint value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_UINT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_uint(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_uint(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_UINT);
+	    if (inRange3(expect[j],var_type[i], NCT_UINT)) {
+		allInIntRange = allInIntRange && expect[j] >= uint_min
+			    && expect[j] <= uint_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_uint(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_UINT)
+			&& expect[j] >= uint_min && expect[j] <= uint_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_UINT)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_longlong(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    longlong value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_LONGLONG == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_longlong(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_longlong(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_LONGLONG);
+	    if (inRange3(expect[j],var_type[i], NCT_LONGLONG)) {
+		allInIntRange = allInIntRange && expect[j] >= longlong_min
+			    && expect[j] <= longlong_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_longlong(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_LONGLONG)
+			&& expect[j] >= longlong_min && expect[j] <= longlong_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_LONGLONG)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_var_ulonglong(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    ulonglong value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_ULONGLONG == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_get_var_ulonglong(BAD_ID, i, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_var_ulonglong(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_ULONGLONG);
+	    if (inRange3(expect[j],var_type[i], NCT_ULONGLONG)) {
+		allInIntRange = allInIntRange && expect[j] >= ulonglong_min
+			    && expect[j] <= ulonglong_max;
+	    } else {
+		allInExtRange = 0;
+	    }
+	}
+	err = nc_get_var_ulonglong(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_ULONGLONG)
+			&& expect[j] >= ulonglong_min && expect[j] <= ulonglong_max) {
+		    IF (!equal(value[j],expect[j],var_type[i],NCT_ULONGLONG)){
+			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);
+	}
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+
+
+
+void
+test_nc_get_vara_text(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    text value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_TEXT == 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_text(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_text(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_text(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_text(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_text(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_text(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_get_vara_text(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_text(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_TEXT);
+		if (inRange3(expect[j],var_type[i], NCT_TEXT)) {
+		    allInIntRange = allInIntRange && expect[j] >= text_min
+				&& expect[j] <= text_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_text(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_text(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_TEXT)
+			    && expect[j] >= text_min && expect[j] <= text_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_TEXT)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_uchar(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    uchar value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_UCHAR == 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_uchar(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_uchar(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_uchar(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_uchar(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_uchar(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_uchar(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_get_vara_uchar(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_uchar(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_UCHAR);
+		if (inRange3(expect[j],var_type[i], NCT_UCHAR)) {
+		    allInIntRange = allInIntRange && expect[j] >= uchar_min
+				&& expect[j] <= uchar_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_uchar(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_uchar(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_UCHAR)
+			    && expect[j] >= uchar_min && expect[j] <= uchar_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_UCHAR)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_schar(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    schar value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_SCHAR == 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_schar(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_schar(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_schar(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_schar(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_schar(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_schar(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_get_vara_schar(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_schar(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_SCHAR);
+		if (inRange3(expect[j],var_type[i], NCT_SCHAR)) {
+		    allInIntRange = allInIntRange && expect[j] >= schar_min
+				&& expect[j] <= schar_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_schar(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_schar(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_SCHAR)
+			    && expect[j] >= schar_min && expect[j] <= schar_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_SCHAR)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_short(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    short value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_SHORT == 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_short(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_short(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_short(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_short(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_short(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_short(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_get_vara_short(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_short(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_SHORT);
+		if (inRange3(expect[j],var_type[i], NCT_SHORT)) {
+		    allInIntRange = allInIntRange && expect[j] >= short_min
+				&& expect[j] <= short_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_short(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_short(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_SHORT)
+			    && expect[j] >= short_min && expect[j] <= short_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_SHORT)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_int(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    int value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_INT == 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_int(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_int(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_int(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_int(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_int(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_int(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_get_vara_int(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_int(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_INT);
+		if (inRange3(expect[j],var_type[i], NCT_INT)) {
+		    allInIntRange = allInIntRange && expect[j] >= int_min
+				&& expect[j] <= int_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_int(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_int(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_INT)
+			    && expect[j] >= int_min && expect[j] <= int_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_INT)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_long(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    long value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_LONG == 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_long(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_long(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_long(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_long(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_long(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_long(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_get_vara_long(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_long(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_LONG);
+		if (inRange3(expect[j],var_type[i], NCT_LONG)) {
+		    allInIntRange = allInIntRange && expect[j] >= long_min
+				&& expect[j] <= long_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_long(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_long(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_LONG)
+			    && expect[j] >= long_min && expect[j] <= long_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_LONG)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_float(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    float value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_FLOAT == 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_float(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_float(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_float(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_float(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_float(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_float(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_get_vara_float(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_float(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_FLOAT);
+		if (inRange3(expect[j],var_type[i], NCT_FLOAT)) {
+		    allInIntRange = allInIntRange && expect[j] >= float_min
+				&& expect[j] <= float_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_float(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_float(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_FLOAT)
+			    && expect[j] >= float_min && expect[j] <= float_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_FLOAT)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_double(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    double value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_DOUBLE == 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_double(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_double(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_double(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_double(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_double(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_double(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_get_vara_double(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_double(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_DOUBLE);
+		if (inRange3(expect[j],var_type[i], NCT_DOUBLE)) {
+		    allInIntRange = allInIntRange && expect[j] >= double_min
+				&& expect[j] <= double_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_double(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_double(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_DOUBLE)
+			    && expect[j] >= double_min && expect[j] <= double_max) {
+			IF (!equal(value[j],expect[j],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[j]);
+				error("got: %g", (double) value[j]);
+			    }
+			} else {
+			    nok++;
+			}
+		    }
+		}
+            } else {
+                IF (nels > 0 && err != NC_ECHAR)
+                    error("wrong type: status = %d", err);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_ushort(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    ushort value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_USHORT == 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_ushort(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_ushort(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_ushort(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_ushort(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_ushort(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_ushort(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_get_vara_ushort(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_ushort(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_USHORT);
+		if (inRange3(expect[j],var_type[i], NCT_USHORT)) {
+		    allInIntRange = allInIntRange && expect[j] >= ushort_min
+				&& expect[j] <= ushort_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_ushort(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_ushort(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_USHORT)
+			    && expect[j] >= ushort_min && expect[j] <= ushort_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_USHORT)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_uint(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    uint value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_UINT == 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_uint(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_uint(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_uint(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_uint(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_uint(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_uint(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_get_vara_uint(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_uint(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_UINT);
+		if (inRange3(expect[j],var_type[i], NCT_UINT)) {
+		    allInIntRange = allInIntRange && expect[j] >= uint_min
+				&& expect[j] <= uint_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_uint(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_uint(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_UINT)
+			    && expect[j] >= uint_min && expect[j] <= uint_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_UINT)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_longlong(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    longlong value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_LONGLONG == 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_longlong(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_longlong(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_longlong(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_longlong(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_longlong(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_longlong(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_get_vara_longlong(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_longlong(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_LONGLONG);
+		if (inRange3(expect[j],var_type[i], NCT_LONGLONG)) {
+		    allInIntRange = allInIntRange && expect[j] >= longlong_min
+				&& expect[j] <= longlong_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_longlong(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_longlong(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_LONGLONG)
+			    && expect[j] >= longlong_min && expect[j] <= longlong_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_LONGLONG)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vara_ulonglong(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    ulonglong value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_ULONGLONG == 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_ulonglong(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID)
+	    error("bad ncid: status = %d", err);
+        err = nc_get_vara_ulonglong(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_ulonglong(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_ulonglong(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_ulonglong(BAD_ID, i, start, edge, value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_vara_ulonglong(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_get_vara_ulonglong(ncid, i, start, edge, value);
+		    IF (canConvert && err != NC_EINVALCOORDS)
+			error("bad start: status = %d", err);
+		    start[j] = 0;
+		}
+	    }
+	    err = nc_get_vara_ulonglong(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 */
+        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];
+            }
+	    allInExtRange = allInIntRange = 1;
+            for (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];
+                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ULONGLONG);
+		if (inRange3(expect[j],var_type[i], NCT_ULONGLONG)) {
+		    allInIntRange = allInIntRange && expect[j] >= ulonglong_min
+				&& expect[j] <= ulonglong_max;
+		} else {
+		    allInExtRange = 0;
+		}
+	    }
+            if (var_rank[i] == 0 && i%2)
+		err = nc_get_vara_ulonglong(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_get_vara_ulonglong(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_ULONGLONG)
+			    && expect[j] >= ulonglong_min && expect[j] <= ulonglong_max) {
+			IF (!equal(value[j],expect[j],var_type[i],NCT_ULONGLONG)){
+			    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);
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+
+
+
+void
+test_nc_get_vars_text(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    text value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_TEXT == 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_get_vars_text(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_text(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_text(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_text(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_text(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_TEXT);
+		    if (inRange3(expect[j],var_type[i],NCT_TEXT)) {
+			allInIntRange = allInIntRange && expect[j] >= text_min
+			    && expect[j] <= text_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_text(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_text(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_TEXT)
+				&& expect[j] >= text_min && expect[j] <= text_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_TEXT)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_uchar(void)
+{

+    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 canConvert;     /* Both text or both numeric */
+    uchar value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_UCHAR == 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_get_vars_uchar(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_uchar(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_uchar(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_uchar(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_uchar(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_UCHAR);
+		    if (inRange3(expect[j],var_type[i],NCT_UCHAR)) {
+			allInIntRange = allInIntRange && expect[j] >= uchar_min
+			    && expect[j] <= uchar_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_uchar(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_uchar(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_UCHAR)
+				&& expect[j] >= uchar_min && expect[j] <= uchar_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_UCHAR)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_schar(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    schar value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_SCHAR == 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_get_vars_schar(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_schar(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_schar(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_schar(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_schar(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_SCHAR);
+		    if (inRange3(expect[j],var_type[i],NCT_SCHAR)) {
+			allInIntRange = allInIntRange && expect[j] >= schar_min
+			    && expect[j] <= schar_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_schar(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_schar(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_SCHAR)
+				&& expect[j] >= schar_min && expect[j] <= schar_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_SCHAR)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_short(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    short value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_SHORT == 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_get_vars_short(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_short(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_short(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_short(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_short(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_SHORT);
+		    if (inRange3(expect[j],var_type[i],NCT_SHORT)) {
+			allInIntRange = allInIntRange && expect[j] >= short_min
+			    && expect[j] <= short_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_short(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_short(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_SHORT)
+				&& expect[j] >= short_min && expect[j] <= short_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_SHORT)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_int(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    int value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_INT == 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_get_vars_int(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_int(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_int(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_int(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_int(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_INT);
+		    if (inRange3(expect[j],var_type[i],NCT_INT)) {
+			allInIntRange = allInIntRange && expect[j] >= int_min
+			    && expect[j] <= int_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_int(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_int(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_INT)
+				&& expect[j] >= int_min && expect[j] <= int_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_INT)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_long(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    long value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_LONG == 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_get_vars_long(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_long(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_long(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_long(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_long(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_LONG);
+		    if (inRange3(expect[j],var_type[i],NCT_LONG)) {
+			allInIntRange = allInIntRange && expect[j] >= long_min
+			    && expect[j] <= long_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_long(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_long(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_LONG)
+				&& expect[j] >= long_min && expect[j] <= long_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_LONG)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_float(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    float value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_FLOAT == 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_get_vars_float(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_float(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_float(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_float(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_float(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_FLOAT);
+		    if (inRange3(expect[j],var_type[i],NCT_FLOAT)) {
+			allInIntRange = allInIntRange && expect[j] >= float_min
+			    && expect[j] <= float_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_float(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_float(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_FLOAT)
+				&& expect[j] >= float_min && expect[j] <= float_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_FLOAT)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_double(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    double value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_DOUBLE == 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_get_vars_double(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_double(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_double(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_double(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_double(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_DOUBLE);
+		    if (inRange3(expect[j],var_type[i],NCT_DOUBLE)) {
+			allInIntRange = allInIntRange && expect[j] >= double_min
+			    && expect[j] <= double_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_double(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_double(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_DOUBLE)
+				&& expect[j] >= double_min && expect[j] <= double_max) {
+			    IF (!equal(value[j],expect[j],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[j]);
+				    error("got: %g", (double) value[j]);
+				}
+			    } else {
+				nok++;
+			    }
+			}
+		    }
+		} else {
+		    IF (nels > 0 && err != NC_ECHAR)
+			error("wrong type: status = %d", err);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_ushort(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    ushort value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_USHORT == 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_get_vars_ushort(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_ushort(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_ushort(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_ushort(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_ushort(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_USHORT);
+		    if (inRange3(expect[j],var_type[i],NCT_USHORT)) {
+			allInIntRange = allInIntRange && expect[j] >= ushort_min
+			    && expect[j] <= ushort_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_ushort(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_ushort(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_USHORT)
+				&& expect[j] >= ushort_min && expect[j] <= ushort_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_USHORT)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_uint(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    uint value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_UINT == 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_get_vars_uint(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_uint(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_uint(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_uint(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_uint(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_UINT);
+		    if (inRange3(expect[j],var_type[i],NCT_UINT)) {
+			allInIntRange = allInIntRange && expect[j] >= uint_min
+			    && expect[j] <= uint_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_uint(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_uint(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_UINT)
+				&& expect[j] >= uint_min && expect[j] <= uint_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_UINT)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_longlong(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    longlong value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_LONGLONG == 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_get_vars_longlong(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_longlong(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_longlong(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_longlong(ncid, i, start, edge, stride, value);

+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_longlong(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_LONGLONG);
+		    if (inRange3(expect[j],var_type[i],NCT_LONGLONG)) {
+			allInIntRange = allInIntRange && expect[j] >= longlong_min
+			    && expect[j] <= longlong_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_longlong(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_longlong(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_LONGLONG)
+				&& expect[j] >= longlong_min && expect[j] <= longlong_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_LONGLONG)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_vars_ulonglong(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    ulonglong value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_ULONGLONG == 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_get_vars_ulonglong(BAD_ID, i, start, edge, stride, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_vars_ulonglong(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_vars_ulonglong(ncid, i, start, edge, stride, value);
+	  if(!canConvert) {
+		IF (err != NC_ECHAR)
+               	    error("conversion: status = %d", err);
+	  } else {
+            IF (err != NC_EINVALCOORDS)
+                error("bad index: status = %d", err);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_vars_ulonglong(ncid, i, start, edge, stride, value);
+            IF (err != NC_EEDGE)
+                error("bad edge: status = %d", err);
+            edge[j] = 1;
+            stride[j] = 0;
+            err = nc_get_vars_ulonglong(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 */
+            /* 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;
+                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];
+                    }
+                }
+*/
+		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_ULONGLONG);
+		    if (inRange3(expect[j],var_type[i],NCT_ULONGLONG)) {
+			allInIntRange = allInIntRange && expect[j] >= ulonglong_min
+			    && expect[j] <= ulonglong_max;
+		    } else {
+			allInExtRange = 0;
+		    }
+		}
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_vars_ulonglong(ncid, i, NULL, NULL, NULL, value);
+                else
+                    err = nc_get_vars_ulonglong(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_ULONGLONG)
+				&& expect[j] >= ulonglong_min && expect[j] <= ulonglong_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_ULONGLONG)){
+				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);
+		}
+	    }
+	}
+
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+
+
+
+void
+test_nc_get_varm_text(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    text value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_TEXT == 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_get_varm_text(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_text(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_text(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_text(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_get_varm_text(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_TEXT);
+                    if (inRange3(expect[j],var_type[i],NCT_TEXT)) {
+                        allInIntRange = allInIntRange && expect[j] >= text_min
+                            && expect[j] <= text_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_text(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_text(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);
+                        }
+                    } 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_TEXT)
+                                && expect[j] >= text_min 
+				&& expect[j] <= text_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_TEXT)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_uchar(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    uchar value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_UCHAR == 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_get_varm_uchar(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_uchar(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_uchar(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_uchar(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_get_varm_uchar(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_UCHAR);
+                    if (inRange3(expect[j],var_type[i],NCT_UCHAR)) {
+                        allInIntRange = allInIntRange && expect[j] >= uchar_min
+                            && expect[j] <= uchar_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_uchar(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_uchar(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);
+                        }
+                    } 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_UCHAR)
+                                && expect[j] >= uchar_min 
+				&& expect[j] <= uchar_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_UCHAR)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_schar(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    schar value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_SCHAR == 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_get_varm_schar(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_schar(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_schar(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_schar(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_get_varm_schar(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_SCHAR);
+                    if (inRange3(expect[j],var_type[i],NCT_SCHAR)) {
+                        allInIntRange = allInIntRange && expect[j] >= schar_min
+                            && expect[j] <= schar_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_schar(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_schar(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);
+                        }
+                    } 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_SCHAR)
+                                && expect[j] >= schar_min 
+				&& expect[j] <= schar_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_SCHAR)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_short(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    short value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_SHORT == 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_get_varm_short(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_short(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_short(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_short(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_get_varm_short(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_SHORT);
+                    if (inRange3(expect[j],var_type[i],NCT_SHORT)) {
+                        allInIntRange = allInIntRange && expect[j] >= short_min
+                            && expect[j] <= short_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_short(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_short(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);
+                        }
+                    } 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_SHORT)
+                                && expect[j] >= short_min 
+				&& expect[j] <= short_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_SHORT)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_int(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    int value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_INT == 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_get_varm_int(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_int(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_int(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_int(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_get_varm_int(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_INT);
+                    if (inRange3(expect[j],var_type[i],NCT_INT)) {
+                        allInIntRange = allInIntRange && expect[j] >= int_min
+                            && expect[j] <= int_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_int(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_int(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);
+                        }
+                    } 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_INT)
+                                && expect[j] >= int_min 
+				&& expect[j] <= int_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_INT)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_long(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    long value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_LONG == 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_get_varm_long(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_long(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_long(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_long(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_get_varm_long(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_LONG);
+                    if (inRange3(expect[j],var_type[i],NCT_LONG)) {
+                        allInIntRange = allInIntRange && expect[j] >= long_min
+                            && expect[j] <= long_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_long(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_long(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);
+                        }
+                    } 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_LONG)
+                                && expect[j] >= long_min 
+				&& expect[j] <= long_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_LONG)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_float(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    float value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_FLOAT == 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_get_varm_float(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_float(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_float(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_float(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_get_varm_float(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_FLOAT);
+                    if (inRange3(expect[j],var_type[i],NCT_FLOAT)) {
+                        allInIntRange = allInIntRange && expect[j] >= float_min
+                            && expect[j] <= float_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_float(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_float(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);
+                        }
+                    } 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_FLOAT)
+                                && expect[j] >= float_min 
+				&& expect[j] <= float_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_FLOAT)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_double(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    double value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_DOUBLE == 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_get_varm_double(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_double(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_double(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_double(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_get_varm_double(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_DOUBLE);
+                    if (inRange3(expect[j],var_type[i],NCT_DOUBLE)) {
+                        allInIntRange = allInIntRange && expect[j] >= double_min
+                            && expect[j] <= double_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_double(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_double(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);
+                        }
+                    } 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_DOUBLE)
+                                && expect[j] >= double_min 
+				&& expect[j] <= double_max) {
+			    IF (!equal(value[j],expect[j],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[j]);
+                                    error("got: %g", (double) value[j]);
+                                }
+                            } else {
+                                nok++;
+                            }
+                        }
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_ushort(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    ushort value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_USHORT == 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_get_varm_ushort(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_ushort(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_ushort(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_ushort(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_get_varm_ushort(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_USHORT);
+                    if (inRange3(expect[j],var_type[i],NCT_USHORT)) {
+                        allInIntRange = allInIntRange && expect[j] >= ushort_min
+                            && expect[j] <= ushort_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_ushort(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_ushort(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);
+                        }
+                    } 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_USHORT)
+                                && expect[j] >= ushort_min 
+				&& expect[j] <= ushort_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_USHORT)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_uint(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    uint value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_UINT == 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_get_varm_uint(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_uint(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_uint(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_uint(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_get_varm_uint(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_UINT);
+                    if (inRange3(expect[j],var_type[i],NCT_UINT)) {
+                        allInIntRange = allInIntRange && expect[j] >= uint_min
+                            && expect[j] <= uint_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_uint(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_uint(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);
+                        }
+                    } 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_UINT)
+                                && expect[j] >= uint_min 
+				&& expect[j] <= uint_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_UINT)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_longlong(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    longlong value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_LONGLONG == 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_get_varm_longlong(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_longlong(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_longlong(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_longlong(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_get_varm_longlong(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_LONGLONG);
+                    if (inRange3(expect[j],var_type[i],NCT_LONGLONG)) {
+                        allInIntRange = allInIntRange && expect[j] >= longlong_min
+                            && expect[j] <= longlong_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_longlong(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_longlong(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);
+                        }
+                    } 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_LONGLONG)
+                                && expect[j] >= longlong_min 
+				&& expect[j] <= longlong_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_LONGLONG)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_varm_ulonglong(void)
+{
+    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 canConvert;     /* Both text or both numeric */
+    ulonglong value[MAX_NELS];
+    double expect[MAX_NELS];
+
+    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_ULONGLONG == 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_get_varm_ulonglong(BAD_ID, i, start, edge, stride, imap, value);
+        IF (err != NC_EBADID)
+            error("bad ncid: status = %d", err);
+        err = nc_get_varm_ulonglong(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++) {
+            start[j] = var_shape[i][j];
+            err = nc_get_varm_ulonglong(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);
+            start[j] = 0;
+            edge[j] = var_shape[i][j] + 1;
+            err = nc_get_varm_ulonglong(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_get_varm_ulonglong(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 */
+            /* 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;
+                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) {
+		    j = var_rank[i] - 1;
+		    imap[j] = 1;
+		    for (; j > 0; j--)
+			imap[j-1] = imap[j] * count[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_ULONGLONG);
+                    if (inRange3(expect[j],var_type[i],NCT_ULONGLONG)) {
+                        allInIntRange = allInIntRange && expect[j] >= ulonglong_min
+                            && expect[j] <= ulonglong_max;
+                    } else {
+                        allInExtRange = 0;
+                    }
+                }
+                if (var_rank[i] == 0 && i%2 )
+                    err = nc_get_varm_ulonglong(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_get_varm_ulonglong(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);
+                        }
+                    } 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_ULONGLONG)
+                                && expect[j] >= ulonglong_min 
+				&& expect[j] <= ulonglong_max) {
+			    IF (!equal(value[j],expect[j],var_type[i], NCT_ULONGLONG)){
+                                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);
+                }
+            }
+        }
+    }
+    err = nc_close(ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+
+
+
+void
+test_nc_get_att_text(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    text value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
+	    err = nc_get_att_text(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_text(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_text(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_TEXT);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_TEXT)) {
+                    allInIntRange = allInIntRange && expect[k] >= text_min
+                                && expect[k] <= text_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_text(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_TEXT)
+                            && expect[k] >= text_min && expect[k] <= text_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_TEXT)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_uchar(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    uchar value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
+	    err = nc_get_att_uchar(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_uchar(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_uchar(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_UCHAR);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UCHAR)) {
+                    allInIntRange = allInIntRange && expect[k] >= uchar_min
+                                && expect[k] <= uchar_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_uchar(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UCHAR)
+                            && expect[k] >= uchar_min && expect[k] <= uchar_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_UCHAR)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_schar(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    schar value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
+	    err = nc_get_att_schar(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_schar(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_schar(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_SCHAR);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SCHAR)) {
+                    allInIntRange = allInIntRange && expect[k] >= schar_min
+                                && expect[k] <= schar_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_schar(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SCHAR)
+                            && expect[k] >= schar_min && expect[k] <= schar_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_SCHAR)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_short(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    short value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
+	    err = nc_get_att_short(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_short(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_short(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_SHORT);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SHORT)) {
+                    allInIntRange = allInIntRange && expect[k] >= short_min
+                                && expect[k] <= short_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_short(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SHORT)
+                            && expect[k] >= short_min && expect[k] <= short_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_SHORT)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_int(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    int value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_INT == NCT_TEXT);
+	    err = nc_get_att_int(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_int(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_int(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_INT);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_INT)) {
+                    allInIntRange = allInIntRange && expect[k] >= int_min
+                                && expect[k] <= int_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_int(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_INT)
+                            && expect[k] >= int_min && expect[k] <= int_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_INT)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_long(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    long value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_LONG == NCT_TEXT);
+	    err = nc_get_att_long(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_long(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_long(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_LONG);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONG)) {
+                    allInIntRange = allInIntRange && expect[k] >= long_min
+                                && expect[k] <= long_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_long(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONG)
+                            && expect[k] >= long_min && expect[k] <= long_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_LONG)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_float(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    float value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
+	    err = nc_get_att_float(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_float(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_float(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_FLOAT);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_FLOAT)) {
+                    allInIntRange = allInIntRange && expect[k] >= float_min
+                                && expect[k] <= float_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_float(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_FLOAT)
+                            && expect[k] >= float_min && expect[k] <= float_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_FLOAT)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_double(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    double value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
+	    err = nc_get_att_double(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_double(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_double(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_DOUBLE);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_DOUBLE)) {
+                    allInIntRange = allInIntRange && expect[k] >= double_min
+                                && expect[k] <= double_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_double(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_DOUBLE)
+                            && expect[k] >= double_min && expect[k] <= double_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_DOUBLE)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_ushort(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    ushort value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_USHORT == NCT_TEXT);
+	    err = nc_get_att_ushort(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_ushort(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_ushort(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_USHORT);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_USHORT)) {
+                    allInIntRange = allInIntRange && expect[k] >= ushort_min
+                                && expect[k] <= ushort_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_ushort(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_USHORT)
+                            && expect[k] >= ushort_min && expect[k] <= ushort_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_USHORT)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_uint(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    uint value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_UINT == NCT_TEXT);
+	    err = nc_get_att_uint(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_uint(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_uint(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_UINT);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UINT)) {
+                    allInIntRange = allInIntRange && expect[k] >= uint_min
+                                && expect[k] <= uint_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_uint(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UINT)
+                            && expect[k] >= uint_min && expect[k] <= uint_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_UINT)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_longlong(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    longlong value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_LONGLONG == NCT_TEXT);
+	    err = nc_get_att_longlong(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_longlong(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_longlong(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_LONGLONG);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONGLONG)) {
+                    allInIntRange = allInIntRange && expect[k] >= longlong_min
+                                && expect[k] <= longlong_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_longlong(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONGLONG)
+                            && expect[k] >= longlong_min && expect[k] <= longlong_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_LONGLONG)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+void
+test_nc_get_att_ulonglong(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int allInExtRange;
+    int allInIntRange;
+    int canConvert;     /* Both text or both numeric */
+    ulonglong value[MAX_NELS];
+    double expect[MAX_NELS];
+    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++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_ULONGLONG == NCT_TEXT);
+	    err = nc_get_att_ulonglong(BAD_ID, i, ATT_NAME(i,j), value);
+	    IF (err != NC_EBADID) 
+		error("bad ncid: status = %d", err);
+	    err = nc_get_att_ulonglong(ncid, BAD_VARID, ATT_NAME(i,j), value);
+	    IF (err != NC_ENOTVAR) 
+		error("bad var id: status = %d", err);
+	    err = nc_get_att_ulonglong(ncid, i, "noSuch", value);
+	    IF (err != NC_ENOTATT) 
+		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_ULONGLONG);
+                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_ULONGLONG)) {
+                    allInIntRange = allInIntRange && expect[k] >= ulonglong_min
+                                && expect[k] <= ulonglong_max;
+                } else {
+                    allInExtRange = 0;
+                }
+	    }
+	    err = nc_get_att_ulonglong(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));
+                    } 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 (k = 0; k < ATT_LEN(i,j); k++) {
+		    if (inRange3(expect[k],ATT_TYPE(i,j),NCT_ULONGLONG)
+                            && expect[k] >= ulonglong_min && expect[k] <= ulonglong_max) {
+			IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_ULONGLONG)){
+			    error("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++;
+                        }
+		    }
+		}
+	    } else {
+		IF (err != NC_ECHAR)
+		    error("wrong type: status = %d", err);
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err)
+	error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+
diff --git a/nc_test/test_put.c b/nc_test/test_put.c
index 470ba9f..f08a063 100644
--- a/nc_test/test_put.c
+++ b/nc_test/test_put.c
@@ -1,11942 +1,11942 @@
-/* Do not edit this file. It is produced from the corresponding .m4 source */
-/*********************************************************************
- *   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 <mpi.h>
-#endif
-
-
-#include "tests.h"
-
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_text(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = text_min;
-    const double max = text_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_uchar(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = uchar_min;
-    const double max = uchar_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_schar(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = schar_min;
-    const double max = schar_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_short(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = short_min;
-    const double max = short_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_int(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = int_min;
-    const double max = int_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_long(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = long_min;
-    const double max = long_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_float(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = float_min;
-    const double max = float_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_double(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = double_min;
-    const double max = double_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_ushort(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = ushort_min;
-    const double max = ushort_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_uint(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = uint_min;
-    const double max = uint_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_longlong(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = longlong_min;
-    const double max = longlong_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-/*
- *  ensure hash value within range for internal TYPE
- */
-static
-double
-hash_ulonglong(
-    const nc_type type,
-    const int rank,
-    const size_t *index,
-    const nct_itype itype)
-{
-    const double min = ulonglong_min;
-    const double max = ulonglong_max;
-
-    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
-}
-
-
-
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_text(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    text value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_TEXT == 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_TEXT);
-		err = nc_get_var1_text(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_TEXT)) {
-                    if (expect >= text_min && expect <= text_max) {
-			IF (err) {
-			    error("nc_get_var1_text: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_TEXT)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_uchar(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    uchar value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_UCHAR == 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_UCHAR);
-		err = nc_get_var1_uchar(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_UCHAR)) {
-                    if (expect >= uchar_min && expect <= uchar_max) {
-			IF (err) {
-			    error("nc_get_var1_uchar: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_UCHAR)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_schar(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    schar value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_SCHAR == 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_SCHAR);
-		err = nc_get_var1_schar(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_SCHAR)) {
-                    if (expect >= schar_min && expect <= schar_max) {
-			IF (err) {
-			    error("nc_get_var1_schar: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_SCHAR)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_short(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    short value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_SHORT == 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_SHORT);
-		err = nc_get_var1_short(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_SHORT)) {
-                    if (expect >= short_min && expect <= short_max) {
-			IF (err) {
-			    error("nc_get_var1_short: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_SHORT)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_int(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    int value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_INT == 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_INT);
-		err = nc_get_var1_int(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_INT)) {
-                    if (expect >= int_min && expect <= int_max) {
-			IF (err) {
-			    error("nc_get_var1_int: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_INT)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_long(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    long value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_LONG == 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_LONG);
-		err = nc_get_var1_long(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_LONG)) {
-                    if (expect >= long_min && expect <= long_max) {
-			IF (err) {
-			    error("nc_get_var1_long: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_LONG)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_float(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    float value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_FLOAT == 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_FLOAT);
-		err = nc_get_var1_float(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_FLOAT)) {
-                    if (expect >= float_min && expect <= float_max) {
-			IF (err) {
-			    error("nc_get_var1_float: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_FLOAT)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_double(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    double value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_DOUBLE == 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_DOUBLE);
-		err = nc_get_var1_double(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_DOUBLE)) {
-                    if (expect >= double_min && expect <= double_max) {
-			IF (err) {
-			    error("nc_get_var1_double: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_DOUBLE)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_ushort(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    ushort value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_USHORT == 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_USHORT);
-		err = nc_get_var1_ushort(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_USHORT)) {
-                    if (expect >= ushort_min && expect <= ushort_max) {
-			IF (err) {
-			    error("nc_get_var1_ushort: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_USHORT)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_uint(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    uint value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_UINT == 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_UINT);
-		err = nc_get_var1_uint(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_UINT)) {
-                    if (expect >= uint_min && expect <= uint_max) {
-			IF (err) {
-			    error("nc_get_var1_uint: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_UINT)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_longlong(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    longlong value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_LONGLONG == 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_LONGLONG);
-		err = nc_get_var1_longlong(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_LONGLONG)) {
-                    if (expect >= longlong_min && expect <= longlong_max) {
-			IF (err) {
-			    error("nc_get_var1_longlong: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_LONGLONG)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-/* 
- *  check all vars in file which are (text/numeric) compatible with TYPE
- */
-static
-void
-check_vars_ulonglong(const char *filename)
-{
-    int  ncid;                  /* netCDF id */
-    size_t index[MAX_RANK];
-    int  err;           /* status */
-    int  d;
-    int  i;
-    size_t  j;
-    ulonglong value;
-    nc_type datatype;
-    int ndims;
-    int dimids[MAX_RANK];
-    double expect;
-    char name[NC_MAX_NAME];
-    size_t length;
-    int canConvert;     /* Both text or both numeric */
-    int nok = 0;      /* count of valid comparisons */
-
-    err = file_open(filename, 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_ULONGLONG == 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_ULONGLONG);
-		err = nc_get_var1_ulonglong(ncid, i, index, &value);
-		if (inRange3(expect,datatype,NCT_ULONGLONG)) {
-                    if (expect >= ulonglong_min && expect <= ulonglong_max) {
-			IF (err) {
-			    error("nc_get_var1_ulonglong: %s", nc_strerror(err));
-			} else {
-                            IF (!equal(value,expect,var_type[i],NCT_ULONGLONG)) {
-				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;
-			    }
-			}
-		    }
-		}
-	    }
-	}
-    }
-    err = nc_close (ncid);
-    IF (err)
-        error("nc_close: %s", nc_strerror(err));
-    print_nok(nok);
-}
-
-
-
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_text(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    text value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_TEXT == 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_TEXT);
-		    if (inRange3(expect[k], datatype, NCT_TEXT)) {
-			++nInExtRange;
-			if (expect[k] >= text_min && expect[k] <= text_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_text(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_TEXT)
-                            && expect[k] >= text_min && expect[k] <= text_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_TEXT)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_uchar(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    uchar value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_UCHAR == 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_UCHAR);
-		    if (inRange3(expect[k], datatype, NCT_UCHAR)) {
-			++nInExtRange;
-			if (expect[k] >= uchar_min && expect[k] <= uchar_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_uchar(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_UCHAR)
-                            && expect[k] >= uchar_min && expect[k] <= uchar_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_UCHAR)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_schar(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    schar value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SCHAR == 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_SCHAR);
-		    if (inRange3(expect[k], datatype, NCT_SCHAR)) {
-			++nInExtRange;
-			if (expect[k] >= schar_min && expect[k] <= schar_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_schar(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_SCHAR)
-                            && expect[k] >= schar_min && expect[k] <= schar_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_SCHAR)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_short(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    short value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SHORT == 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_SHORT);
-		    if (inRange3(expect[k], datatype, NCT_SHORT)) {
-			++nInExtRange;
-			if (expect[k] >= short_min && expect[k] <= short_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_short(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_SHORT)
-                            && expect[k] >= short_min && expect[k] <= short_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_SHORT)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_int(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    int value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_INT == 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_INT);
-		    if (inRange3(expect[k], datatype, NCT_INT)) {
-			++nInExtRange;
-			if (expect[k] >= int_min && expect[k] <= int_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_int(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_INT)
-                            && expect[k] >= int_min && expect[k] <= int_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_INT)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_long(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    long value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_LONG == 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_LONG);
-		    if (inRange3(expect[k], datatype, NCT_LONG)) {
-			++nInExtRange;
-			if (expect[k] >= long_min && expect[k] <= long_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_long(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_LONG)
-                            && expect[k] >= long_min && expect[k] <= long_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_LONG)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_float(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    float value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_FLOAT == 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_FLOAT);
-		    if (inRange3(expect[k], datatype, NCT_FLOAT)) {
-			++nInExtRange;
-			if (expect[k] >= float_min && expect[k] <= float_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_float(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_FLOAT)
-                            && expect[k] >= float_min && expect[k] <= float_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_FLOAT)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_double(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    double value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_DOUBLE == 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_DOUBLE);
-		    if (inRange3(expect[k], datatype, NCT_DOUBLE)) {
-			++nInExtRange;
-			if (expect[k] >= double_min && expect[k] <= double_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_double(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_DOUBLE)
-                            && expect[k] >= double_min && expect[k] <= double_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_DOUBLE)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_ushort(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    ushort value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_USHORT == 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_USHORT);
-		    if (inRange3(expect[k], datatype, NCT_USHORT)) {
-			++nInExtRange;
-			if (expect[k] >= ushort_min && expect[k] <= ushort_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_ushort(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_USHORT)
-                            && expect[k] >= ushort_min && expect[k] <= ushort_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_USHORT)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_uint(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    uint value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_UINT == 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_UINT);
-		    if (inRange3(expect[k], datatype, NCT_UINT)) {
-			++nInExtRange;
-			if (expect[k] >= uint_min && expect[k] <= uint_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_uint(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_UINT)
-                            && expect[k] >= uint_min && expect[k] <= uint_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_UINT)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_longlong(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    longlong value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_LONGLONG == 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_LONGLONG);
-		    if (inRange3(expect[k], datatype, NCT_LONGLONG)) {
-			++nInExtRange;
-			if (expect[k] >= longlong_min && expect[k] <= longlong_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_longlong(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_LONGLONG)
-                            && expect[k] >= longlong_min && expect[k] <= longlong_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_LONGLONG)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-/* 
- *  check all attributes in file which are (text/numeric) compatible with TYPE
- *  ignore any attributes containing values outside range of TYPE
- */
-static
-void
-check_atts_ulonglong(int  ncid)
-{
-    int  err;           /* status */
-    int  i;
-    int  j;
-    size_t  k;
-    ulonglong value[MAX_NELS];
-    nc_type datatype;
-    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 */
-
-    for (i = -1; i < numVars; i++) {
-        for (j = 0; j < NATTS(i); j++) {
-	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_ULONGLONG == 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_ULONGLONG);
-		    if (inRange3(expect[k], datatype, NCT_ULONGLONG)) {
-			++nInExtRange;
-			if (expect[k] >= ulonglong_min && expect[k] <= ulonglong_max)
-			    ++nInIntRange;
-		    }
-		}
-		err = nc_get_att_ulonglong(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);
-                }
-		for (k = 0; k < length; k++) {
-                    if (inRange3(expect[k],datatype,NCT_ULONGLONG)
-                            && expect[k] >= ulonglong_min && expect[k] <= ulonglong_max) {
-                        IF (!equal(value[k],expect[k],datatype,NCT_ULONGLONG)) {
-                            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++;
-                        }
-                    }
-                }
-            }                                               
-        }
-    }
-
-    print_nok(nok);
-}
-
-
-
-
-void
-test_nc_put_var1_text(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    text 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_text(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_text(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_text(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_text( var_type[i], var_rank[i], index, NCT_TEXT);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_text(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_text(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_TEXT)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_text(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_uchar(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    uchar 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_uchar(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_uchar(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_uchar(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_uchar( var_type[i], var_rank[i], index, NCT_UCHAR);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_uchar(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_uchar(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_UCHAR)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uchar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_schar(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    schar 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_schar(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_schar(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_schar(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_schar( var_type[i], var_rank[i], index, NCT_SCHAR);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_schar(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_schar(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_SCHAR)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_schar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_short(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    short 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_short(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_short(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_short(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_short( var_type[i], var_rank[i], index, NCT_SHORT);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_short(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_short(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_SHORT)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_short(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_int(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_int(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_int(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_int(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_int( var_type[i], var_rank[i], index, NCT_INT);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_int(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_int(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_INT)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_int(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_long(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    long 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_long(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_long(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_long(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_long( var_type[i], var_rank[i], index, NCT_LONG);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_long(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_long(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_LONG)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_long(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_float(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    float 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_float(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_float(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_float(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_float( var_type[i], var_rank[i], index, NCT_FLOAT);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_float(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_float(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_FLOAT)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_float(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_double(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    double 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_double(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_double(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_double(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_double( var_type[i], var_rank[i], index, NCT_DOUBLE);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_double(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_double(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_DOUBLE)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_double(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_ushort(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    ushort 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_ushort(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_ushort(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_ushort(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_ushort( var_type[i], var_rank[i], index, NCT_USHORT);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_ushort(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_ushort(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_USHORT)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ushort(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_uint(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    uint 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_uint(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_uint(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_uint(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_uint( var_type[i], var_rank[i], index, NCT_UINT);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_uint(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_uint(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_UINT)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uint(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_longlong(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    longlong 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_longlong(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_longlong(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_longlong(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_longlong( var_type[i], var_rank[i], index, NCT_LONGLONG);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_longlong(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_longlong(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_LONGLONG)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_longlong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var1_ulonglong(void)
-{
-    int ncid;
-    int i;
-    int j;
-    int err;
-    size_t index[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    ulonglong 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;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-    err = nc_enddef(ncid);
-    IF (err)
-        error("nc_enddef: %s", nc_strerror(err));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == NCT_TEXT);
-        for (j = 0; j < var_rank[i]; j++)
-            index[j] = 0;
-        err = nc_put_var1_ulonglong(BAD_ID, i, index, &value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var1_ulonglong(ncid, BAD_VARID, index, &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 */
-		index[j] = var_shape[i][j];
-		err = nc_put_var1_ulonglong(ncid, i, index, &value);
-		IF (canConvert && 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");
-            value = hash_ulonglong( var_type[i], var_rank[i], index, NCT_ULONGLONG);
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_var1_ulonglong(ncid, i, NULL, &value);
-	    else
-		err = nc_put_var1_ulonglong(ncid, i, index, &value);
-	    if (canConvert) {
-		if (inRange3(value, var_type[i],NCT_ULONGLONG)) {
-		    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);
-            }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ulonglong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-
-
-
-void
-test_nc_put_var_text(void)
-{
-    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? */
-    text value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_text(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_text(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_text(var_type[i], var_rank[i], index, NCT_TEXT);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_TEXT);
-	}
-        err = nc_put_var_text(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_TEXT == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_text(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_text(var_type[i], var_rank[i], index, NCT_TEXT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_TEXT);
-	    }
-	    err = nc_put_var_text(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_text(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_uchar(void)
-{
-    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? */
-    uchar value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_uchar(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_uchar(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_uchar(var_type[i], var_rank[i], index, NCT_UCHAR);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_UCHAR);
-	}
-        err = nc_put_var_uchar(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_UCHAR == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_uchar(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_uchar(var_type[i], var_rank[i], index, NCT_UCHAR);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_UCHAR);
-	    }
-	    err = nc_put_var_uchar(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uchar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_schar(void)
-{
-    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? */
-    schar value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_schar(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_schar(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_schar(var_type[i], var_rank[i], index, NCT_SCHAR);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_SCHAR);
-	}
-        err = nc_put_var_schar(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_SCHAR == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_schar(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_schar(var_type[i], var_rank[i], index, NCT_SCHAR);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_SCHAR);
-	    }
-	    err = nc_put_var_schar(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_schar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_short(void)
-{
-    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? */
-    short value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_short(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_short(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_short(var_type[i], var_rank[i], index, NCT_SHORT);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_SHORT);
-	}
-        err = nc_put_var_short(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_SHORT == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_short(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_short(var_type[i], var_rank[i], index, NCT_SHORT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_SHORT);
-	    }
-	    err = nc_put_var_short(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_short(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_int(void)
-{
-    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 value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_int(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_int(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_int(var_type[i], var_rank[i], index, NCT_INT);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_INT);
-	}
-        err = nc_put_var_int(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_INT == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_int(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_int(var_type[i], var_rank[i], index, NCT_INT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_INT);
-	    }
-	    err = nc_put_var_int(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_int(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_long(void)
-{
-    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? */
-    long value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_long(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_long(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_long(var_type[i], var_rank[i], index, NCT_LONG);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_LONG);
-	}
-        err = nc_put_var_long(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_LONG == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_long(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_long(var_type[i], var_rank[i], index, NCT_LONG);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_LONG);
-	    }
-	    err = nc_put_var_long(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_long(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_float(void)
-{
-    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? */
-    float value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_float(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_float(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_float(var_type[i], var_rank[i], index, NCT_FLOAT);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_FLOAT);
-	}
-        err = nc_put_var_float(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_FLOAT == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_float(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_float(var_type[i], var_rank[i], index, NCT_FLOAT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_FLOAT);
-	    }
-	    err = nc_put_var_float(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_float(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_double(void)
-{
-    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? */
-    double value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_double(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_double(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_double(var_type[i], var_rank[i], index, NCT_DOUBLE);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_DOUBLE);
-	}
-        err = nc_put_var_double(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_DOUBLE == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_double(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_double(var_type[i], var_rank[i], index, NCT_DOUBLE);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_DOUBLE);
-	    }
-	    err = nc_put_var_double(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_double(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_ushort(void)
-{
-    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? */
-    ushort value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_ushort(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_ushort(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_ushort(var_type[i], var_rank[i], index, NCT_USHORT);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_USHORT);
-	}
-        err = nc_put_var_ushort(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_USHORT == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_ushort(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_ushort(var_type[i], var_rank[i], index, NCT_USHORT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_USHORT);
-	    }
-	    err = nc_put_var_ushort(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ushort(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_uint(void)
-{
-    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? */
-    uint value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_uint(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_uint(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_uint(var_type[i], var_rank[i], index, NCT_UINT);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_UINT);
-	}
-        err = nc_put_var_uint(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_UINT == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_uint(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_uint(var_type[i], var_rank[i], index, NCT_UINT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_UINT);
-	    }
-	    err = nc_put_var_uint(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uint(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_longlong(void)
-{
-    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? */
-    longlong value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_longlong(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_longlong(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_longlong(var_type[i], var_rank[i], index, NCT_LONGLONG);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_LONGLONG);
-	}
-        err = nc_put_var_longlong(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_LONGLONG == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_longlong(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_longlong(var_type[i], var_rank[i], index, NCT_LONGLONG);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_LONGLONG);
-	    }
-	    err = nc_put_var_longlong(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_longlong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_var_ulonglong(void)
-{
-    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? */
-    ulonglong value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == NCT_TEXT);
-        assert(var_rank[i] <= MAX_RANK);
-        assert(var_nels[i] <= MAX_NELS);
-        err = nc_put_var_ulonglong(BAD_ID, i, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_var_ulonglong(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_ulonglong(var_type[i], var_rank[i], index, NCT_ULONGLONG);
-	    allInExtRange = allInExtRange 
-		&& inRange3(value[j], var_type[i], NCT_ULONGLONG);
-	}
-        err = nc_put_var_ulonglong(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);
-	}
-    }
-
-        /* 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));
-    index[0] = NRECS-1;
-    err = nc_put_var1_text(ncid, varid, index, "x");
-    IF (err)
-        error("nc_put_var1_text: %s", nc_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_ULONGLONG == NCT_TEXT);
-	    assert(var_rank[i] <= MAX_RANK);
-	    assert(var_nels[i] <= MAX_NELS);
-	    err = nc_put_var_ulonglong(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_ulonglong(var_type[i], var_rank[i], index, NCT_ULONGLONG);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_ULONGLONG);
-	    }
-	    err = nc_put_var_ulonglong(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);
-	    }
-        }
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ulonglong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-
-
-
-void
-test_nc_put_vara_text(void)
-{
-    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? */
-    text value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == 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_put_vara_text(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_text(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_text(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_text(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_text(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_text(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_text(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_text(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 */
-	    /* 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];
-	    }
-            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_text(var_type[i], var_rank[i], index, NCT_TEXT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_TEXT);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_text(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_text(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_text(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_uchar(void)
-{
-    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? */
-    uchar value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == 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_put_vara_uchar(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_uchar(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_uchar(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_uchar(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_uchar(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_uchar(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_uchar(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_uchar(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 */
-	    /* 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];
-	    }
-            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_uchar(var_type[i], var_rank[i], index, NCT_UCHAR);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_UCHAR);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_uchar(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_uchar(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uchar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_schar(void)
-{
-    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? */
-    schar value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == 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_put_vara_schar(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_schar(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_schar(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_schar(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_schar(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_schar(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_schar(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_schar(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 */
-	    /* 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];
-	    }
-            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_schar(var_type[i], var_rank[i], index, NCT_SCHAR);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_SCHAR);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_schar(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_schar(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_schar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_short(void)
-{
-    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? */
-    short value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == 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_put_vara_short(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_short(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_short(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_short(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_short(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_short(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_short(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_short(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 */
-	    /* 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];
-	    }
-            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_short(var_type[i], var_rank[i], index, NCT_SHORT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_SHORT);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_short(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_short(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_short(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_int(void)
-{
-    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 value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == 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_put_vara_int(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_int(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_int(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_int(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_int(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_int(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_int(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_int(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 */
-	    /* 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];
-	    }
-            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_int(var_type[i], var_rank[i], index, NCT_INT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_INT);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_int(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_int(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_int(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_long(void)
-{
-    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? */
-    long value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == 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_put_vara_long(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_long(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_long(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_long(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_long(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_long(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_long(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_long(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 */
-	    /* 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];
-	    }
-            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_long(var_type[i], var_rank[i], index, NCT_LONG);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_LONG);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_long(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_long(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_long(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_float(void)
-{
-    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? */
-    float value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == 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_put_vara_float(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_float(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_float(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_float(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_float(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_float(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_float(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_float(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 */
-	    /* 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];
-	    }
-            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_float(var_type[i], var_rank[i], index, NCT_FLOAT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_FLOAT);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_float(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_float(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_float(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_double(void)
-{
-    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? */
-    double value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == 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_put_vara_double(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_double(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_double(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_double(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_double(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_double(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_double(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_double(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 */
-	    /* 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];
-	    }
-            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_double(var_type[i], var_rank[i], index, NCT_DOUBLE);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_DOUBLE);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_double(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_double(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_double(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_ushort(void)
-{
-    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? */
-    ushort value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == 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_put_vara_ushort(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_ushort(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_ushort(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_ushort(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_ushort(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_ushort(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_ushort(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_ushort(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 */
-	    /* 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];
-	    }
-            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_ushort(var_type[i], var_rank[i], index, NCT_USHORT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_USHORT);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_ushort(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_ushort(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ushort(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_uint(void)
-{
-    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? */
-    uint value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == 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_put_vara_uint(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_uint(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_uint(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_uint(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_uint(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_uint(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_uint(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_uint(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 */
-	    /* 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];
-	    }
-            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_uint(var_type[i], var_rank[i], index, NCT_UINT);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_UINT);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_uint(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_uint(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uint(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_longlong(void)
-{
-    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? */
-    longlong value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == 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_put_vara_longlong(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_longlong(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_longlong(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_longlong(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_longlong(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_longlong(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_longlong(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_longlong(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 */
-	    /* 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];
-	    }
-            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_longlong(var_type[i], var_rank[i], index, NCT_LONGLONG);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_LONGLONG);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_longlong(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_longlong(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_longlong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vara_ulonglong(void)
-{
-    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? */
-    ulonglong value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    value[0] = 0;
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == 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_put_vara_ulonglong(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_ulonglong(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_ulonglong(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_ulonglong(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EEDGE)
-		    error("bad edge: status = %d", err);
-		edge[j] = 1;
-	    }
-        }
-            /* Check correct error returned even when nothing to put */
-        for (j = 0; j < var_rank[i]; j++) {
-            edge[j] = 0;
-	}
-        err = nc_put_vara_ulonglong(BAD_ID, i, start, edge, value);
-        IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-        err = nc_put_vara_ulonglong(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_ulonglong(ncid, i, start, edge, value);
-		IF (canConvert && err != NC_EINVALCOORDS)
-		    error("bad start: status = %d", err);
-		start[j] = 0;
-	    }
-        }
-
-/* 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_ulonglong(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 */
-	    /* 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];
-	    }
-            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_ulonglong(var_type[i], var_rank[i], index, NCT_ULONGLONG);
-		allInExtRange = allInExtRange 
-		    && inRange3(value[j], var_type[i], NCT_ULONGLONG);
-	    }
-	    if (var_rank[i] == 0 && i%2 == 0)
-		err = nc_put_vara_ulonglong(ncid, i, NULL, NULL, value);
-	    else
-		err = nc_put_vara_ulonglong(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 = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ulonglong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-
-
-
-void
-test_nc_put_vars_text(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    text value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == 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_text(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_text(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_text(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_text(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_text(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_text(var_type[i], var_rank[i], index2, 
-			NCT_TEXT);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_TEXT);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_text(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_text(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_text(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_uchar(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    uchar value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == 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_uchar(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_uchar(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_uchar(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_uchar(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_uchar(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_uchar(var_type[i], var_rank[i], index2, 
-			NCT_UCHAR);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_UCHAR);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_uchar(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_uchar(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uchar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_schar(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    schar value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == 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_schar(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_schar(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_schar(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_schar(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_schar(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_schar(var_type[i], var_rank[i], index2, 
-			NCT_SCHAR);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_SCHAR);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_schar(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_schar(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_schar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_short(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    short value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == 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_short(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_short(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_short(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_short(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_short(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_short(var_type[i], var_rank[i], index2, 
-			NCT_SHORT);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_SHORT);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_short(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_short(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_short(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_int(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    int value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == 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_int(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_int(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_int(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_int(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_int(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_int(var_type[i], var_rank[i], index2, 
-			NCT_INT);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_INT);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_int(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_int(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_int(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_long(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    long value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == 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_long(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_long(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_long(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_long(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_long(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_long(var_type[i], var_rank[i], index2, 
-			NCT_LONG);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_LONG);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_long(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_long(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_long(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_float(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    float value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == 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_float(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_float(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_float(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_float(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_float(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_float(var_type[i], var_rank[i], index2, 
-			NCT_FLOAT);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_FLOAT);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_float(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_float(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_float(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_double(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    double value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == 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_double(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_double(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_double(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_double(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_double(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_double(var_type[i], var_rank[i], index2, 
-			NCT_DOUBLE);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_DOUBLE);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_double(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_double(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_double(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_ushort(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    ushort value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == 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_ushort(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_ushort(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_ushort(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_ushort(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_ushort(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_ushort(var_type[i], var_rank[i], index2, 
-			NCT_USHORT);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_USHORT);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_ushort(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_ushort(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ushort(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_uint(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    uint value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == 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_uint(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_uint(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_uint(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_uint(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_uint(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_uint(var_type[i], var_rank[i], index2, 
-			NCT_UINT);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_UINT);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_uint(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_uint(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uint(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_longlong(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    longlong value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == 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_longlong(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_longlong(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_longlong(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_longlong(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_longlong(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_longlong(var_type[i], var_rank[i], index2, 
-			NCT_LONGLONG);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_LONGLONG);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_longlong(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_longlong(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_longlong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_vars_ulonglong(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];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    ulonglong value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == 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_ulonglong(BAD_ID, i, start, edge, stride, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_vars_ulonglong(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_ulonglong(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_ulonglong(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_ulonglong(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 */
-/* TODO
-		if ( roll(2) ) {
-		    for (j = 0; j < var_rank[i]; j++) {
-			index[j] += (count[j] - 1) * 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_ulonglong(var_type[i], var_rank[i], index2, 
-			NCT_ULONGLONG);
-		    allInExtRange = allInExtRange 
-			&& inRange3(value[j], var_type[i], NCT_ULONGLONG);
-		}
-		if (var_rank[i] == 0 && i%2 == 0)
-		    err = nc_put_vars_ulonglong(ncid, i, NULL, NULL, stride, value);
-		else
-		    err = nc_put_vars_ulonglong(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);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ulonglong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-	error("remove of %s failed", scratch);
-}
-
-
-
-
-void
-test_nc_put_varm_text(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    text value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == 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_text(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_text(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_text(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_text(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_text(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_text(var_type[i], var_rank[i], index2,
-                        NCT_TEXT);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_TEXT);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_text(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_text(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_text(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_uchar(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    uchar value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == 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_uchar(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_uchar(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_uchar(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_uchar(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_uchar(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_uchar(var_type[i], var_rank[i], index2,
-                        NCT_UCHAR);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_UCHAR);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_uchar(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_uchar(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uchar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_schar(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    schar value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == 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_schar(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_schar(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_schar(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_schar(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_schar(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_schar(var_type[i], var_rank[i], index2,
-                        NCT_SCHAR);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_SCHAR);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_schar(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_schar(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_schar(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_short(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    short value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == 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_short(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_short(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_short(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_short(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_short(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_short(var_type[i], var_rank[i], index2,
-                        NCT_SHORT);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_SHORT);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_short(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_short(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_short(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_int(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    int value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == 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_int(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_int(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_int(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_int(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_int(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_int(var_type[i], var_rank[i], index2,
-                        NCT_INT);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_INT);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_int(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_int(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_int(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_long(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    long value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == 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_long(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_long(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_long(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_long(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_long(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_long(var_type[i], var_rank[i], index2,
-                        NCT_LONG);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_LONG);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_long(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_long(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_long(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_float(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    float value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == 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_float(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_float(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_float(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_float(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_float(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_float(var_type[i], var_rank[i], index2,
-                        NCT_FLOAT);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_FLOAT);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_float(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_float(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_float(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_double(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    double value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == 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_double(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_double(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_double(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_double(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_double(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_double(var_type[i], var_rank[i], index2,
-                        NCT_DOUBLE);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_DOUBLE);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_double(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_double(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_double(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_ushort(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    ushort value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == 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_ushort(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_ushort(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_ushort(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_ushort(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_ushort(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_ushort(var_type[i], var_rank[i], index2,
-                        NCT_USHORT);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_USHORT);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_ushort(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_ushort(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ushort(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_uint(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    uint value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == 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_uint(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_uint(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_uint(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_uint(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_uint(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_uint(var_type[i], var_rank[i], index2,
-                        NCT_UINT);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_UINT);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_uint(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_uint(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_uint(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_longlong(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    longlong value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == 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_longlong(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_longlong(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_longlong(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_longlong(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_longlong(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_longlong(var_type[i], var_rank[i], index2,
-                        NCT_LONGLONG);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_LONGLONG);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_longlong(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_longlong(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_longlong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-void
-test_nc_put_varm_ulonglong(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];
-    ptrdiff_t imap[MAX_RANK];
-    int canConvert;	/* Both text or both numeric */
-    int allInExtRange;	/* all values within external range? */
-    ulonglong value[MAX_NELS];
-
-    err = file_create(scratch, NC_CLOBBER, &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));
-
-#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
-
-    for (i = 0; i < numVars; i++) {
-	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == 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_ulonglong(BAD_ID, i, start, edge, stride, imap, value);
-	IF (err != NC_EBADID) 
-	    error("bad ncid: status = %d", err);
-	err = nc_put_varm_ulonglong(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_ulonglong(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_ulonglong(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_ulonglong(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];
-	    }
-            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) {
-                    j = var_rank[i] - 1;
-                    imap[j] = 1;
-                    for (; j > 0; j--)
-                        imap[j-1] = imap[j] * count[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_ulonglong(var_type[i], var_rank[i], index2,
-                        NCT_ULONGLONG);
-                    allInExtRange = allInExtRange
-                        && inRange3(value[j], var_type[i], NCT_ULONGLONG);
-                }
-                if (var_rank[i] == 0 && i%2 == 0)
-                    err = nc_put_varm_ulonglong(ncid,i,NULL,NULL,NULL,NULL,value);
-                else
-                    err = nc_put_varm_ulonglong(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);
-                    }
-                } else {
-                    IF (nels > 0 && err != NC_ECHAR)
-                        error("wrong type: status = %d", err);
-		}
-	    }
-	}
-    }
-
-    err = nc_close(ncid);
-    IF (err) 
-	error("nc_close: %s", nc_strerror(err));
-
-    check_vars_ulonglong(scratch);
-
-    err = remove(scratch);
-    IF (err)
-        error("remove of %s failed", scratch);
-}
-
-
-
-void
-test_nc_put_att_text(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    text value[MAX_NELS];
-
-    err = file_create(scratch, NC_NOCLOBBER, &ncid);
-    IF (err) {
-        error("nc_create: %s", nc_strerror(err));
-        return;
-    }
-    def_dims(ncid);
-    def_vars(ncid);
-
-    {
-	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);
-    }
-    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));
-		}
-	    }
-        }
-    }
-
-    check_atts_text(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_uchar(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    uchar value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_uchar(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_uchar(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_uchar(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_uchar(ATT_TYPE(i,j), -1, &k, NCT_UCHAR);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_UCHAR);
-		}
-		err = nc_put_att_uchar(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_uchar(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_schar(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    schar value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_schar(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_schar(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_schar(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_schar(ATT_TYPE(i,j), -1, &k, NCT_SCHAR);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_SCHAR);
-		}
-		err = nc_put_att_schar(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_schar(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_short(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    short value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_short(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_short(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_short(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_short(ATT_TYPE(i,j), -1, &k, NCT_SHORT);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_SHORT);
-		}
-		err = nc_put_att_short(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_short(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_int(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    int value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_int(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_int(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_int(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_int(ATT_TYPE(i,j), -1, &k, NCT_INT);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_INT);
-		}
-		err = nc_put_att_int(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_int(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_long(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    long value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_long(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_long(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_long(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_long(ATT_TYPE(i,j), -1, &k, NCT_LONG);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_LONG);
-		}
-		err = nc_put_att_long(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_long(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_float(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    float value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_float(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_float(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_float(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_float(ATT_TYPE(i,j), -1, &k, NCT_FLOAT);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_FLOAT);
-		}
-		err = nc_put_att_float(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_float(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_double(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    double value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_double(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_double(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_double(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_double(ATT_TYPE(i,j), -1, &k, NCT_DOUBLE);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_DOUBLE);
-		}
-		err = nc_put_att_double(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_double(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_ushort(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    ushort value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_ushort(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_ushort(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_ushort(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_ushort(ATT_TYPE(i,j), -1, &k, NCT_USHORT);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_USHORT);
-		}
-		err = nc_put_att_ushort(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_ushort(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_uint(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    uint value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_uint(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_uint(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_uint(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_uint(ATT_TYPE(i,j), -1, &k, NCT_UINT);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_UINT);
-		}
-		err = nc_put_att_uint(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_uint(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_longlong(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    longlong value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_longlong(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_longlong(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_longlong(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_longlong(ATT_TYPE(i,j), -1, &k, NCT_LONGLONG);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_LONGLONG);
-		}
-		err = nc_put_att_longlong(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_longlong(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_ulonglong(void)
-{
-    int ncid;
-    int i;
-    int j;
-    size_t k;
-    int err;
-    ulonglong value[MAX_NELS];
-    int allInExtRange;  /* all values within external range? */
-
-    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++) {
-        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_ulonglong(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_ulonglong(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_ulonglong(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_ulonglong(ATT_TYPE(i,j), -1, &k, NCT_ULONGLONG);
-		    allInExtRange = allInExtRange
-			&& inRange3(value[k], ATT_TYPE(i,j), NCT_ULONGLONG);
-		}
-		err = nc_put_att_ulonglong(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);
-		}
-	    }
-        }
-    }
-
-    check_atts_ulonglong(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);
-}
-
-
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+/*********************************************************************
+ *   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 <mpi.h>
+#endif
+
+
+#include "tests.h"
+
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_text(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = text_min;
+    const double max = text_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_uchar(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = uchar_min;
+    const double max = uchar_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_schar(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = schar_min;
+    const double max = schar_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_short(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = short_min;
+    const double max = short_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_int(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = int_min;
+    const double max = int_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_long(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = long_min;
+    const double max = long_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_float(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = float_min;
+    const double max = float_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_double(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = double_min;
+    const double max = double_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_ushort(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = ushort_min;
+    const double max = ushort_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_uint(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = uint_min;
+    const double max = uint_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_longlong(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = longlong_min;
+    const double max = longlong_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+/*
+ *  ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_ulonglong(
+    const nc_type type,
+    const int rank,
+    const size_t *index,
+    const nct_itype itype)
+{
+    const double min = ulonglong_min;
+    const double max = ulonglong_max;
+
+    return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+
+
+
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_text(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    text value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_TEXT == 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_TEXT);
+		err = nc_get_var1_text(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_TEXT)) {
+                    if (expect >= text_min && expect <= text_max) {
+			IF (err) {
+			    error("nc_get_var1_text: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_TEXT)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_uchar(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    uchar value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_UCHAR == 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_UCHAR);
+		err = nc_get_var1_uchar(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_UCHAR)) {
+                    if (expect >= uchar_min && expect <= uchar_max) {
+			IF (err) {
+			    error("nc_get_var1_uchar: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_UCHAR)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_schar(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    schar value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_SCHAR == 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_SCHAR);
+		err = nc_get_var1_schar(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_SCHAR)) {
+                    if (expect >= schar_min && expect <= schar_max) {
+			IF (err) {
+			    error("nc_get_var1_schar: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_SCHAR)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_short(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    short value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_SHORT == 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_SHORT);
+		err = nc_get_var1_short(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_SHORT)) {
+                    if (expect >= short_min && expect <= short_max) {
+			IF (err) {
+			    error("nc_get_var1_short: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_SHORT)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_int(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    int value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_INT == 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_INT);
+		err = nc_get_var1_int(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_INT)) {
+                    if (expect >= int_min && expect <= int_max) {
+			IF (err) {
+			    error("nc_get_var1_int: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_INT)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_long(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    long value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_LONG == 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_LONG);
+		err = nc_get_var1_long(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_LONG)) {
+                    if (expect >= long_min && expect <= long_max) {
+			IF (err) {
+			    error("nc_get_var1_long: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_LONG)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_float(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    float value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_FLOAT == 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_FLOAT);
+		err = nc_get_var1_float(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_FLOAT)) {
+                    if (expect >= float_min && expect <= float_max) {
+			IF (err) {
+			    error("nc_get_var1_float: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_FLOAT)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_double(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    double value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_DOUBLE == 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_DOUBLE);
+		err = nc_get_var1_double(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_DOUBLE)) {
+                    if (expect >= double_min && expect <= double_max) {
+			IF (err) {
+			    error("nc_get_var1_double: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_DOUBLE)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_ushort(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    ushort value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_USHORT == 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_USHORT);
+		err = nc_get_var1_ushort(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_USHORT)) {
+                    if (expect >= ushort_min && expect <= ushort_max) {
+			IF (err) {
+			    error("nc_get_var1_ushort: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_USHORT)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_uint(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    uint value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_UINT == 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_UINT);
+		err = nc_get_var1_uint(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_UINT)) {
+                    if (expect >= uint_min && expect <= uint_max) {
+			IF (err) {
+			    error("nc_get_var1_uint: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_UINT)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_longlong(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    longlong value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_LONGLONG == 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_LONGLONG);
+		err = nc_get_var1_longlong(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_LONGLONG)) {
+                    if (expect >= longlong_min && expect <= longlong_max) {
+			IF (err) {
+			    error("nc_get_var1_longlong: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_LONGLONG)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+/* 
+ *  check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+void
+check_vars_ulonglong(const char *filename)
+{
+    int  ncid;                  /* netCDF id */
+    size_t index[MAX_RANK];
+    int  err;           /* status */
+    int  d;
+    int  i;
+    size_t  j;
+    ulonglong value;
+    nc_type datatype;
+    int ndims;
+    int dimids[MAX_RANK];
+    double expect;
+    char name[NC_MAX_NAME];
+    size_t length;
+    int canConvert;     /* Both text or both numeric */
+    int nok = 0;      /* count of valid comparisons */
+
+    err = file_open(filename, 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_ULONGLONG == 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_ULONGLONG);
+		err = nc_get_var1_ulonglong(ncid, i, index, &value);
+		if (inRange3(expect,datatype,NCT_ULONGLONG)) {
+                    if (expect >= ulonglong_min && expect <= ulonglong_max) {
+			IF (err) {
+			    error("nc_get_var1_ulonglong: %s", nc_strerror(err));
+			} else {
+                            IF (!equal(value,expect,var_type[i],NCT_ULONGLONG)) {
+				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;
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    err = nc_close (ncid);
+    IF (err)
+        error("nc_close: %s", nc_strerror(err));
+    print_nok(nok);
+}
+
+
+
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_text(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    text value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_TEXT == 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_TEXT);
+		    if (inRange3(expect[k], datatype, NCT_TEXT)) {
+			++nInExtRange;
+			if (expect[k] >= text_min && expect[k] <= text_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_text(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_TEXT)
+                            && expect[k] >= text_min && expect[k] <= text_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_TEXT)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_uchar(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    uchar value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_UCHAR == 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_UCHAR);
+		    if (inRange3(expect[k], datatype, NCT_UCHAR)) {
+			++nInExtRange;
+			if (expect[k] >= uchar_min && expect[k] <= uchar_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_uchar(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_UCHAR)
+                            && expect[k] >= uchar_min && expect[k] <= uchar_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_UCHAR)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_schar(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    schar value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SCHAR == 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_SCHAR);
+		    if (inRange3(expect[k], datatype, NCT_SCHAR)) {
+			++nInExtRange;
+			if (expect[k] >= schar_min && expect[k] <= schar_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_schar(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_SCHAR)
+                            && expect[k] >= schar_min && expect[k] <= schar_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_SCHAR)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_short(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    short value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SHORT == 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_SHORT);
+		    if (inRange3(expect[k], datatype, NCT_SHORT)) {
+			++nInExtRange;
+			if (expect[k] >= short_min && expect[k] <= short_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_short(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_SHORT)
+                            && expect[k] >= short_min && expect[k] <= short_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_SHORT)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_int(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    int value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_INT == 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_INT);
+		    if (inRange3(expect[k], datatype, NCT_INT)) {
+			++nInExtRange;
+			if (expect[k] >= int_min && expect[k] <= int_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_int(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_INT)
+                            && expect[k] >= int_min && expect[k] <= int_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_INT)) {
+                            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++;
+                        }
+                    }

+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_long(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    long value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_LONG == 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_LONG);
+		    if (inRange3(expect[k], datatype, NCT_LONG)) {
+			++nInExtRange;
+			if (expect[k] >= long_min && expect[k] <= long_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_long(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_LONG)
+                            && expect[k] >= long_min && expect[k] <= long_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_LONG)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_float(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    float value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_FLOAT == 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_FLOAT);
+		    if (inRange3(expect[k], datatype, NCT_FLOAT)) {
+			++nInExtRange;
+			if (expect[k] >= float_min && expect[k] <= float_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_float(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_FLOAT)
+                            && expect[k] >= float_min && expect[k] <= float_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_FLOAT)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_double(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    double value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_DOUBLE == 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_DOUBLE);
+		    if (inRange3(expect[k], datatype, NCT_DOUBLE)) {
+			++nInExtRange;
+			if (expect[k] >= double_min && expect[k] <= double_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_double(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_DOUBLE)
+                            && expect[k] >= double_min && expect[k] <= double_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_DOUBLE)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_ushort(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    ushort value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_USHORT == 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_USHORT);
+		    if (inRange3(expect[k], datatype, NCT_USHORT)) {
+			++nInExtRange;
+			if (expect[k] >= ushort_min && expect[k] <= ushort_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_ushort(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_USHORT)
+                            && expect[k] >= ushort_min && expect[k] <= ushort_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_USHORT)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_uint(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    uint value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_UINT == 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_UINT);
+		    if (inRange3(expect[k], datatype, NCT_UINT)) {
+			++nInExtRange;
+			if (expect[k] >= uint_min && expect[k] <= uint_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_uint(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_UINT)
+                            && expect[k] >= uint_min && expect[k] <= uint_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_UINT)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_longlong(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    longlong value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_LONGLONG == 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_LONGLONG);
+		    if (inRange3(expect[k], datatype, NCT_LONGLONG)) {
+			++nInExtRange;
+			if (expect[k] >= longlong_min && expect[k] <= longlong_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_longlong(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_LONGLONG)
+                            && expect[k] >= longlong_min && expect[k] <= longlong_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_LONGLONG)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+/* 
+ *  check all attributes in file which are (text/numeric) compatible with TYPE
+ *  ignore any attributes containing values outside range of TYPE
+ */
+static
+void
+check_atts_ulonglong(int  ncid)
+{
+    int  err;           /* status */
+    int  i;
+    int  j;
+    size_t  k;
+    ulonglong value[MAX_NELS];
+    nc_type datatype;
+    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 */
+
+    for (i = -1; i < numVars; i++) {
+        for (j = 0; j < NATTS(i); j++) {
+	    canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_ULONGLONG == 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_ULONGLONG);
+		    if (inRange3(expect[k], datatype, NCT_ULONGLONG)) {
+			++nInExtRange;
+			if (expect[k] >= ulonglong_min && expect[k] <= ulonglong_max)
+			    ++nInIntRange;
+		    }
+		}
+		err = nc_get_att_ulonglong(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);
+                }
+		for (k = 0; k < length; k++) {
+                    if (inRange3(expect[k],datatype,NCT_ULONGLONG)
+                            && expect[k] >= ulonglong_min && expect[k] <= ulonglong_max) {
+                        IF (!equal(value[k],expect[k],datatype,NCT_ULONGLONG)) {
+                            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++;
+                        }
+                    }
+                }
+            }                                               
+        }
+    }
+
+    print_nok(nok);
+}
+
+
+
+
+void
+test_nc_put_var1_text(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    text 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_text(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_text(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_text(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_text( var_type[i], var_rank[i], index, NCT_TEXT);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_text(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_text(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_TEXT)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_text(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_uchar(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    uchar 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_uchar(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_uchar(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_uchar(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_uchar( var_type[i], var_rank[i], index, NCT_UCHAR);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_uchar(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_uchar(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_UCHAR)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uchar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_schar(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    schar 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_schar(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_schar(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_schar(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_schar( var_type[i], var_rank[i], index, NCT_SCHAR);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_schar(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_schar(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_SCHAR)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_schar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_short(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    short 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_short(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_short(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_short(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_short( var_type[i], var_rank[i], index, NCT_SHORT);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_short(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_short(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_SHORT)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_short(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_int(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_int(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_int(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_int(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_int( var_type[i], var_rank[i], index, NCT_INT);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_int(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_int(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_INT)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_int(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_long(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    long 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_long(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_long(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_long(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_long( var_type[i], var_rank[i], index, NCT_LONG);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_long(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_long(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_LONG)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_long(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_float(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    float 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_float(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_float(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_float(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_float( var_type[i], var_rank[i], index, NCT_FLOAT);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_float(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_float(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_FLOAT)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_float(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_double(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    double 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_double(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_double(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_double(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_double( var_type[i], var_rank[i], index, NCT_DOUBLE);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_double(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_double(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_DOUBLE)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_double(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_ushort(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    ushort 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_ushort(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_ushort(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_ushort(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_ushort( var_type[i], var_rank[i], index, NCT_USHORT);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_ushort(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_ushort(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_USHORT)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ushort(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_uint(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    uint 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_uint(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_uint(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_uint(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_uint( var_type[i], var_rank[i], index, NCT_UINT);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_uint(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_uint(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_UINT)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uint(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_longlong(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    longlong 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_longlong(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_longlong(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_longlong(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_longlong( var_type[i], var_rank[i], index, NCT_LONGLONG);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_longlong(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_longlong(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_LONGLONG)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_longlong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var1_ulonglong(void)
+{
+    int ncid;
+    int i;
+    int j;
+    int err;
+    size_t index[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    ulonglong 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;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+    err = nc_enddef(ncid);
+    IF (err)
+        error("nc_enddef: %s", nc_strerror(err));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == NCT_TEXT);
+        for (j = 0; j < var_rank[i]; j++)
+            index[j] = 0;
+        err = nc_put_var1_ulonglong(BAD_ID, i, index, &value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var1_ulonglong(ncid, BAD_VARID, index, &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 */
+		index[j] = var_shape[i][j];
+		err = nc_put_var1_ulonglong(ncid, i, index, &value);
+		IF (canConvert && 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");
+            value = hash_ulonglong( var_type[i], var_rank[i], index, NCT_ULONGLONG);
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_var1_ulonglong(ncid, i, NULL, &value);
+	    else
+		err = nc_put_var1_ulonglong(ncid, i, index, &value);
+	    if (canConvert) {
+		if (inRange3(value, var_type[i],NCT_ULONGLONG)) {
+		    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);
+            }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ulonglong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+
+
+
+void
+test_nc_put_var_text(void)
+{
+    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? */
+    text value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_text(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_text(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_text(var_type[i], var_rank[i], index, NCT_TEXT);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_TEXT);
+	}
+        err = nc_put_var_text(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_TEXT == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_text(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_text(var_type[i], var_rank[i], index, NCT_TEXT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_TEXT);
+	    }
+	    err = nc_put_var_text(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_text(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_uchar(void)
+{
+    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? */
+    uchar value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_uchar(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_uchar(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_uchar(var_type[i], var_rank[i], index, NCT_UCHAR);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_UCHAR);
+	}
+        err = nc_put_var_uchar(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_UCHAR == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_uchar(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_uchar(var_type[i], var_rank[i], index, NCT_UCHAR);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_UCHAR);
+	    }
+	    err = nc_put_var_uchar(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uchar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_schar(void)
+{
+    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? */
+    schar value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_schar(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_schar(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_schar(var_type[i], var_rank[i], index, NCT_SCHAR);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_SCHAR);
+	}
+        err = nc_put_var_schar(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_SCHAR == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_schar(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_schar(var_type[i], var_rank[i], index, NCT_SCHAR);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_SCHAR);
+	    }
+	    err = nc_put_var_schar(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_schar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_short(void)
+{
+    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? */
+    short value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_short(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_short(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_short(var_type[i], var_rank[i], index, NCT_SHORT);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_SHORT);
+	}
+        err = nc_put_var_short(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_SHORT == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_short(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_short(var_type[i], var_rank[i], index, NCT_SHORT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_SHORT);
+	    }
+	    err = nc_put_var_short(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_short(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_int(void)
+{
+    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 value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_int(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_int(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_int(var_type[i], var_rank[i], index, NCT_INT);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_INT);
+	}
+        err = nc_put_var_int(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_INT == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_int(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_int(var_type[i], var_rank[i], index, NCT_INT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_INT);
+	    }
+	    err = nc_put_var_int(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_int(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_long(void)
+{
+    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? */
+    long value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_long(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_long(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_long(var_type[i], var_rank[i], index, NCT_LONG);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_LONG);
+	}
+        err = nc_put_var_long(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_LONG == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_long(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_long(var_type[i], var_rank[i], index, NCT_LONG);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_LONG);
+	    }
+	    err = nc_put_var_long(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_long(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_float(void)
+{
+    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? */
+    float value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_float(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_float(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_float(var_type[i], var_rank[i], index, NCT_FLOAT);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_FLOAT);
+	}
+        err = nc_put_var_float(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_FLOAT == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_float(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_float(var_type[i], var_rank[i], index, NCT_FLOAT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_FLOAT);
+	    }
+	    err = nc_put_var_float(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_float(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_double(void)
+{
+    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? */
+    double value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_double(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_double(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_double(var_type[i], var_rank[i], index, NCT_DOUBLE);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_DOUBLE);
+	}
+        err = nc_put_var_double(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_DOUBLE == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_double(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_double(var_type[i], var_rank[i], index, NCT_DOUBLE);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_DOUBLE);
+	    }
+	    err = nc_put_var_double(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_double(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_ushort(void)
+{
+    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? */
+    ushort value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_ushort(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_ushort(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_ushort(var_type[i], var_rank[i], index, NCT_USHORT);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_USHORT);
+	}
+        err = nc_put_var_ushort(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_USHORT == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_ushort(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_ushort(var_type[i], var_rank[i], index, NCT_USHORT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_USHORT);
+	    }
+	    err = nc_put_var_ushort(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ushort(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_uint(void)
+{
+    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? */
+    uint value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_uint(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_uint(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_uint(var_type[i], var_rank[i], index, NCT_UINT);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_UINT);
+	}
+        err = nc_put_var_uint(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_UINT == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_uint(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_uint(var_type[i], var_rank[i], index, NCT_UINT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_UINT);
+	    }
+	    err = nc_put_var_uint(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uint(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_longlong(void)
+{
+    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? */
+    longlong value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_longlong(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_longlong(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_longlong(var_type[i], var_rank[i], index, NCT_LONGLONG);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_LONGLONG);
+	}
+        err = nc_put_var_longlong(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);
+	}
+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_LONGLONG == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_longlong(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_longlong(var_type[i], var_rank[i], index, NCT_LONGLONG);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_LONGLONG);
+	    }
+	    err = nc_put_var_longlong(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_longlong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_var_ulonglong(void)
+{
+    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? */
+    ulonglong value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == NCT_TEXT);
+        assert(var_rank[i] <= MAX_RANK);
+        assert(var_nels[i] <= MAX_NELS);
+        err = nc_put_var_ulonglong(BAD_ID, i, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_var_ulonglong(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_ulonglong(var_type[i], var_rank[i], index, NCT_ULONGLONG);
+	    allInExtRange = allInExtRange 
+		&& inRange3(value[j], var_type[i], NCT_ULONGLONG);
+	}
+        err = nc_put_var_ulonglong(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);
+	}

+    }
+
+        /* 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));
+    index[0] = NRECS-1;
+    err = nc_put_var1_text(ncid, varid, index, "x");
+    IF (err)
+        error("nc_put_var1_text: %s", nc_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_ULONGLONG == NCT_TEXT);
+	    assert(var_rank[i] <= MAX_RANK);
+	    assert(var_nels[i] <= MAX_NELS);
+	    err = nc_put_var_ulonglong(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_ulonglong(var_type[i], var_rank[i], index, NCT_ULONGLONG);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_ULONGLONG);
+	    }
+	    err = nc_put_var_ulonglong(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);
+	    }
+        }
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ulonglong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+
+
+
+void
+test_nc_put_vara_text(void)
+{
+    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? */
+    text value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == 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_put_vara_text(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_text(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_text(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_text(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_text(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_text(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_text(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_text(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 */
+	    /* 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];
+	    }
+            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_text(var_type[i], var_rank[i], index, NCT_TEXT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_TEXT);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_text(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_text(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_text(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_uchar(void)
+{
+    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? */
+    uchar value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == 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_put_vara_uchar(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_uchar(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_uchar(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_uchar(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_uchar(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_uchar(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_uchar(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_uchar(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 */
+	    /* 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];
+	    }
+            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_uchar(var_type[i], var_rank[i], index, NCT_UCHAR);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_UCHAR);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_uchar(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_uchar(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uchar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_schar(void)
+{
+    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? */
+    schar value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == 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_put_vara_schar(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_schar(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_schar(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_schar(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_schar(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_schar(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_schar(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_schar(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 */
+	    /* 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];
+	    }
+            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_schar(var_type[i], var_rank[i], index, NCT_SCHAR);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_SCHAR);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_schar(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_schar(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_schar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_short(void)
+{
+    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? */
+    short value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == 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_put_vara_short(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_short(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_short(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_short(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_short(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_short(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_short(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_short(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 */
+	    /* 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];
+	    }
+            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_short(var_type[i], var_rank[i], index, NCT_SHORT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_SHORT);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_short(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_short(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_short(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_int(void)
+{
+    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 value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == 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_put_vara_int(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_int(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_int(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_int(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_int(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_int(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_int(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_int(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 */
+	    /* 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];
+	    }
+            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_int(var_type[i], var_rank[i], index, NCT_INT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_INT);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_int(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_int(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_int(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_long(void)
+{
+    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? */
+    long value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == 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_put_vara_long(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_long(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_long(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_long(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_long(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_long(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_long(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_long(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 */
+	    /* 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];
+	    }
+            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_long(var_type[i], var_rank[i], index, NCT_LONG);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_LONG);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_long(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_long(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_long(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_float(void)
+{
+    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? */
+    float value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == 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_put_vara_float(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_float(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_float(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_float(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_float(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_float(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_float(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_float(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 */
+	    /* 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];
+	    }
+            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_float(var_type[i], var_rank[i], index, NCT_FLOAT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_FLOAT);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_float(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_float(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_float(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_double(void)
+{
+    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? */
+    double value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == 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_put_vara_double(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_double(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_double(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_double(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_double(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_double(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_double(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_double(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 */
+	    /* 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];
+	    }
+            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_double(var_type[i], var_rank[i], index, NCT_DOUBLE);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_DOUBLE);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_double(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_double(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_double(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_ushort(void)
+{
+    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? */
+    ushort value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == 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_put_vara_ushort(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_ushort(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_ushort(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_ushort(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_ushort(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_ushort(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_ushort(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_ushort(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 */
+	    /* 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];
+	    }
+            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_ushort(var_type[i], var_rank[i], index, NCT_USHORT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_USHORT);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_ushort(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_ushort(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ushort(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_uint(void)
+{
+    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? */
+    uint value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == 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_put_vara_uint(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_uint(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_uint(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_uint(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_uint(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_uint(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_uint(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_uint(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 */
+	    /* 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];
+	    }
+            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_uint(var_type[i], var_rank[i], index, NCT_UINT);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_UINT);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_uint(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_uint(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uint(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_longlong(void)
+{
+    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? */
+    longlong value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == 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_put_vara_longlong(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_longlong(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_longlong(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_longlong(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_longlong(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_longlong(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_longlong(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_longlong(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 */
+	    /* 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];
+	    }
+            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_longlong(var_type[i], var_rank[i], index, NCT_LONGLONG);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_LONGLONG);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_longlong(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_longlong(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_longlong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vara_ulonglong(void)
+{
+    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? */
+    ulonglong value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    value[0] = 0;
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == 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_put_vara_ulonglong(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_ulonglong(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_ulonglong(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_ulonglong(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EEDGE)
+		    error("bad edge: status = %d", err);
+		edge[j] = 1;
+	    }
+        }
+            /* Check correct error returned even when nothing to put */
+        for (j = 0; j < var_rank[i]; j++) {
+            edge[j] = 0;
+	}
+        err = nc_put_vara_ulonglong(BAD_ID, i, start, edge, value);
+        IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+        err = nc_put_vara_ulonglong(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_ulonglong(ncid, i, start, edge, value);
+		IF (canConvert && err != NC_EINVALCOORDS)
+		    error("bad start: status = %d", err);
+		start[j] = 0;
+	    }
+        }
+
+/* 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_ulonglong(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 */
+	    /* 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];
+	    }
+            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_ulonglong(var_type[i], var_rank[i], index, NCT_ULONGLONG);
+		allInExtRange = allInExtRange 
+		    && inRange3(value[j], var_type[i], NCT_ULONGLONG);
+	    }
+	    if (var_rank[i] == 0 && i%2 == 0)
+		err = nc_put_vara_ulonglong(ncid, i, NULL, NULL, value);
+	    else
+		err = nc_put_vara_ulonglong(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 = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ulonglong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+
+
+
+void
+test_nc_put_vars_text(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    text value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == 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_text(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_text(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_text(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_text(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_text(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_text(var_type[i], var_rank[i], index2, 
+			NCT_TEXT);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_TEXT);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_text(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_text(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_text(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_uchar(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    uchar value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == 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_uchar(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_uchar(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_uchar(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_uchar(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_uchar(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_uchar(var_type[i], var_rank[i], index2, 
+			NCT_UCHAR);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_UCHAR);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_uchar(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_uchar(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uchar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_schar(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    schar value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == 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_schar(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_schar(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_schar(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_schar(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_schar(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_schar(var_type[i], var_rank[i], index2, 
+			NCT_SCHAR);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_SCHAR);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_schar(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_schar(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_schar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_short(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    short value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == 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_short(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_short(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_short(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_short(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_short(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_short(var_type[i], var_rank[i], index2, 
+			NCT_SHORT);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_SHORT);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_short(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_short(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_short(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_int(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    int value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == 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_int(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_int(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_int(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_int(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_int(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_int(var_type[i], var_rank[i], index2, 
+			NCT_INT);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_INT);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_int(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_int(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_int(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_long(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    long value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == 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_long(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_long(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_long(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_long(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_long(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_long(var_type[i], var_rank[i], index2, 
+			NCT_LONG);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_LONG);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_long(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_long(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_long(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_float(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    float value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == 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_float(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_float(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_float(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_float(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_float(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_float(var_type[i], var_rank[i], index2, 
+			NCT_FLOAT);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_FLOAT);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_float(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_float(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_float(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_double(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    double value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == 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_double(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_double(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_double(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_double(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_double(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_double(var_type[i], var_rank[i], index2, 
+			NCT_DOUBLE);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_DOUBLE);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_double(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_double(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_double(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_ushort(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    ushort value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == 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_ushort(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_ushort(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_ushort(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_ushort(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_ushort(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_ushort(var_type[i], var_rank[i], index2, 
+			NCT_USHORT);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_USHORT);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_ushort(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_ushort(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ushort(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_uint(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    uint value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == 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_uint(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_uint(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_uint(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_uint(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_uint(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_uint(var_type[i], var_rank[i], index2, 
+			NCT_UINT);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_UINT);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_uint(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_uint(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uint(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_longlong(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    longlong value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == 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_longlong(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_longlong(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_longlong(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_longlong(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_longlong(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_longlong(var_type[i], var_rank[i], index2, 
+			NCT_LONGLONG);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_LONGLONG);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_longlong(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_longlong(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_longlong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_vars_ulonglong(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];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    ulonglong value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == 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_ulonglong(BAD_ID, i, start, edge, stride, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_vars_ulonglong(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_ulonglong(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_ulonglong(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_ulonglong(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 */
+/* TODO
+		if ( roll(2) ) {
+		    for (j = 0; j < var_rank[i]; j++) {
+			index[j] += (count[j] - 1) * 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_ulonglong(var_type[i], var_rank[i], index2, 
+			NCT_ULONGLONG);
+		    allInExtRange = allInExtRange 
+			&& inRange3(value[j], var_type[i], NCT_ULONGLONG);
+		}
+		if (var_rank[i] == 0 && i%2 == 0)
+		    err = nc_put_vars_ulonglong(ncid, i, NULL, NULL, stride, value);
+		else
+		    err = nc_put_vars_ulonglong(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);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ulonglong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+	error("remove of %s failed", scratch);
+}
+
+
+
+
+void
+test_nc_put_varm_text(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    text value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == 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_text(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_text(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_text(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_text(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_text(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_text(var_type[i], var_rank[i], index2,
+                        NCT_TEXT);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_TEXT);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_text(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_text(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_text(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_uchar(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    uchar value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == 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_uchar(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_uchar(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_uchar(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_uchar(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_uchar(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_uchar(var_type[i], var_rank[i], index2,
+                        NCT_UCHAR);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_UCHAR);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_uchar(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_uchar(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uchar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_schar(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    schar value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == 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_schar(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_schar(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_schar(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_schar(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_schar(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_schar(var_type[i], var_rank[i], index2,
+                        NCT_SCHAR);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_SCHAR);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_schar(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_schar(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_schar(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_short(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    short value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == 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_short(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_short(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_short(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_short(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_short(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_short(var_type[i], var_rank[i], index2,
+                        NCT_SHORT);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_SHORT);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_short(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_short(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_short(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_int(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    int value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == 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_int(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_int(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_int(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_int(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_int(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_int(var_type[i], var_rank[i], index2,
+                        NCT_INT);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_INT);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_int(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_int(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_int(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_long(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    long value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == 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_long(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_long(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_long(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_long(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_long(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_long(var_type[i], var_rank[i], index2,
+                        NCT_LONG);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_LONG);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_long(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_long(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_long(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_float(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    float value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == 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_float(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_float(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_float(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_float(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_float(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_float(var_type[i], var_rank[i], index2,
+                        NCT_FLOAT);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_FLOAT);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_float(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_float(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_float(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_double(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    double value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == 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_double(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_double(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_double(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_double(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_double(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_double(var_type[i], var_rank[i], index2,
+                        NCT_DOUBLE);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_DOUBLE);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_double(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_double(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_double(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_ushort(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    ushort value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_USHORT == 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_ushort(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_ushort(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_ushort(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_ushort(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_ushort(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_ushort(var_type[i], var_rank[i], index2,
+                        NCT_USHORT);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_USHORT);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_ushort(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_ushort(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ushort(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_uint(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    uint value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_UINT == 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_uint(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_uint(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_uint(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_uint(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_uint(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_uint(var_type[i], var_rank[i], index2,
+                        NCT_UINT);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_UINT);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_uint(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_uint(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }

+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_uint(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_longlong(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    longlong value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_LONGLONG == 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_longlong(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_longlong(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_longlong(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_longlong(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_longlong(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_longlong(var_type[i], var_rank[i], index2,
+                        NCT_LONGLONG);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_LONGLONG);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_longlong(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_longlong(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_longlong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+void
+test_nc_put_varm_ulonglong(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];
+    ptrdiff_t imap[MAX_RANK];
+    int canConvert;	/* Both text or both numeric */
+    int allInExtRange;	/* all values within external range? */
+    ulonglong value[MAX_NELS];
+
+    err = file_create(scratch, NC_CLOBBER, &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));
+
+#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
+
+    for (i = 0; i < numVars; i++) {
+	canConvert = (var_type[i] == NC_CHAR) == (NCT_ULONGLONG == 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_ulonglong(BAD_ID, i, start, edge, stride, imap, value);
+	IF (err != NC_EBADID) 
+	    error("bad ncid: status = %d", err);
+	err = nc_put_varm_ulonglong(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_ulonglong(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_ulonglong(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_ulonglong(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];
+	    }
+            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) {
+                    j = var_rank[i] - 1;
+                    imap[j] = 1;
+                    for (; j > 0; j--)
+                        imap[j-1] = imap[j] * count[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_ulonglong(var_type[i], var_rank[i], index2,
+                        NCT_ULONGLONG);
+                    allInExtRange = allInExtRange
+                        && inRange3(value[j], var_type[i], NCT_ULONGLONG);
+                }
+                if (var_rank[i] == 0 && i%2 == 0)
+                    err = nc_put_varm_ulonglong(ncid,i,NULL,NULL,NULL,NULL,value);
+                else
+                    err = nc_put_varm_ulonglong(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);
+                    }
+                } else {
+                    IF (nels > 0 && err != NC_ECHAR)
+                        error("wrong type: status = %d", err);
+		}
+	    }
+	}
+    }
+
+    err = nc_close(ncid);
+    IF (err) 
+	error("nc_close: %s", nc_strerror(err));
+
+    check_vars_ulonglong(scratch);
+
+    err = remove(scratch);
+    IF (err)
+        error("remove of %s failed", scratch);
+}
+
+
+
+void
+test_nc_put_att_text(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    text value[MAX_NELS];
+
+    err = file_create(scratch, NC_NOCLOBBER, &ncid);
+    IF (err) {
+        error("nc_create: %s", nc_strerror(err));
+        return;
+    }
+    def_dims(ncid);
+    def_vars(ncid);
+
+    {
+	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);
+    }
+    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));
+		}
+	    }
+        }
+    }
+
+    check_atts_text(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_uchar(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    uchar value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_uchar(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_uchar(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_uchar(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_uchar(ATT_TYPE(i,j), -1, &k, NCT_UCHAR);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_UCHAR);
+		}
+		err = nc_put_att_uchar(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_uchar(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_schar(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    schar value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_schar(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_schar(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_schar(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_schar(ATT_TYPE(i,j), -1, &k, NCT_SCHAR);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_SCHAR);
+		}
+		err = nc_put_att_schar(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_schar(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_short(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    short value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_short(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_short(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_short(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_short(ATT_TYPE(i,j), -1, &k, NCT_SHORT);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_SHORT);
+		}
+		err = nc_put_att_short(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_short(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_int(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    int value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_int(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_int(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_int(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_int(ATT_TYPE(i,j), -1, &k, NCT_INT);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_INT);
+		}
+		err = nc_put_att_int(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_int(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_long(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    long value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_long(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_long(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_long(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_long(ATT_TYPE(i,j), -1, &k, NCT_LONG);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_LONG);
+		}
+		err = nc_put_att_long(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_long(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_float(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    float value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_float(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_float(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_float(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_float(ATT_TYPE(i,j), -1, &k, NCT_FLOAT);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_FLOAT);
+		}
+		err = nc_put_att_float(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_float(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_double(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    double value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_double(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_double(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_double(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_double(ATT_TYPE(i,j), -1, &k, NCT_DOUBLE);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_DOUBLE);
+		}
+		err = nc_put_att_double(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_double(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_ushort(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    ushort value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_ushort(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_ushort(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_ushort(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_ushort(ATT_TYPE(i,j), -1, &k, NCT_USHORT);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_USHORT);
+		}
+		err = nc_put_att_ushort(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_ushort(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_uint(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    uint value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_uint(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_uint(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_uint(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_uint(ATT_TYPE(i,j), -1, &k, NCT_UINT);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_UINT);
+		}
+		err = nc_put_att_uint(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_uint(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_longlong(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    longlong value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_longlong(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_longlong(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_longlong(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_longlong(ATT_TYPE(i,j), -1, &k, NCT_LONGLONG);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_LONGLONG);
+		}
+		err = nc_put_att_longlong(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_longlong(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_ulonglong(void)
+{
+    int ncid;
+    int i;
+    int j;
+    size_t k;
+    int err;
+    ulonglong value[MAX_NELS];
+    int allInExtRange;  /* all values within external range? */
+
+    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++) {
+        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_ulonglong(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_ulonglong(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_ulonglong(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_ulonglong(ATT_TYPE(i,j), -1, &k, NCT_ULONGLONG);
+		    allInExtRange = allInExtRange
+			&& inRange3(value[k], ATT_TYPE(i,j), NCT_ULONGLONG);
+		}
+		err = nc_put_att_ulonglong(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);
+		}
+	    }
+        }
+    }
+
+    check_atts_ulonglong(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);
+}
+
+
diff --git a/nc_test/test_read.c b/nc_test/test_read.c
index f0e4c08..96edad9 100644
--- a/nc_test/test_read.c
+++ b/nc_test/test_read.c
@@ -6,7 +6,7 @@
 
 #include "tests.h"
 
-/* 
+/*
  * Test nc_strerror.
  *    Try on a bad error status.
  *    Test for each defined error status.
@@ -72,7 +72,7 @@ test_nc_strerror(void)
 }
 
 
-/* 
+/*
  * Test nc_open.
  * If in read-only section of tests,
  *    Try to open a non-existent netCDF file, check error return.
@@ -90,7 +90,7 @@ test_nc_open(void)
     int err;
     int ncid;
     int ncid2;
-    
+
     /* Try to open a nonexistent file */
     err = file_open("tooth-fairy.nc", NC_NOWRITE, &ncid);/* should fail */
     IF (err == NC_NOERR)
@@ -124,17 +124,17 @@ test_nc_open(void)
 	error("netCDF IDs for first and second nc_open calls should differ");
 
     err = file_create(scratch, NC_NOCLOBBER, &ncid2);
-    IF (err) 
+    IF (err)
        error("nc_create: %s", nc_strerror(err));
-    else 
+    else
        (void) nc_close(ncid2);
     err = file_open(scratch, NC_WRITE, &ncid2);
-    IF (err) 
+    IF (err)
        error("nc_open: %s", nc_strerror(err));
-    else 
+    else
        (void) nc_close(ncid2);
     err = remove(scratch);
-    IF (err) 
+    IF (err)
        error("remove of %s failed", scratch);
 
     err = nc_close(ncid);
@@ -143,7 +143,7 @@ test_nc_open(void)
 }
 
 
-/* 
+/*
  * Test nc_close.
  *    Try to close a netCDF file twice, check whether second close fails.
  *    Try on bad handle, check error return.
@@ -165,7 +165,7 @@ test_nc_close(void)
     err = nc_close(ncid);
     IF (err != NC_EBADID)
 	error("nc_close of closed file should have failed");
-    
+
     /* Try with a bad netCDF ID */
     err = nc_close(BAD_ID);/* should fail */
     IF (err != NC_EBADID)
@@ -180,7 +180,7 @@ test_nc_close(void)
 	error("nc_close in data mode failed: %s", nc_strerror(err));
 
     err = file_create(scratch, NC_NOCLOBBER, &ncid);
-    IF (err) 
+    IF (err)
        error("nc_create: %s", nc_strerror(err));
     err = nc_close(ncid);
     IF (err)
@@ -191,7 +191,7 @@ test_nc_close(void)
 }
 
 
-/* 
+/*
  * Test nc_inq.
  *    Try on bad handle, check error return.
  *    Try in data mode, check returned values.
@@ -213,12 +213,12 @@ test_nc_inq(void)
     err = file_open(testfile, NC_NOWRITE, &ncid);
     IF (err)
 	error("nc_open: %s", nc_strerror(err));
-    
+
     /* Try on bad handle */
     err = nc_inq(BAD_ID, 0, 0, 0, 0);
     IF (err != NC_EBADID)
 	error("bad ncid: status = %d", err);
-    
+
     err = nc_inq(ncid, &ndims, &nvars, &ngatts, &recdim);
     IF (err)
 	error("nc_inq: %s", nc_strerror(err));
@@ -230,7 +230,7 @@ test_nc_inq(void)
 	error("nc_inq: wrong number of global atts returned, %d", ngatts);
     else IF (recdim != RECDIM)
 	error("nc_inq: wrong record dimension ID returned, %d", recdim);
-    
+
     /* Inguire for no info (useless, but should still work) */
     err = nc_inq(ncid, 0, 0, 0, 0);
     IF (err)
@@ -493,14 +493,14 @@ test_nc_inq_dim(void)
 	err = nc_inq_dim(ncid, i, name, &length);
 	IF (err)
 	    error("nc_inq_dim: %s", nc_strerror(err));
-	else IF (strcmp(dim_name[i],name)) 
+	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);
 	err = nc_inq_dim(ncid, i, name, 0);
         IF (err)
 	    error("nc_inq_dim: %s", nc_strerror(err));
-	else IF (strcmp(dim_name[i],name)) 
+	else IF (strcmp(dim_name[i],name))
 	    error("name expected: %s, got: %s",dim_name[i],name);
 	err = nc_inq_dim(ncid, i, 0, &length);
         IF (err)
@@ -565,7 +565,7 @@ test_nc_inq_dimname(void)
 	err = nc_inq_dimname(ncid, i, name);
 	IF (err)
 	    error("nc_inq_dimname: %s", nc_strerror(err));
-	else IF (strcmp(dim_name[i],name)) 
+	else IF (strcmp(dim_name[i],name))
 	    error("name expected: %s, got: %s",dim_name[i],name);
     }
     err = nc_close(ncid);
@@ -635,7 +635,7 @@ test_nc_inq_var(void)
 	err = nc_inq_var(ncid, i, name, &datatype, &ndims, dimids, &natts);
 	IF (err)
 	    error("nc_inq_var: %s", nc_strerror(err));
-	else IF (strcmp(var_name[i],name)) 
+	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);
@@ -648,7 +648,7 @@ test_nc_inq_var(void)
 	err = nc_inq_var(ncid, i, name, 0, 0, 0, 0);
         IF (err)
 	    error("nc_inq_var: %s", nc_strerror(err));
-	else IF (strcmp(var_name[i],name)) 
+	else IF (strcmp(var_name[i],name))
 	    error("name expected: %s, got: %s",var_name[i],name);
 	err = nc_inq_var(ncid, i, 0, &datatype, 0, 0, 0);
         IF (err)
@@ -728,7 +728,7 @@ test_nc_inq_varname(void)
 	err = nc_inq_varname(ncid, i, name);
 	IF (err)
 	    error("nc_inq_varname: %s", nc_strerror(err));
-	else IF (strcmp(var_name[i],name)) 
+	else IF (strcmp(var_name[i],name))
 	    error("name expected: %s, got: %s",var_name[i],name);
     }
     err = nc_close(ncid);
@@ -1347,25 +1347,25 @@ test_nc_get_att(void)
     size_t k;
     int err;
     double buf[MAX_NELS];	/* (void *) buffer */
-    char *p;			/* (void *) pointer */
+    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) 
+    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) 
+	    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) 
+	    IF (err != NC_ENOTVAR)
 		error("bad var id: status = %d", err);
 	    err = nc_get_att(ncid, i, "noSuch", buf);
-	    IF (err != NC_ENOTATT) 
+	    IF (err != NC_ENOTATT)
 		error("Bad attribute name: status = %d", err);
 	    err = nc_get_att(ncid, i, ATT_NAME(i,j), buf);
 	    IF (err) {
@@ -1373,13 +1373,13 @@ test_nc_get_att(void)
 	    } else {
 		for (k = 0; k < ATT_LEN(i,j); k++) {
 		    expect = hash(ATT_TYPE(i,j), -1, &k );
-		    p = (char *) buf;
+		    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)) {
+              IF (!equal(got,expect,ATT_TYPE(i,j),NCT_DOUBLE)) {
 			    error("value read not that expected");
 			    if (verbose) {
 				error("\n");
@@ -1418,19 +1418,19 @@ test_nc_inq_att(void)
     size_t n;
 
     err = file_open(testfile, NC_NOWRITE, &ncid);
-    IF (err) 
+    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) 
+	    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) 
+	    IF (err != NC_ENOTVAR)
 		error("bad var id: status = %d", err);
 	    err = nc_inq_att(ncid, i, "noSuch", &t, &n);
-	    IF (err != NC_ENOTATT) 
+	    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) {
@@ -1438,7 +1438,7 @@ test_nc_inq_att(void)
 	    } else {
 		IF (t != ATT_TYPE(i,j))
 		    error("type not that expected");
-		IF (n != ATT_LEN(i,j)) 
+		IF (n != ATT_LEN(i,j))
 		    error("length not that expected");
 	    }
 	}
@@ -1611,4 +1611,3 @@ test_nc_inq_attid(void)
     IF (err)
 	error("nc_close: %s", nc_strerror(err));
 }
-
diff --git a/nc_test/test_write.c b/nc_test/test_write.c
index 4c17175..a5fd560 100644
--- a/nc_test/test_write.c
+++ b/nc_test/test_write.c
@@ -64,11 +64,11 @@ test_nc_create(void)
 
 
 /*
- * Test nc_redef 
+ * 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. 
+ *    create file, define dims & vars.
  *    attempt put var (error)
  *    attempt redef (error) & enddef.
  *    put vars
@@ -117,7 +117,7 @@ test_nc_redef(void)
     IF (err != NC_ENOTINDEFINE)
 	error("nc_redef in NC_NOWRITE mode: status = %d", err);
     err = nc_close(ncid);
-    IF (err) 
+    IF (err)
 	error("nc_close: %s", nc_strerror(err));
 
 	/* tests using scratch file */
@@ -133,7 +133,7 @@ test_nc_redef(void)
     def_vars(ncid);
     put_atts(ncid);
     err = nc_inq_varid(ncid, "d", &varid);
-    IF (err) 
+    IF (err)
 	error("nc_inq_varid: %s", nc_strerror(err));
     var = 1.0;
     err = nc_put_var1_double(ncid, varid, NULL, &var);
@@ -190,7 +190,7 @@ test_nc_redef(void)
     IF (err)
 	error("nc_inq_format: %s", nc_strerror(err));
     err = nc_close(ncid);
-    IF (err) 
+    IF (err)
 	error("nc_close: %s", nc_strerror(err));
 
     /* check scratch file written as expected */
@@ -198,11 +198,11 @@ test_nc_redef(void)
 
     IF ((err = file_open(scratch, NC_NOWRITE, &ncid)))
         error("nc_open: %s", nc_strerror(err));
-    IF ((err = nc_inq_dim(ncid, dimid, name, &length))) 
+    IF ((err = nc_inq_dim(ncid, dimid, name, &length)))
 	error("nc_inq_dim: %s", nc_strerror(err));
-    IF (strcmp(name, "abc") != 0) 
+    IF (strcmp(name, "abc") != 0)
 	error("Unexpected dim name");
-    IF (length != sizehint) 
+    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));
@@ -229,7 +229,7 @@ test_nc_redef(void)
     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))) 
+    IF ((err = nc_close(ncid)))
 	error("nc_close: %s", nc_strerror(err));
 
     /* check scratch file written as expected */
@@ -239,11 +239,11 @@ test_nc_redef(void)
     IF (err)
         error("nc_open: %s", nc_strerror(err));
     err = nc_inq_dim(ncid, dimid, name, &length);
-    IF (err) 
+    IF (err)
 	error("nc_inq_dim: %s", nc_strerror(err));
-    IF (strcmp(name, "def") != 0) 
+    IF (strcmp(name, "def") != 0)
 	error("Unexpected dim name");
-    IF (length != sizehint) 
+    IF (length != sizehint)
 	error("Unexpected dim length");
     err = nc_get_var1_double(ncid, varid, NULL, &var);
     IF (err)
@@ -266,7 +266,7 @@ test_nc_redef(void)
 
 
 /*
- * Test nc_enddef 
+ * Test nc_enddef
  * Simply calls test_nc_redef which tests both nc_redef & nc_enddef
  */
 void
@@ -381,12 +381,12 @@ test_nc_abort(void)
     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));
@@ -491,19 +491,19 @@ test_nc_def_dim(void)
     IF (err)
         error("nc_redef: %s", nc_strerror(err));
     err = nc_def_dim(ncid, dim_name[0], NC_UNLIMITED, &dimid);
-    IF (err) 
+    IF (err)
 	error("nc_def_dim: %s", nc_strerror(err));
-    IF (dimid != 0) 
+    IF (dimid != 0)
 	error("Unexpected dimid");
     err = nc_inq_unlimdim(ncid, &dimid);
-    IF (err) 
+    IF (err)
 	error("nc_inq_unlimdim: %s", nc_strerror(err));
-    IF (dimid != 0) 
+    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) 
+    IF (length != 0)
 	error("Unexpected length");
     err = nc_def_dim(ncid, "abc", NC_UNLIMITED, &dimid);
     IF (err != NC_EUNLIMIT)
@@ -523,9 +523,9 @@ test_nc_def_dim(void)
 	        error("bad size: status = %d", err);
 	}
         err = nc_def_dim(ncid, dim_name[i], dim_len[i], &dimid);
-        IF (err) 
+        IF (err)
 	    error("nc_def_dim: %s", nc_strerror(err));
-	IF (dimid != i) 
+	IF (dimid != i)
 	    error("Unexpected dimid");
     }
 
@@ -682,7 +682,7 @@ test_nc_def_var(void)
     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) 
+        IF (err)
 	    error("nc_def_var: %s", nc_strerror(err));
 	IF (varid != i)
 	    error("Unexpected varid");
@@ -1104,7 +1104,7 @@ test_nc_put_varm(void)
             stride[j] = 1;
         }
 	if (var_rank[i] > 0) {
-	    j = var_rank[i] - 1; 
+	    j = var_rank[i] - 1;
             // imap[j] = nctypelen(var_type[i]); /* in bytes */
             imap[j] = 1; /* in numbers of elements */
 	    for (; j > 0; j--)
@@ -1443,7 +1443,7 @@ test_nc_copy_att(void)
         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
@@ -1455,7 +1455,7 @@ test_nc_copy_att(void)
     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
@@ -1497,8 +1497,8 @@ test_nc_copy_att(void)
 		error("nc_get_att_text: %s", nc_strerror(err));
 	    IF (value != 'A')
 		error("Unexpected value");
-	}                                                   
-    }                                                   
+	}
+    }
 
     err = nc_close(ncid_out);
     IF (err)
@@ -1537,7 +1537,7 @@ test_nc_rename_att(void)
     nc_type atttype;
     size_t length;
     size_t attlength;
-    char  text[MAX_NELS];
+    signed char  text[MAX_NELS];
     double value[MAX_NELS];
     double expect;
 
@@ -1999,7 +1999,7 @@ nc_get_file_version(char *path, int *version)
    fclose(fp);
    if (strncmp(magic, "CDF", MAGIC_NUM_LEN-1)==0)
    {
-      if (magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CLASSIC || 
+      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];
@@ -2050,7 +2050,7 @@ test_nc_set_default_format(void)
 	  error("setting classic format: status = %d", err);
        if ((file_create(scratch, NC_CLOBBER, &ncid)))
 	  error("bad nc_create: status = %d", err);
-       if ((err=nc_put_att_text(ncid, NC_GLOBAL, "testatt", 
+       if ((err=nc_put_att_text(ncid, NC_GLOBAL, "testatt",
 				sizeof("blah"), "blah")))
 	  error("bad put_att: status = %d", err);
        if ((err=nc_close(ncid)))
diff --git a/nc_test/tests.h b/nc_test/tests.h
index 9a46755..4223ee6 100644
--- a/nc_test/tests.h
+++ b/nc_test/tests.h
@@ -26,8 +26,14 @@
 
     /* Limits of external types (based on those in ncx.h) */
 
+#ifdef __CHAR_UNSIGNED__
+#define X_CHAR_MIN	SCHAR_MIN
+#define X_CHAR_MAX	SCHAR_MAX
+#else
 #define X_CHAR_MIN	CHAR_MIN
 #define X_CHAR_MAX	CHAR_MAX
+#endif //__unsigned_char__
+
 #define X_BYTE_MIN	(-128)
 #define X_BYTE_MAX	127
 #define X_SHORT_MIN	(-32768)
@@ -50,12 +56,12 @@
 #define X_DOUBLE_MAX    1.79769313486230e+308
 #else
 /* scalb(1. - scalb(.5 , -52), 1024) */
-#define X_DOUBLE_MAX	1.7976931348623157e+308 
+#define X_DOUBLE_MAX	1.7976931348623157e+308
 #endif
 #define X_DOUBLE_MIN	(-X_DOUBLE_MAX)
 
-#define X_SCHAR_MAX     X_CHAR_MAX
-#define X_SCHAR_MIN     X_CHAR_MIN
+#define X_SCHAR_MAX     SCHAR_MAX
+#define X_SCHAR_MIN     SCHAR_MIN
 #define X_UCHAR_MAX     UCHAR_MAX
 #define X_UCHAR_MIN     0
 #define X_UBYTE_MAX     X_UCHAR_MAX
@@ -141,7 +147,7 @@ extern int numTypes;  /* number of netCDF data types to test */
 
     /* Limits of internal types */
 
-#define text_min CHAR_MIN
+#define text_min SCHAR_MIN
 #define uchar_min 0
 #define schar_min SCHAR_MIN
 #define short_min SHRT_MIN
@@ -157,7 +163,7 @@ extern int numTypes;  /* number of netCDF data types to test */
 #define uint64_min 0
 #define ulonglong_min uint64_min
 
-#define text_max CHAR_MAX
+#define text_max SCHAR_MAX
 #define uchar_max UCHAR_MAX
 #define schar_max SCHAR_MAX
 #define short_max SHRT_MAX
@@ -199,7 +205,7 @@ extern "C" {
 # include <sys/types.h>
 #endif
 
-typedef char text;
+typedef signed char text;
 typedef signed char schar;
 
 #ifndef HAVE_USHORT
diff --git a/nc_test/util.c b/nc_test/util.c
index fcdb111..25f0b82 100644
--- a/nc_test/util.c
+++ b/nc_test/util.c
@@ -6,7 +6,6 @@
 
 #include "tests.h"
 #include <math.h>
-
 void
 print_nok(int nok)
 {
@@ -125,7 +124,7 @@ inRange_float(const double value, const nc_type datatype)
 /* wrapper for inRange to handle special NC_BYTE/uchar adjustment */
 int
 inRange3(
-    const double value, 
+    const double value,
     const nc_type datatype,
     const nct_itype itype)
 {
@@ -144,14 +143,14 @@ inRange3(
 }
 
 
-/* 
- *  Does x == y, where one is internal and other external (netCDF)?  
+/*
+ *  Does x == y, where one is internal and other external (netCDF)?
  *  Use tolerant comparison based on IEEE FLT_EPSILON or DBL_EPSILON.
  */
 int
 equal(
-    const double x, 
-    const double y, 
+    const double x,
+    const double y,
     nc_type extType, 	/* external data type */
     nct_itype itype)
 {
@@ -264,7 +263,7 @@ int nc2dbl ( const nc_type datatype, const void *p, double *result)
     if ( ! result ) return 3;
     switch (datatype) {
         case NC_BYTE: *result = *((signed char *) p); break;
-        case NC_CHAR: *result = *((char *) p); break;
+        case NC_CHAR: *result = *((signed char *) p); break;
         case NC_SHORT: *result = *((short *) p); break;
         case NC_INT:
 #if INT_MAX >= X_INT_MAX
@@ -303,10 +302,14 @@ int dbl2nc ( const double d, const nc_type datatype, void *p)
                 *((signed char *) p) = r;
                 break;
             case NC_CHAR:
-                r = floor(0.5+d);
-                if ( r < text_min  ||  r > text_max )  return 2;
-                *((char   *) p) = r;
-                break;
+              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;
@@ -371,7 +374,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 type, const int rank, const size_t *index )
 {
     double base;
     double result;
@@ -476,7 +479,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 type, const int rank, const size_t *index )
 {
     double base;
     double result;
@@ -577,9 +580,9 @@ hash( const nc_type type, const int rank, const size_t *index )
 /* wrapper for hash to handle special NC_BYTE/uchar adjustment */
 double
 hash4(
-    const nc_type type, 
-    const int rank, 
-    const size_t *index, 
+    const nc_type type,
+    const int rank,
+    const size_t *index,
     const nct_itype itype)
 {
     double result;
@@ -646,9 +649,9 @@ product(size_t nn, const size_t *sp)
 	return result;
 }
 
-/* 
+/*
    define global variables:
-   dim_name, dim_len, 
+   dim_name, dim_len,
    var_name, var_type, var_rank, var_shape, var_natts, var_dimid, var_nels
    att_name, gatt_name, att_type, gatt_type, att_len, gatt_len
  */
@@ -737,7 +740,7 @@ init_gvars (void)
 
 
 /* define dims defined by global variables */
-void                                                        
+void
 def_dims(int ncid)
 {
     int  err;             /* status */
@@ -753,7 +756,7 @@ def_dims(int ncid)
 
 
 /* define vars defined by global variables */
-void                                                        
+void
 def_vars(int ncid)
 {
     int  err;             /* status */
@@ -769,7 +772,7 @@ def_vars(int ncid)
 
 
 /* put attributes defined by global variables */
-void                                                        
+void
 put_atts(int ncid)
 {
     int  err;             /* status */
@@ -778,7 +781,7 @@ put_atts(int ncid)
     int  j;		/* index of attribute */
     int  allInRange;
     double att[MAX_NELS];
-    char catt[MAX_NELS];
+    signed char catt[MAX_NELS];
 
     for (i = -1; i < numVars; i++) {
 	for (j = 0; j < NATTS(i); j++) {
@@ -788,7 +791,7 @@ put_atts(int ncid)
 		}
 		err = nc_put_att_text(ncid, i, ATT_NAME(i,j),
 		    ATT_LEN(i,j), catt);
-		IF (err) 
+		IF (err)
 		    error("nc_put_att_text: %s", nc_strerror(err));
 	    } else {
 		for (allInRange = 1, k = 0; k < ATT_LEN(i,j); k++) {
@@ -810,7 +813,7 @@ put_atts(int ncid)
 }
 
 /* put variables defined by global variables */
-void                                                        
+void
 put_vars(int ncid)
 {
     size_t start[MAX_RANK];
@@ -819,7 +822,7 @@ put_vars(int ncid)
     int  i;
     size_t  j;
     double value[MAX_NELS];
-    char text[MAX_NELS];
+    signed char text[MAX_NELS];
     int  allInRange;
 
     for (j = 0; j < MAX_RANK; j++)
@@ -855,19 +858,19 @@ put_vars(int ncid)
 
 /* Create & write all of specified file using global variables */
 void
-write_file(char *filename) 
+write_file(char *filename)
 {
     int  ncid; /* netCDF id */
     int  err;  /* status */
     err = file_create(filename, NC_CLOBBER, &ncid);
-    IF (err) 
+    IF (err)
 	error("nc_create: %s", nc_strerror(err));
 
     def_dims(ncid);
     def_vars(ncid);
     put_atts(ncid);
     err = nc_enddef(ncid);
-    IF (err) 
+    IF (err)
 	error("nc_enddef: %s", nc_strerror(err));
 
 #ifdef USE_PNETCDF
@@ -884,7 +887,7 @@ write_file(char *filename)
     put_vars(ncid);
 
     err = nc_close (ncid);
-    IF (err) 
+    IF (err)
 	error("nc_close: %s", nc_strerror(err));
 }
 
@@ -922,7 +925,7 @@ check_vars(int  ncid)
     int  err;		/* status */
     int  i;
     size_t  j;
-    char  text;
+    signed char  text;
     double value;
     nc_type datatype;
     int ndims;
@@ -936,29 +939,29 @@ check_vars(int  ncid)
     for (i = 0; i < numVars; i++) {
         isChar = var_type[i] == NC_CHAR;
 	err = nc_inq_var(ncid, i, name, &datatype, &ndims, dimids, NULL);
-	IF (err) 
+	IF (err)
 	    error("nc_inq_var: %s", nc_strerror(err));
-	IF (strcmp(name, var_name[i]) != 0) 
+	IF (strcmp(name, var_name[i]) != 0)
 	    error("Unexpected var_name");
-	IF (datatype != var_type[i]) 
+	IF (datatype != var_type[i])
 	    error("Unexpected type");
-	IF (ndims != var_rank[i]) 
+	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) 
+	    IF (err)
 		error("nc_inq_dim: %s", nc_strerror(err));
-	    IF (length != var_shape[i][j]) 
+	    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) 
+	    IF (err)
 		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 ",
@@ -979,7 +982,7 @@ check_vars(int  ncid)
 		    } else {
 			IF (!equal(value,expect,var_type[i], NCT_DOUBLE)) {
 			    value = 0;
-	  		    err = nc_get_var1_double(ncid, i, index, &value);		
+	  		    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);
 			    print_n_size_t(var_rank[i], index);
@@ -1003,7 +1006,7 @@ check_vars(int  ncid)
  * check attributes of specified file have expected name, type, length & values
  */
 void
-check_atts(int  ncid) 
+check_atts(int  ncid)
 {
     int  err;		/* status */
     int  i;
@@ -1012,7 +1015,7 @@ check_atts(int  ncid)
     nc_type datatype;
     char name[NC_MAX_NAME];
     size_t length;
-    char  text[MAX_NELS];
+    signed char text[MAX_NELS];
     double value[MAX_NELS];
     double expect;
     int nok = 0;      /* count of valid comparisons */
@@ -1020,12 +1023,12 @@ check_atts(int  ncid)
     for (i = -1; i < numVars; i++) {
 	for (j = 0; j < NATTS(i); j++) {
             err = nc_inq_attname(ncid, i, j, name);
-            IF (err) 
+            IF (err)
                 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);
-	    IF (err) 
+	    IF (err)
 		error("nc_inq_att: %s", nc_strerror(err));
 	    IF (datatype != ATT_TYPE(i,j))
 		error("nc_inq_att: unexpected type");
@@ -1038,9 +1041,9 @@ check_atts(int  ncid)
 		for (k = 0; k < ATT_LEN(i,j); k++) {
 		    IF (text[k] != hash(datatype, -1, &k)) {
 			error("nc_get_att_text: unexpected value");
-                    } else {
-                        nok++;
-                    }
+            } else {
+              nok++;
+            }
 		}
 	    } else {
 		err = nc_get_att_double(ncid, i, name, value);
@@ -1065,7 +1068,7 @@ check_atts(int  ncid)
 
 /* Check file (dims, vars, atts) corresponds to global variables */
 void
-check_file(char *filename) 
+check_file(char *filename)
 {
     int  ncid;		/* netCDF id */
     int  err;		/* status */
@@ -1078,7 +1081,7 @@ check_file(char *filename)
 	check_vars(ncid);
 	check_atts(ncid);
 	err = nc_close (ncid);
-	IF (err) 
+	IF (err)
 	    error("nc_close: %s", nc_strerror(err));
     }
 }
diff --git a/nc_test4/CMakeLists.txt b/nc_test4/CMakeLists.txt
index 2f727f8..18eb4c9 100644
--- a/nc_test4/CMakeLists.txt
+++ b/nc_test4/CMakeLists.txt
@@ -8,7 +8,8 @@ SET(NC4_TESTS tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_vars
   tst_xplatform tst_xplatform2 tst_h_atts2 tst_endian_fill tst_atts
   t_type cdm_sea_soundings tst_vl tst_atts1 tst_atts2
   tst_vars2 tst_files5 tst_files6 tst_sync tst_h_strbug tst_h_refs
-  tst_h_scalar tst_rename tst_h5_endians tst_atts_string_rewrite)
+  tst_h_scalar tst_rename tst_h5_endians tst_atts_string_rewrite
+  tst_put_vars_two_unlim_dim)
 
 # Note, renamegroup needs to be compiled before run_grp_rename
 build_bin_test(renamegroup)
@@ -85,5 +86,3 @@ ENDIF()
 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} ref_chunks1.cdl ref_chunks2.cdl ref_tst_compounds.nc ref_tst_xplatform2_1.nc ref_tst_xplatform2_2.nc ref_tst_dims.nc ref_tst_interops4.nc ref_grp_rename.cdl ref_tst_nvars.nc contig.hdf4 chunked.hdf4)
-
-ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")
diff --git a/nc_test4/Makefile.am b/nc_test4/Makefile.am
index 4aa27da..8245b86 100644
--- a/nc_test4/Makefile.am
+++ b/nc_test4/Makefile.am
@@ -122,7 +122,8 @@ ref_tst_xplatform2_1.nc ref_tst_xplatform2_2.nc ref_tst_dims.nc		\
 ref_tst_interops4.nc run_get_knmi_files.sh CMakeLists.txt               \
 run_grp_rename.sh tst_formatx_hdf4.sh                                   \
 run_chunk_hdf4.sh contiguous.hdf4 chunked.hdf4 \
-tst_h5_endians.c tst_h4_lendian.c tst_atts_string_rewrite.c
+tst_h5_endians.c tst_h4_lendian.c tst_atts_string_rewrite.c \
+tst_put_vars_two_unlim_dim.c
 
 CLEANFILES = tst_mpi_parallel.bin cdm_sea_soundings.nc bm_chunking.nc	\
 bm_radar.nc bm_radar1.nc radar_3d_compression_test.txt			\
diff --git a/nc_test4/Makefile.in b/nc_test4/Makefile.in
index f3add0a..df3055e 100644
--- a/nc_test4/Makefile.in
+++ b/nc_test4/Makefile.in
@@ -882,7 +882,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
@@ -1036,7 +1035,8 @@ ref_tst_xplatform2_1.nc ref_tst_xplatform2_2.nc ref_tst_dims.nc		\
 ref_tst_interops4.nc run_get_knmi_files.sh CMakeLists.txt               \
 run_grp_rename.sh tst_formatx_hdf4.sh                                   \
 run_chunk_hdf4.sh contiguous.hdf4 chunked.hdf4 \
-tst_h5_endians.c tst_h4_lendian.c tst_atts_string_rewrite.c
+tst_h5_endians.c tst_h4_lendian.c tst_atts_string_rewrite.c \
+tst_put_vars_two_unlim_dim.c
 
 CLEANFILES = tst_mpi_parallel.bin cdm_sea_soundings.nc bm_chunking.nc	\
 bm_radar.nc bm_radar1.nc radar_3d_compression_test.txt			\
diff --git a/nc_test4/bm_many_objs.c b/nc_test4/bm_many_objs.c
index 887d3a6..56215ee 100644
--- a/nc_test4/bm_many_objs.c
+++ b/nc_test4/bm_many_objs.c
@@ -61,8 +61,9 @@ int main(int argc, char **argv)
     
     /*  create new file */
     if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
-    /* create N variables, printing time after every 1000.  Because only
-     * NC_MAX_VARS are permitted per group, create the necessary number
+    /* create N variables, printing time after every 1000.  
+     * Put NC_MAX_VARS variables per group (even though netcdf4 non-classic 
+     * format does not limit variable count), create the necessary number
      * of groups to hold nitem variables. */
     numvar = nitem;
     v = 1;
diff --git a/nc_test4/tst_put_vars_two_unlim_dim.c b/nc_test4/tst_put_vars_two_unlim_dim.c
new file mode 100644
index 0000000..98a9b13
--- /dev/null
+++ b/nc_test4/tst_put_vars_two_unlim_dim.c
@@ -0,0 +1,67 @@
+/*
+ * Test contributed in support of netCDF issue
+ * https://github.com/Unidata/netcdf-c/issues/160
+ */
+
+#include "netcdf.h"
+
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+    int ret;
+    int ncid;
+    int dim1id, dim2id;
+    int var1id, var2id;
+    size_t start = 0;
+    size_t count = 5;
+    double vals[] = { 1.0, 2.0, 3.0, 4.0, 5.0 };
+
+    if ((ret = nc_create("tst_put_vars_two_unlim_dim.nc", NC_NETCDF4 | NC_CLOBBER, &ncid))) {
+        printf("nc_create(...): error code = %d\n", ret);
+        return -1;
+    }
+
+    if ((ret = nc_def_dim(ncid, "dim1", NC_UNLIMITED, &dim1id))) {
+        printf("nc_def_dim(...\"dim1\"...): error code = %d\n", ret);
+        nc_close(ncid);
+        return -1;
+    }
+
+    if ((ret = nc_def_dim(ncid, "dim2", NC_UNLIMITED, &dim2id))) {
+        printf("nc_def_dim(...\"dim1\"...): error code = %d\n", ret);
+        nc_close(ncid);
+        return -1;
+    }
+
+    if ((ret = nc_def_var(ncid, "var1", NC_DOUBLE, 1, &dim1id, &var1id))) {
+        printf("nc_def_var(...\"var1\"...): error code = %d\n", ret);
+        nc_close(ncid);
+        return -1;
+    }
+
+    if ((ret = nc_def_var(ncid, "var2", NC_DOUBLE, 1, &dim2id, &var2id))) {
+        printf("nc_def_var(...\"var2\"...): error code = %d\n", ret);
+        nc_close(ncid);
+        return -1;
+    }
+
+    if ((ret = nc_put_vars_double(ncid, var1id, &start, &count, NULL, &vals[0])))  {
+        printf("nc_put_var_double(...var1id...): error code = %d\n", ret);
+        nc_close(ncid);
+        return -1;
+    }
+
+    if ((ret = nc_put_vars_double(ncid, var2id, &start, &count, NULL, &vals[0])))  {
+        printf("nc_put_var_double(...var2id...): error code = %d\n", ret);
+        nc_close(ncid);
+        return -1;
+    }
+
+    if ((ret = nc_close(ncid))) {
+        printf("nc_close(...): error code = %d\n", ret);
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/ncdap_test/Makefile.in b/ncdap_test/Makefile.in
index b5ec8d1..4e4c226 100644
--- a/ncdap_test/Makefile.in
+++ b/ncdap_test/Makefile.in
@@ -567,7 +567,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/ncdap_test/expected3/Makefile.in b/ncdap_test/expected3/Makefile.in
index 929e5f6..14d0f47 100644
--- a/ncdap_test/expected3/Makefile.in
+++ b/ncdap_test/expected3/Makefile.in
@@ -180,7 +180,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/ncdap_test/expected3/test.07.dmp b/ncdap_test/expected3/test.07.dmp
index 7f022c2..c1c6df0 100644
--- a/ncdap_test/expected3/test.07.dmp
+++ b/ncdap_test/expected3/test.07.dmp
@@ -19,6 +19,12 @@ variables:
 	double types.f64(types) ;
 	char types.s(types, maxStrlen64) ;
 	char types.u(types, maxStrlen64) ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
 data:
 
  person.name =
diff --git a/ncdap_test/expected3/test.21.dmp b/ncdap_test/expected3/test.21.dmp
index 3c37480..c037432 100644
--- a/ncdap_test/expected3/test.21.dmp
+++ b/ncdap_test/expected3/test.21.dmp
@@ -10,6 +10,12 @@ variables:
 	int exp.i ;
 	short exp.g(exp.g_0, exp.g_1, exp.g_2) ;
 	short exp.f(exp.f_0, exp.f_1) ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
 data:
 
  exp.j = 1 ;
diff --git a/ncdap_test/expected4/Makefile.in b/ncdap_test/expected4/Makefile.in
index 6c30ea4..929a2fa 100644
--- a/ncdap_test/expected4/Makefile.in
+++ b/ncdap_test/expected4/Makefile.in
@@ -178,7 +178,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/ncdap_test/expected4/test.07.dmp b/ncdap_test/expected4/test.07.dmp
index 401af21..5771649 100644
--- a/ncdap_test/expected4/test.07.dmp
+++ b/ncdap_test/expected4/test.07.dmp
@@ -20,6 +20,12 @@ types:
 variables:
 	person_t person ;
 	types_t types ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
 data:
 
  person = 
diff --git a/ncdap_test/expected4/test.21.dmp b/ncdap_test/expected4/test.21.dmp
index ffa508d..876df50 100644
--- a/ncdap_test/expected4/test.21.dmp
+++ b/ncdap_test/expected4/test.21.dmp
@@ -8,6 +8,12 @@ types:
   }; // exp_t
 variables:
 	exp_t exp ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
 data:
 
  exp = 
diff --git a/ncdap_test/expectremote3/Makefile.in b/ncdap_test/expectremote3/Makefile.in
index 892ffbb..a67f79b 100644
--- a/ncdap_test/expectremote3/Makefile.in
+++ b/ncdap_test/expectremote3/Makefile.in
@@ -180,7 +180,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/ncdap_test/expectremote3/test.01.1.dmp b/ncdap_test/expectremote3/test.01.1.dmp
index 0422960..9caf965 100644
--- a/ncdap_test/expectremote3/test.01.1.dmp
+++ b/ncdap_test/expectremote3/test.01.1.dmp
@@ -1,6 +1,16 @@
 netcdf test {
 variables:
 	double f64 ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
+		:b.Description = "A test byte" ;
+		:b.units = "unknown" ;
+		:i32.Description = "A 32 bit test server int" ;
+		:i32.units = "unknown" ;
 data:
 
  f64 = 1000 ;
diff --git a/ncdap_test/expectremote3/test.01.dmp b/ncdap_test/expectremote3/test.01.dmp
index a874406..e238449 100644
--- a/ncdap_test/expectremote3/test.01.dmp
+++ b/ncdap_test/expectremote3/test.01.dmp
@@ -15,6 +15,12 @@ variables:
 	double f64 ;
 	char s(maxStrlen64) ;
 	char u(maxStrlen64) ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
 data:
 
  b = 0 ;
diff --git a/ncdap_test/expectremote3/test.07.1.dmp b/ncdap_test/expectremote3/test.07.1.dmp
index e6e307c..eabeeb5 100644
--- a/ncdap_test/expectremote3/test.07.1.dmp
+++ b/ncdap_test/expectremote3/test.07.1.dmp
@@ -3,6 +3,16 @@ dimensions:
 	person = 5 ;
 variables:
 	int person.age(person) ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
+		:b.Description = "A test byte" ;
+		:b.units = "unknown" ;
+		:i32.Description = "A 32 bit test server int" ;
+		:i32.units = "unknown" ;
 data:
 
  person.age = 1, 2, 3, 5, 8 ;
diff --git a/ncdap_test/expectremote3/test.07.3.dmp b/ncdap_test/expectremote3/test.07.3.dmp
index 48a452e..df91e0f 100644
--- a/ncdap_test/expectremote3/test.07.3.dmp
+++ b/ncdap_test/expectremote3/test.07.3.dmp
@@ -5,6 +5,16 @@ dimensions:
 variables:
 	char person.name(person, maxStrlen64) ;
 	int person.age(person) ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
+		:b.Description = "A test byte" ;
+		:b.units = "unknown" ;
+		:i32.Description = "A 32 bit test server int" ;
+		:i32.units = "unknown" ;
 data:
 
  person.name =
diff --git a/ncdap_test/expectremote3/test.07.4.dmp b/ncdap_test/expectremote3/test.07.4.dmp
index d72d1fc..6b8ba5b 100644
--- a/ncdap_test/expectremote3/test.07.4.dmp
+++ b/ncdap_test/expectremote3/test.07.4.dmp
@@ -3,6 +3,16 @@ dimensions:
 	types = 5 ;
 variables:
 	float types.f32(types) ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
+		:b.Description = "A test byte" ;
+		:b.units = "unknown" ;
+		:i32.Description = "A 32 bit test server int" ;
+		:i32.units = "unknown" ;
 data:
 
  types.f32 = 0, 0.9999833, 1.999867, 2.99955, 3.998933 ;
diff --git a/ncdap_test/expectremote3/test.07.dmp b/ncdap_test/expectremote3/test.07.dmp
index 4677112..666302a 100644
--- a/ncdap_test/expectremote3/test.07.dmp
+++ b/ncdap_test/expectremote3/test.07.dmp
@@ -19,6 +19,12 @@ variables:
 	double types.f64(types) ;
 	char types.s(types, maxStrlen64) ;
 	char types.u(types, maxStrlen64) ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
 data:
 
  person.name =
diff --git a/ncdap_test/expectremote4/Makefile.in b/ncdap_test/expectremote4/Makefile.in
index 7bd807b..2d353a7 100644
--- a/ncdap_test/expectremote4/Makefile.in
+++ b/ncdap_test/expectremote4/Makefile.in
@@ -180,7 +180,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/ncdap_test/expectremote4/test.01.1.dmp b/ncdap_test/expectremote4/test.01.1.dmp
index 0422960..9caf965 100644
--- a/ncdap_test/expectremote4/test.01.1.dmp
+++ b/ncdap_test/expectremote4/test.01.1.dmp
@@ -1,6 +1,16 @@
 netcdf test {
 variables:
 	double f64 ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
+		:b.Description = "A test byte" ;
+		:b.units = "unknown" ;
+		:i32.Description = "A 32 bit test server int" ;
+		:i32.units = "unknown" ;
 data:
 
  f64 = 1000 ;
diff --git a/ncdap_test/expectremote4/test.01.dmp b/ncdap_test/expectremote4/test.01.dmp
index cadbce6..8154eae 100644
--- a/ncdap_test/expectremote4/test.01.dmp
+++ b/ncdap_test/expectremote4/test.01.dmp
@@ -13,6 +13,12 @@ variables:
 	double f64 ;
 	string s ;
 	string u ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
 data:
 
  b = 0 ;
diff --git a/ncdap_test/expectremote4/test.07.1.dmp b/ncdap_test/expectremote4/test.07.1.dmp
index be5c4f2..f7ec167 100644
--- a/ncdap_test/expectremote4/test.07.1.dmp
+++ b/ncdap_test/expectremote4/test.07.1.dmp
@@ -3,6 +3,16 @@ types:
   int(*) person_t ;
 variables:
 	person_t person ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
+		:b.Description = "A test byte" ;
+		:b.units = "unknown" ;
+		:i32.Description = "A 32 bit test server int" ;
+		:i32.units = "unknown" ;
 data:
 
  person = {1, 2, 3, 5, 8} ;
diff --git a/ncdap_test/expectremote4/test.07.dmp b/ncdap_test/expectremote4/test.07.dmp
index 92b4c4f..97fe85f 100644
--- a/ncdap_test/expectremote4/test.07.dmp
+++ b/ncdap_test/expectremote4/test.07.dmp
@@ -20,6 +20,12 @@ types:
 variables:
 	person_t person ;
 	types_t types ;
+
+// global attributes:
+		:Facility.PrincipleInvestigator = "Mark Abbott\n",
+			"Ph.D" ;
+		:Facility.DataCenter = "COAS Environmental Computer Facility" ;
+		:Facility.DrifterType = "MetOcean WOCE/OCM" ;
 data:
 
  person = 
diff --git a/ncdap_test/t_dap3a.c b/ncdap_test/t_dap3a.c
index afe8cf9..f4bbb08 100644
--- a/ncdap_test/t_dap3a.c
+++ b/ncdap_test/t_dap3a.c
@@ -124,8 +124,8 @@ int main()
     /* Assume that TESTS_ENVIRONMENT was set */
     topsrcdir = getenv("TOPSRCDIR");
     if(topsrcdir == NULL) {
-        fprintf(stderr,"*** FAIL: $abs_top_srcdir not defined: location= %s:%d\n",__FILE__,__LINE__);
-        exit(1);
+        fprintf(stderr,"$abs_top_srcdir not defined: using '../'");
+	topsrcdir = "..";
     }    
     len = strlen("file://") + strlen(topsrcdir) + strlen("/ncdap_test/testdata3/test.02") + 1;
 #ifdef DEBUG
diff --git a/ncdap_test/testdata3/Makefile.in b/ncdap_test/testdata3/Makefile.in
index f061edf..55cf646 100644
--- a/ncdap_test/testdata3/Makefile.in
+++ b/ncdap_test/testdata3/Makefile.in
@@ -180,7 +180,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/ncdap_test/testdata3/synth6.das b/ncdap_test/testdata3/synth6.das
index 6419379..f3ccf44 100644
--- a/ncdap_test/testdata3/synth6.das
+++ b/ncdap_test/testdata3/synth6.das
@@ -1,2 +1,24 @@
-Attributes {}
+Attributes {
+    S1 {
+        v3 {
+          Int32 a1 32;
+	}
+    }
+    GLOBAL {
+	Int32 globalattr 177;
+    }
+    CoreMetadata {
+        OrbitNumber {
+            Int32 Value 375;
+            String Data_Location "PGE";
+            String Mandatory "FALSE";
+        }
+        RangeBeginningDate {
+            String Value "1997/12/21";
+            String Data_Location "PGE";
+            String Mandatory "FALSE";
+        }
+    }
+}
+
 
diff --git a/ncdump/CMakeLists.txt b/ncdump/CMakeLists.txt
index a7ebdd1..075feda 100644
--- a/ncdump/CMakeLists.txt
+++ b/ncdump/CMakeLists.txt
@@ -54,8 +54,10 @@ ENDIF()
 IF(ENABLE_TESTS)
   ADD_EXECUTABLE(rewrite-scalar rewrite-scalar.c)
   ADD_EXECUTABLE(bom bom.c)
+  ADD_EXECUTABLE(tst_dimsizes tst_dimsizes.c)
   TARGET_LINK_LIBRARIES(rewrite-scalar netcdf)
   TARGET_LINK_LIBRARIES(bom netcdf)
+  TARGET_LINK_LIBRARIES(tst_dimsizes netcdf)
 
 IF(MSVC)
   SET_TARGET_PROPERTIES(rewrite-scalar PROPERTIES RUNTIME_OUTPUT_DIRECTORY
@@ -71,6 +73,13 @@ IF(MSVC)
     ${CMAKE_CURRENT_BINARY_DIR})
   SET_TARGET_PROPERTIES(bom PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE
     ${CMAKE_CURRENT_BINARY_DIR})
+
+  SET_TARGET_PROPERTIES(tst_dimsizes PROPERTIES RUNTIME_OUTPUT_DIRECTORY
+    ${CMAKE_CURRENT_BINARY_DIR})
+  SET_TARGET_PROPERTIES(tst_dimsizes PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG
+    ${CMAKE_CURRENT_BINARY_DIR})
+  SET_TARGET_PROPERTIES(tst_dimsizes PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE
+    ${CMAKE_CURRENT_BINARY_DIR})
 ENDIF()
 
   # Base tests
@@ -96,10 +105,9 @@ ENDIF()
   add_sh_test(ncdump tst_nccopy3)
   add_sh_test(ncdump tst_charfill)
 
-
-
   add_sh_test(ncdump tst_formatx3)
   add_sh_test(ncdump tst_bom)
+  add_sh_test(ncdump tst_dimsizes)
 
   # The following test script invokes
   # gcc directly.
@@ -175,6 +183,11 @@ ENDIF()
     add_sh_test(ncdump tst_ncgen4)
   ENDIF()
 
+  add_sh_test(ncdump tst_inttags)
+  IF(USE_NETCDF4)
+    add_sh_test(ncdump tst_inttags4)
+  ENDIF()
+
 
 ENDIF()
 
diff --git a/ncdump/Make0 b/ncdump/Make0
new file mode 100644
index 0000000..41d25a1
--- /dev/null
+++ b/ncdump/Make0
@@ -0,0 +1,24 @@
+# Test c output
+T=tst_dimsizes
+#CMD=valgrind --leak-check=full
+#CMD=gdb --args
+
+#MPI=1
+LLP="LD_LIBRARY_PATH=/usr/local/lib"
+
+ifndef MPI
+CC=gcc
+CFLAGS=-g -O0 -I.. -I../include 
+LDFLAGS=../liblib/.libs/libnetcdf.a  -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -lm -lcurl
+else
+CC=/usr/local/bin/mpicc
+LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz  ../liblib/.libs/libnetcdf.a -ldl -lcurl -lpnetcdf -lmpich -lm
+endif
+
+all::
+	export ${LLP}; export CFLAGS; export LDFLAGS; \
+	${CC} -o $T.exe ${CFLAGS} ${T}.c ${LDFLAGS}; \
+	${CMD} ./$T.exe
+
+cpp::
+	${CC} -E ${CFLAGS} ${T}.c > ${T}.txt
diff --git a/ncdump/Makefile.am b/ncdump/Makefile.am
index 5c6548a..0a1856b 100644
--- a/ncdump/Makefile.am
+++ b/ncdump/Makefile.am
@@ -28,10 +28,11 @@ man_MANS = ncdump.1 nccopy.1
 if BUILD_TESTSETS
 #if !BUILD_DLL
 # These tests are run for both netCDF-4 and non-netCDF-4 builds.
-check_PROGRAMS = rewrite-scalar ctest ctest64 ncdump tst_utf8 bom
-TESTS = run_tests.sh tst_64bit.sh ctest ctest64 tst_output.sh	\
+check_PROGRAMS = rewrite-scalar ctest ctest64 ncdump tst_utf8 bom tst_dimsizes
+TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh ctest ctest64 tst_output.sh	\
 tst_lengths.sh tst_calendars.sh tst_utf8 run_utf8_tests.sh      \
-tst_nccopy3.sh tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh
+tst_nccopy3.sh tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh \
+tst_dimsizes.sh
 
 if LARGE_FILE_TESTS
 TESTS += tst_iter.sh
@@ -51,7 +52,7 @@ tst_enum_data tst_opaque_data tst_string_data tst_vlen_data tst_comp	\
 tst_comp2 tst_nans tst_special_atts tst_unicode tst_fillbug tst_compress \
 tst_chunking tst_h_scalar tst_bug324
 
-TESTS += tst_create_files tst_group_data tst_enum_data tst_opaque_data	\
+TESTS += tst_inttags4.sh tst_create_files tst_group_data tst_enum_data tst_opaque_data	\
 tst_string_data tst_vlen_data tst_comp tst_comp2 tst_nans		\
 tst_special_atts tst_netcdf4.sh tst_h_rdc0 tst_unicode tst_fillbug	\
 tst_fillbug.sh tst_netcdf4_4.sh tst_compress tst_nccopy4.sh             \
@@ -109,9 +110,11 @@ tst_vlen_data.cdl tst_solar_1.cdl tst_format_att.cdl tst_inflated.nc    \
 tmp_subset.cdl tst_inflated4.nc tst_deflated.nc tst_chunking.nc tmp*.nc \
 tst_charfill.nc tmp_tst_charfill.cdl \
 iter.* \
-tst_nc_test_netcdf4_4_0.cdl tst_mud4.nc tst_mud4.cdl tst_mud4-bc.cdl \
-tst_ncf213.cdl tst_ncf213.nc tst_h_scalar.cdl tst_h_scalar.nc \
-tst_mud4_chars.cdl tst_mud4_chars.nc
+tst_nc_test_netcdf4_4_0.cdl tst_mud4.nc tst_mud4.cdl tst_mud4-bc.cdl    \
+tst_ncf213.cdl tst_ncf213.nc tst_h_scalar.cdl tst_h_scalar.nc           \
+tst_mud4_chars.cdl tst_mud4_chars.nc                                    \
+inttags.nc inttags4.nc tst_inttags.cdl tst_inttags4.cdl                 \
+tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc
 
 # These files all have to be included with the distribution.
 EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl		\
@@ -132,11 +135,14 @@ ref_nc_test_netcdf4.cdl ref_tst_special_atts3.cdl tst_brecs.cdl         \
 ref_tst_grp_spec0.cdl ref_tst_grp_spec.cdl tst_grp_spec.sh              \
 ref_tst_charfill.cdl tst_charfill.cdl tst_charfill.sh                   \
 tst_iter.sh tst_mud.sh ref_tst_mud4.cdl ref_tst_mud4-bc.cdl             \
-ref_tst_mud4_chars.cdl \
+ref_tst_mud4_chars.cdl                                                  \
+inttags.cdl inttags4.cdl ref_inttags.cdl ref_inttags4.cdl               \
 ref_tst_ncf213.cdl tst_h_scalar.sh                                      \
 run_utf8_nc4_tests.sh							\
 tst_formatx3.sh tst_formatx4.sh ref_tst_utf8_4.cdl                      \
-CMakeLists.txt XGetopt.c tst_bom.sh tst_inmemory_nc3.sh tst_inmemory_nc4.sh
+tst_inttags.sh tst_inttags4.sh                                          \
+CMakeLists.txt XGetopt.c tst_bom.sh tst_inmemory_nc3.sh                 \
+tst_dimsizes.sh tst_inmemory_nc4.sh
 
 # CDL files and Expected results
 SUBDIRS=cdl expected
diff --git a/ncdump/Makefile.in b/ncdump/Makefile.in
index 844aac9..e41bbf2 100644
--- a/ncdump/Makefile.in
+++ b/ncdump/Makefile.in
@@ -110,17 +110,19 @@ bin_PROGRAMS = ncdump$(EXEEXT) nccopy$(EXEEXT)
 @BUILD_TESTSETS_TRUE at check_PROGRAMS = rewrite-scalar$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@	ctest$(EXEEXT) ctest64$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@	ncdump$(EXEEXT) tst_utf8$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@	bom$(EXEEXT) $(am__EXEEXT_1)
- at BUILD_TESTSETS_TRUE@TESTS = run_tests.sh tst_64bit.sh ctest$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@	ctest64$(EXEEXT) tst_output.sh \
- at BUILD_TESTSETS_TRUE@	tst_lengths.sh tst_calendars.sh \
- at BUILD_TESTSETS_TRUE@	tst_utf8$(EXEEXT) run_utf8_tests.sh \
- at BUILD_TESTSETS_TRUE@	tst_nccopy3.sh tst_charfill.sh \
- at BUILD_TESTSETS_TRUE@	tst_iter.sh tst_formatx3.sh tst_bom.sh \
- at BUILD_TESTSETS_TRUE@	$(am__append_3) $(am__append_4) \
- at BUILD_TESTSETS_TRUE@	$(am__append_5) $(am__EXEEXT_2) \
- at BUILD_TESTSETS_TRUE@	$(am__append_8) tst_ncgen4_classic.sh \
- at BUILD_TESTSETS_TRUE@	$(am__append_9)
+ at BUILD_TESTSETS_TRUE@	bom$(EXEEXT) tst_dimsizes$(EXEEXT) \
+ at BUILD_TESTSETS_TRUE@	$(am__EXEEXT_1)
+ at BUILD_TESTSETS_TRUE@TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh \
+ at BUILD_TESTSETS_TRUE@	ctest$(EXEEXT) ctest64$(EXEEXT) \
+ at BUILD_TESTSETS_TRUE@	tst_output.sh tst_lengths.sh \
+ at BUILD_TESTSETS_TRUE@	tst_calendars.sh tst_utf8$(EXEEXT) \
+ at BUILD_TESTSETS_TRUE@	run_utf8_tests.sh tst_nccopy3.sh \
+ at BUILD_TESTSETS_TRUE@	tst_charfill.sh tst_iter.sh \
+ at BUILD_TESTSETS_TRUE@	tst_formatx3.sh tst_bom.sh \
+ at BUILD_TESTSETS_TRUE@	tst_dimsizes.sh $(am__append_3) \
+ at BUILD_TESTSETS_TRUE@	$(am__append_4) $(am__append_5) \
+ at BUILD_TESTSETS_TRUE@	$(am__EXEEXT_2) $(am__append_8) \
+ at BUILD_TESTSETS_TRUE@	tst_ncgen4_classic.sh $(am__append_9)
 @BUILD_TESTSETS_TRUE@@LARGE_FILE_TESTS_TRUE at am__append_3 = tst_iter.sh
 @BUILD_DISKLESS_TRUE@@BUILD_TESTSETS_TRUE at am__append_4 = tst_inmemory_nc3.sh
 @BUILD_DISKLESS_TRUE@@BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_5 = tst_inmemory_nc4.sh
@@ -131,7 +133,7 @@ bin_PROGRAMS = ncdump$(EXEEXT) nccopy$(EXEEXT)
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_comp2 tst_nans tst_special_atts tst_unicode tst_fillbug tst_compress \
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_chunking tst_h_scalar tst_bug324
 
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_7 = tst_create_files tst_group_data tst_enum_data tst_opaque_data	\
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_7 = tst_inttags4.sh tst_create_files tst_group_data tst_enum_data tst_opaque_data	\
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_string_data tst_vlen_data tst_comp tst_comp2 tst_nans		\
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_special_atts tst_netcdf4.sh tst_h_rdc0 tst_unicode tst_fillbug	\
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_fillbug.sh tst_netcdf4_4.sh tst_compress tst_nccopy4.sh             \
@@ -227,6 +229,10 @@ tst_create_files_SOURCES = tst_create_files.c
 tst_create_files_OBJECTS = tst_create_files.$(OBJEXT)
 tst_create_files_LDADD = $(LDADD)
 tst_create_files_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
+tst_dimsizes_SOURCES = tst_dimsizes.c
+tst_dimsizes_OBJECTS = tst_dimsizes.$(OBJEXT)
+tst_dimsizes_LDADD = $(LDADD)
+tst_dimsizes_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
 tst_enum_data_SOURCES = tst_enum_data.c
 tst_enum_data_OBJECTS = tst_enum_data.$(OBJEXT)
 tst_enum_data_LDADD = $(LDADD)
@@ -311,16 +317,17 @@ am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = bom.c ctest.c ctest64.c $(nccopy_SOURCES) $(ncdump_SOURCES) \
 	rewrite-scalar.c tst_bug324.c tst_chunking.c tst_comp.c \
-	tst_comp2.c tst_compress.c tst_create_files.c tst_enum_data.c \
-	tst_fillbug.c tst_group_data.c tst_h_rdc0.c tst_h_scalar.c \
-	tst_nans.c tst_opaque_data.c tst_special_atts.c \
+	tst_comp2.c tst_compress.c tst_create_files.c tst_dimsizes.c \
+	tst_enum_data.c tst_fillbug.c tst_group_data.c tst_h_rdc0.c \
+	tst_h_scalar.c tst_nans.c tst_opaque_data.c tst_special_atts.c \
 	tst_string_data.c tst_unicode.c tst_utf8.c tst_vlen_data.c
 DIST_SOURCES = bom.c ctest.c ctest64.c $(nccopy_SOURCES) \
 	$(ncdump_SOURCES) rewrite-scalar.c tst_bug324.c tst_chunking.c \
 	tst_comp.c tst_comp2.c tst_compress.c tst_create_files.c \
-	tst_enum_data.c tst_fillbug.c tst_group_data.c tst_h_rdc0.c \
-	tst_h_scalar.c tst_nans.c tst_opaque_data.c tst_special_atts.c \
-	tst_string_data.c tst_unicode.c tst_utf8.c tst_vlen_data.c
+	tst_dimsizes.c tst_enum_data.c tst_fillbug.c tst_group_data.c \
+	tst_h_rdc0.c tst_h_scalar.c tst_nans.c tst_opaque_data.c \
+	tst_special_atts.c tst_string_data.c tst_unicode.c tst_utf8.c \
+	tst_vlen_data.c
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
 	ctags-recursive dvi-recursive html-recursive info-recursive \
 	install-data-recursive install-dvi-recursive \
@@ -547,7 +554,8 @@ am__set_TESTS_bases = \
   bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
   bases=`echo $$bases`
 RECHECK_LOGS = $(TEST_LOGS)
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__EXEEXT_2 = tst_create_files$(EXEEXT) \
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__EXEEXT_2 = tst_inttags4.sh \
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_create_files$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_group_data$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_enum_data$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_opaque_data$(EXEEXT) \
@@ -672,7 +680,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
@@ -835,7 +842,9 @@ CLEANFILES = test0.nc test1.cdl test1.nc test2.cdl ctest1.cdl \
 	tmp_tst_charfill.cdl iter.* tst_nc_test_netcdf4_4_0.cdl \
 	tst_mud4.nc tst_mud4.cdl tst_mud4-bc.cdl tst_ncf213.cdl \
 	tst_ncf213.nc tst_h_scalar.cdl tst_h_scalar.nc \
-	tst_mud4_chars.cdl tst_mud4_chars.nc results/*.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 results/*.nc \
 	results/*.dmp results/*.dmp2 tmp*.cdl tst_bug324.nc
 
 # These files all have to be included with the distribution.
@@ -861,9 +870,11 @@ EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \
 	ref_tst_grp_spec.cdl tst_grp_spec.sh ref_tst_charfill.cdl \
 	tst_charfill.cdl tst_charfill.sh tst_iter.sh tst_mud.sh \
 	ref_tst_mud4.cdl ref_tst_mud4-bc.cdl ref_tst_mud4_chars.cdl \
+	inttags.cdl inttags4.cdl ref_inttags.cdl ref_inttags4.cdl \
 	ref_tst_ncf213.cdl tst_h_scalar.sh run_utf8_nc4_tests.sh \
 	tst_formatx3.sh tst_formatx4.sh ref_tst_utf8_4.cdl \
-	CMakeLists.txt XGetopt.c tst_bom.sh tst_inmemory_nc3.sh \
+	tst_inttags.sh tst_inttags4.sh CMakeLists.txt XGetopt.c \
+	tst_bom.sh tst_inmemory_nc3.sh tst_dimsizes.sh \
 	tst_inmemory_nc4.sh tst_ncgen_shared.sh tst_ncgen4.sh \
 	tst_ncgen4_classic.sh tst_ncgen4_diff.sh tst_ncgen4_cycle.sh \
 	ref_ctest.c ref_ctest64.c
@@ -1013,6 +1024,10 @@ tst_create_files$(EXEEXT): $(tst_create_files_OBJECTS) $(tst_create_files_DEPEND
 	@rm -f tst_create_files$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_create_files_OBJECTS) $(tst_create_files_LDADD) $(LIBS)
 
+tst_dimsizes$(EXEEXT): $(tst_dimsizes_OBJECTS) $(tst_dimsizes_DEPENDENCIES) $(EXTRA_tst_dimsizes_DEPENDENCIES) 
+	@rm -f tst_dimsizes$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(tst_dimsizes_OBJECTS) $(tst_dimsizes_LDADD) $(LIBS)
+
 tst_enum_data$(EXEEXT): $(tst_enum_data_OBJECTS) $(tst_enum_data_DEPENDENCIES) $(EXTRA_tst_enum_data_DEPENDENCIES) 
 	@rm -f tst_enum_data$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_enum_data_OBJECTS) $(tst_enum_data_LDADD) $(LIBS)
@@ -1085,6 +1100,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_comp2.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_compress.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_create_files.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_dimsizes.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_enum_data.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_fillbug.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_group_data.Po at am__quote@
@@ -1427,6 +1443,13 @@ recheck: all $(check_PROGRAMS)
 	        am__force_recheck=am--force-recheck \
 	        TEST_LOGS="$$log_list"; \
 	exit $$?
+tst_inttags.sh.log: tst_inttags.sh
+	@p='tst_inttags.sh'; \
+	b='tst_inttags.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 run_tests.sh.log: run_tests.sh
 	@p='run_tests.sh'; \
 	b='run_tests.sh'; \
@@ -1525,6 +1548,13 @@ tst_bom.sh.log: tst_bom.sh
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tst_dimsizes.sh.log: tst_dimsizes.sh
+	@p='tst_dimsizes.sh'; \
+	b='tst_dimsizes.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 tst_inmemory_nc3.sh.log: tst_inmemory_nc3.sh
 	@p='tst_inmemory_nc3.sh'; \
 	b='tst_inmemory_nc3.sh'; \
@@ -1539,6 +1569,13 @@ tst_inmemory_nc4.sh.log: tst_inmemory_nc4.sh
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tst_inttags4.sh.log: tst_inttags4.sh
+	@p='tst_inttags4.sh'; \
+	b='tst_inttags4.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 tst_create_files.log: tst_create_files$(EXEEXT)
 	@p='tst_create_files$(EXEEXT)'; \
 	b='tst_create_files'; \
diff --git a/ncdump/cdl/Makefile.am b/ncdump/cdl/Makefile.am
index 569d429..45a3998 100644
--- a/ncdump/cdl/Makefile.am
+++ b/ncdump/cdl/Makefile.am
@@ -24,7 +24,7 @@ ref_tst_opaque_data.cdl  \
 ref_tst_vlen_data.cdl ref_tst_vlen_data2.cdl \
 ref_niltest.cdl ref_tst_h_scalar.cdl ref_tst_econst.cdl \
 ref_tst_nul3.cdl ref_tst_nul4.cdl ref_tst_names.cdl \
-ref_tst_long_charconst.cdl tst_chararray.cdl \
+ref_tst_long_charconst.cdl tst_chararray.cdl ref_keyword.cdl \
 CMakeLists.txt
 
 
diff --git a/ncdump/cdl/Makefile.in b/ncdump/cdl/Makefile.in
index 1db16c2..e33daec 100644
--- a/ncdump/cdl/Makefile.in
+++ b/ncdump/cdl/Makefile.in
@@ -180,7 +180,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
@@ -320,7 +319,7 @@ ref_tst_opaque_data.cdl  \
 ref_tst_vlen_data.cdl ref_tst_vlen_data2.cdl \
 ref_niltest.cdl ref_tst_h_scalar.cdl ref_tst_econst.cdl \
 ref_tst_nul3.cdl ref_tst_nul4.cdl ref_tst_names.cdl \
-ref_tst_long_charconst.cdl tst_chararray.cdl \
+ref_tst_long_charconst.cdl tst_chararray.cdl ref_keyword.cdl \
 CMakeLists.txt
 
 all: all-am
diff --git a/ncdump/cdl/ref_keyword.cdl b/ncdump/cdl/ref_keyword.cdl
new file mode 100644
index 0000000..f3c5686
--- /dev/null
+++ b/ncdump/cdl/ref_keyword.cdl
@@ -0,0 +1,9 @@
+netcdf file {
+variables:
+int data;
+data : _FillValue = 0;
+
+data:
+
+data = 177;
+}
diff --git a/ncdump/cdl/ref_tst_solar_1.cdl b/ncdump/cdl/ref_tst_solar_1.cdl
index c0e34bc..5f25974 100755
--- a/ncdump/cdl/ref_tst_solar_1.cdl
+++ b/ncdump/cdl/ref_tst_solar_1.cdl
@@ -4,14 +4,14 @@ dimensions:
 
 // global attributes:
 		:Number_of_vogons = 2ub, 23ub, 230ub ;
-		:Number_of_vogon_poems = 23232244UL, 1214124123423UL, 2353424234UL ;
+		:Number_of_vogon_poems = 23232244ULL, 1214124123423ULL, 2353424234ULL ;
 
 group: solar_system {
 
   group: Earth {
 
     // global attributes:
-    		:alien_concept_number_which_cannot_be_understood_by_humans = -23232244L, 1214124123423L, -2353424234L ;
+    		:alien_concept_number_which_cannot_be_understood_by_humans = -23232244, 1214124123423, -2353424234 ;
 
     group: Luna {
       variables:
diff --git a/ncdump/chunkspec.c b/ncdump/chunkspec.c
index d5a3b26..c92dc48 100644
--- a/ncdump/chunkspec.c
+++ b/ncdump/chunkspec.c
@@ -109,12 +109,16 @@ chunkspec_parse(int ncid, const char *spec) {
 		if(ret != NC_NOERR)
 		    return(ret);
 		chunksize = dimlen;
-	    } else {	      /* convert nnn string to long integer */
+	    } else {	      /* convert nnn string to long long integer */
 		char *ep;
-		long val = strtol(pp, &ep, 0);
+#ifdef HAVE_STRTOLL
+		long long val = strtoll(pp, &ep, 0);
+#else
+		long long val = strtol(pp, &ep, 0);
+#endif
 		if(ep == pp || errno == ERANGE || val < 1) /* allow chunksize bigger than dimlen */
 		    return (NC_EINVAL);
-		chunksize = val;
+		chunksize = (size_t)val;
 	    }
 	    chunkspecs.chunksizes[idim] = chunksize;
 	    idim++;
diff --git a/ncdump/ctests.sh b/ncdump/ctests.sh
index af507cf..809ce98 100755
--- a/ncdump/ctests.sh
+++ b/ncdump/ctests.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 #set -e
-set -x
 echo "*** ctests.sh: testing ncgen4 -c"
 
 KFLAG=3
diff --git a/ncdump/expected/Makefile.am b/ncdump/expected/Makefile.am
index b4601d7..291f469 100644
--- a/ncdump/expected/Makefile.am
+++ b/ncdump/expected/Makefile.am
@@ -20,7 +20,7 @@ ref_solar.dmp unlimtest1.dmp unlimtest2.dmp \
 ref_tst_vlen_data.dmp ref_tst_vlen_data2.dmp \
 ref_niltest.dmp ref_tst_h_scalar.dmp ref_tst_econst.dmp \
 ref_tst_nul3.dmp ref_tst_nul4.dmp ref_tst_names.dmp \
-ref_tst_long_charconst.dmp tst_chararray.dmp \
+ref_tst_long_charconst.dmp tst_chararray.dmp ref_keyword.dmp \
 CMakeLists.txt
 
 # These do not exist because they are not run as usual tests
diff --git a/ncdump/expected/Makefile.in b/ncdump/expected/Makefile.in
index 1883008..8e4cbea 100644
--- a/ncdump/expected/Makefile.in
+++ b/ncdump/expected/Makefile.in
@@ -178,7 +178,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
@@ -316,7 +315,7 @@ ref_solar.dmp unlimtest1.dmp unlimtest2.dmp \
 ref_tst_vlen_data.dmp ref_tst_vlen_data2.dmp \
 ref_niltest.dmp ref_tst_h_scalar.dmp ref_tst_econst.dmp \
 ref_tst_nul3.dmp ref_tst_nul4.dmp ref_tst_names.dmp \
-ref_tst_long_charconst.dmp tst_chararray.dmp \
+ref_tst_long_charconst.dmp tst_chararray.dmp ref_keyword.dmp \
 CMakeLists.txt
 
 all: all-am
diff --git a/ncdump/expected/c0.dmp b/ncdump/expected/c0.dmp
index 10654ed..8a26bd3 100644
--- a/ncdump/expected/c0.dmp
+++ b/ncdump/expected/c0.dmp
@@ -20,7 +20,7 @@ variables:
 		s:b = 0b, 127b, -128b, -1b ;
 		s:s = -32768s, 0s, 32767s ;
 	int i ;
-		i:i = -2147483647L, 0L, 2147483647L ;
+		i:i = -2147483647, 0, 2147483647 ;
 		i:f = -1.e+36f, 0.f, 1.e+36f ;
 		i:d = -1.e+308, 0., 1.e+308 ;
 	float f ;
@@ -102,7 +102,7 @@ variables:
 		:Gc = "" ;
 		:Gb = -128b, 127b ;
 		:Gs = -32768s, 0s, 32767s ;
-		:Gi = -2147483647L, 0L, 2147483647L ;
+		:Gi = -2147483647, 0, 2147483647 ;
 		:Gf = -1.e+36f, 0.f, 1.e+36f ;
 		:Gd = -1.e+308, 0., 1.e+308 ;
 		:Gatt-name-dashes = -1 ;
diff --git a/ncdump/expected/ref_ctest1_nc4.dmp b/ncdump/expected/ref_ctest1_nc4.dmp
index 8f355f0..52a0fab 100644
--- a/ncdump/expected/ref_ctest1_nc4.dmp
+++ b/ncdump/expected/ref_ctest1_nc4.dmp
@@ -20,7 +20,7 @@ variables:
 		s:b = 0b, 127b, -128b, -1b ;
 		s:s = -32768s, 0s, 32767s ;
 	int i ;
-		i:i = -2147483647L, 0L, 2147483647L ;
+		i:i = -2147483647, 0, 2147483647 ;
 		i:f = -1.e+36f, 0.f, 1.e+36f ;
 		i:d = -1.e+308, 0., 1.e+308 ;
 	float f ;
@@ -102,7 +102,7 @@ variables:
 		:Gc = "" ;
 		:Gb = -128b, 127b ;
 		:Gs = -32768s, 0s, 32767s ;
-		:Gi = -2147483647L, 0L, 2147483647L ;
+		:Gi = -2147483647, 0, 2147483647 ;
 		:Gf = -1.e+36f, 0.f, 1.e+36f ;
 		:Gd = -1.e+308, 0., 1.e+308 ;
 		:Gatt-name-dashes = -1 ;
diff --git a/ncdump/expected/ref_ctest1_nc4c.dmp b/ncdump/expected/ref_ctest1_nc4c.dmp
index d09face..6f918c2 100644
--- a/ncdump/expected/ref_ctest1_nc4c.dmp
+++ b/ncdump/expected/ref_ctest1_nc4c.dmp
@@ -20,7 +20,7 @@ variables:
 		s:b = 0b, 127b, -128b, -1b ;
 		s:s = -32768s, 0s, 32767s ;
 	int i ;
-		i:i = -2147483647L, 0L, 2147483647L ;
+		i:i = -2147483647, 0, 2147483647 ;
 		i:f = -1.e+36f, 0.f, 1.e+36f ;
 		i:d = -1.e+308, 0., 1.e+308 ;
 	float f ;
@@ -102,7 +102,7 @@ variables:
 		:Gc = "" ;
 		:Gb = -128b, 127b ;
 		:Gs = -32768s, 0s, 32767s ;
-		:Gi = -2147483647L, 0L, 2147483647L ;
+		:Gi = -2147483647, 0, 2147483647 ;
 		:Gf = -1.e+36f, 0.f, 1.e+36f ;
 		:Gd = -1.e+308, 0., 1.e+308 ;
 		:Gatt-name-dashes = -1 ;
diff --git a/ncdump/expected/ref_keyword.dmp b/ncdump/expected/ref_keyword.dmp
new file mode 100644
index 0000000..afdf5ae
--- /dev/null
+++ b/ncdump/expected/ref_keyword.dmp
@@ -0,0 +1,8 @@
+netcdf ref_keyword {
+variables:
+	int data ;
+		data :_FillValue = 0 ;
+data:
+
+ data = 177 ;
+}
diff --git a/ncdump/expected/ref_tst_solar_1.dmp b/ncdump/expected/ref_tst_solar_1.dmp
index 4ee0bc2..0c0e9f2 100644
--- a/ncdump/expected/ref_tst_solar_1.dmp
+++ b/ncdump/expected/ref_tst_solar_1.dmp
@@ -4,14 +4,14 @@ dimensions:
 
 // global attributes:
 		:Number_of_vogons = 2UB, 23UB, 230UB ;
-		:Number_of_vogon_poems = 23232244UL, 1214124123423UL, 2353424234UL ;
+		:Number_of_vogon_poems = 23232244ULL, 1214124123423ULL, 2353424234ULL ;
 
 group: solar_system {
 
   group: Earth {
 
     // group attributes:
-    		:alien_concept_number_which_cannot_be_understood_by_humans = -23232244L, 1214124123423L, -2353424234L ;
+    		:alien_concept_number_which_cannot_be_understood_by_humans = -23232244LL, 1214124123423LL, -2353424234LL ;
 
     group: Luna {
       variables:
diff --git a/ncdump/inttags.cdl b/ncdump/inttags.cdl
new file mode 100644
index 0000000..222665a
--- /dev/null
+++ b/ncdump/inttags.cdl
@@ -0,0 +1,15 @@
+netcdf inttags {
+dimensions:
+	d = 3 ;
+variables:
+	byte b(d);
+	short s(d);
+	int i(d);
+data:
+
+ b = -127B, 127b, 255b ;
+
+ s = 32767S, -32766s, 65535s;
+
+ i = -2147483646L, 2147483647l, 4294967295l;
+}
diff --git a/ncdump/inttags4.cdl b/ncdump/inttags4.cdl
new file mode 100644
index 0000000..806469c
--- /dev/null
+++ b/ncdump/inttags4.cdl
@@ -0,0 +1,23 @@
+netcdf inttags64 {
+dimensions:
+	d = 3 ;
+variables:
+	ubyte ub(d);
+	ushort us(d);
+	uint ui(d);
+	int64 i64(d);
+	uint64 ui64(d);
+// global attributes:
+		:attrll = -23232244LL, 1214124123423LL, -2353424234LL ;
+data:
+
+ ub = 255UB, 255ub, 255u ;
+
+ us = 65534US, 65534us, 65534u ;
+
+ ui = 4294967294UL, 4294967294ul, 4294967294u ;
+
+ i64 = 9223372036854775807LL, 9223372036854775807ll, 9223372036854775807 ;
+
+ ui64 = 18446744073709551615ULL, 18446744073709551615ull, 18446744073709551615u ;
+}
diff --git a/ncdump/ncdump.c b/ncdump/ncdump.c
index 7e1c5ac..e84d1e0 100644
--- a/ncdump/ncdump.c
+++ b/ncdump/ncdump.c
@@ -53,6 +53,27 @@ typedef int ssize_t;
 #define int64_t long long
 #define uint64_t unsigned long long
 
+/* If we have a variable named one of these:
+   we need to be careful about printing their attributes.
+*/
+static const char* keywords[] = {
+"variable",
+"dimension",
+"data",
+"group",
+"types",
+NULL
+};
+
+static int iskeyword(const char* kw)
+{
+    const char** p;
+    for(p=keywords;*p;p++) {
+	if(strcmp(kw,*p)==0) return 1;
+    }    
+    return 0;
+}
+
 /* globals */
 char *progname;
 fspec_t formatting_specs =	/* defaults, overridden by command-line options */
@@ -606,11 +627,11 @@ pr_att_valgs(
 	    break;
 	case NC_INT64:
 	    i64 = ((int64_t *) vals)[iel];
-	    printf ("%lldL%s", i64, delim);
+	    printf ("%lldLL%s", i64, delim);
 	    break;
 	case NC_UINT64:
 	    ui64 = ((uint64_t *) vals)[iel];
-	    printf ("%lluUL%s", ui64, delim);
+	    printf ("%lluULL%s", ui64, delim);
 	    break;
 #ifdef USE_NETCDF4
 	case NC_STRING:
@@ -751,6 +772,8 @@ pr_att(
     }
     /* 	printf ("\t\t%s:%s = ", varname, att.name); */
     print_name(varname);
+    if(iskeyword(varname)) /* see discussion about escapes in ncgen man page*/
+	printf(" ");    
     printf(":");
     print_name(att.name);
     printf(" = ");
@@ -1538,7 +1561,7 @@ do_ncdump_rec(int ncid, const char *path)
 	  printf ("UNLIMITED ; // (%u currently)\n",
 		  (unsigned int)dims[dimid].size);
       } else {
-	  printf ("%u ;\n", (unsigned int)dims[dimid].size);
+	  printf ("%llu ;\n", (unsigned long long)dims[dimid].size);
       }
    }
 #endif /* USE_NETCDF4 */
diff --git a/ncdump/ncdump.h b/ncdump/ncdump.h
index 2805d5e..3378b81 100644
--- a/ncdump/ncdump.h
+++ b/ncdump/ncdump.h
@@ -70,7 +70,8 @@ typedef struct {			/* specification for how to format dump */
     int nc_kind;		/* kind of netCDF file named on
 				 * command line, 1 (classic), 2
 				 * (64-bit offset), 3 (netCDF-4), 4
-				 * (netCDF-4 classic model) */
+				 * (netCDF-4 classic model), 5 (64-bit data)
+				 */
     int nc_extended;     	/* extended format info fornetCDF file named
 				 * on command line.
                                  */
diff --git a/ncdump/ref_ctest1_nc4.cdl b/ncdump/ref_ctest1_nc4.cdl
index e6727da..ef6bbed 100644
--- a/ncdump/ref_ctest1_nc4.cdl
+++ b/ncdump/ref_ctest1_nc4.cdl
@@ -28,9 +28,9 @@ variables:
 	double d ;
 		d:c = "abcd\tZ$&" ;
 	int64 i64 ;
-		i64:att_int64 = 1L ;
+		i64:att_int64 = 1LL ;
 	uint64 ui64 ;
-		ui64:att_uint64 = 1UL ;
+		ui64:att_uint64 = 1ULL ;
 	char cr(Dr) ;
 	byte br(Dr) ;
 	short sr(Dr) ;
diff --git a/ncdump/ref_inttags.cdl b/ncdump/ref_inttags.cdl
new file mode 100644
index 0000000..5d70a45
--- /dev/null
+++ b/ncdump/ref_inttags.cdl
@@ -0,0 +1,15 @@
+netcdf inttags {
+dimensions:
+	d = 3 ;
+variables:
+	byte b(d) ;
+	short s(d) ;
+	int i(d) ;
+data:
+
+ b = -127, 127, -1 ;
+
+ s = 32767, -32766, -1 ;
+
+ i = -2147483646, 2147483647, -1 ;
+}
diff --git a/ncdump/ref_inttags4.cdl b/ncdump/ref_inttags4.cdl
new file mode 100644
index 0000000..92eb333
--- /dev/null
+++ b/ncdump/ref_inttags4.cdl
@@ -0,0 +1,24 @@
+netcdf inttags4 {
+dimensions:
+	d = 3 ;
+variables:
+	ubyte ub(d) ;
+	ushort us(d) ;
+	uint ui(d) ;
+	int i64(d) ;
+	uint64 ui64(d) ;
+
+// global attributes:
+		:attrll = -23232244LL, 1214124123423LL, -2353424234LL ;
+data:
+
+ ub = 255, 255, 255 ;
+
+ us = 65534, 65534, 65534 ;
+
+ ui = 4294967294, 4294967294, 4294967294 ;
+
+ i64 = -1, -1, -1 ;
+
+ ui64 = 18446744073709551615, 18446744073709551615, 18446744073709551615 ;
+}
diff --git a/ncdump/ref_tst_solar_1.cdl b/ncdump/ref_tst_solar_1.cdl
index deda1a8..5ff111c 100644
--- a/ncdump/ref_tst_solar_1.cdl
+++ b/ncdump/ref_tst_solar_1.cdl
@@ -4,14 +4,14 @@ dimensions:
 
 // global attributes:
 		:Number_of_vogons = 2UB, 23UB, 230UB ;
-		:Number_of_vogon_poems = 23232244UL, 1214124123423UL, 2353424234UL ;
+		:Number_of_vogon_poems = 23232244ULL, 1214124123423ULL, 2353424234ULL ;
 
 group: solar_system {
 
   group: Earth {
 
     // group attributes:
-    		:alien_concept_number_which_cannot_be_understood_by_humans = -23232244L, 1214124123423L, -2353424234L ;
+    		:alien_concept_number_which_cannot_be_understood_by_humans = -23232244LL, 1214124123423LL, -2353424234LL ;
 
     group: Luna {
       variables:
diff --git a/ncdump/run_back_comp_tests.sh b/ncdump/run_back_comp_tests.sh
index c37ad02..14e554d 100755
--- a/ncdump/run_back_comp_tests.sh
+++ b/ncdump/run_back_comp_tests.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script runs the backward compatibility tests.
 
 set -e
diff --git a/ncdump/run_tests.sh b/ncdump/run_tests.sh
index 4afaca4..cbf9c0a 100755
--- a/ncdump/run_tests.sh
+++ b/ncdump/run_tests.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script runs the ncdump tests.
 # $Id: run_tests.sh,v 1.18 2010/05/19 13:43:39 ed Exp $
 
diff --git a/ncdump/run_utf8_nc4_tests.sh b/ncdump/run_utf8_nc4_tests.sh
index 05a1f86..000d808 100755
--- a/ncdump/run_utf8_nc4_tests.sh
+++ b/ncdump/run_utf8_nc4_tests.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 #
 # Moving some netcdf-4 only tests here, out of tst_nccopy and run_utf8_tests.
 # Without this, the tests fail when netcdf-4 is disabled.
diff --git a/ncdump/run_utf8_tests.sh b/ncdump/run_utf8_tests.sh
index 7d9e8ef..a409513 100755
--- a/ncdump/run_utf8_tests.sh
+++ b/ncdump/run_utf8_tests.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script runs ncdump tests relating to the new UTF8 name stuff.
 # $Id:$
 
diff --git a/ncdump/tst_64bit.sh b/ncdump/tst_64bit.sh
index b8a5468..b8e871e 100755
--- a/ncdump/tst_64bit.sh
+++ b/ncdump/tst_64bit.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script runs the ncdump tests.
 # $Id: tst_64bit.sh,v 1.9 2006/03/04 18:50:15 ed Exp $
 
diff --git a/ncdump/tst_bom.sh b/ncdump/tst_bom.sh
index bd9b4eb..53d2f89 100755
--- a/ncdump/tst_bom.sh
+++ b/ncdump/tst_bom.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script tests BOM support in ncgen
 
 set -e
diff --git a/ncdump/tst_calendars.sh b/ncdump/tst_calendars.sh
index 17ebbf9..8d2313f 100755
--- a/ncdump/tst_calendars.sh
+++ b/ncdump/tst_calendars.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script tests ncdump -t option for CF calendar attributes
 # $Id $
 
diff --git a/ncdump/tst_charfill.sh b/ncdump/tst_charfill.sh
index e9e42ca..96b7909 100755
--- a/ncdump/tst_charfill.sh
+++ b/ncdump/tst_charfill.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script runs an ncgen buf in handling character _Fillvalue.
 set -e
 echo ""
diff --git a/ncdump/tst_dimsizes.c b/ncdump/tst_dimsizes.c
new file mode 100644
index 0000000..913fa4d
--- /dev/null
+++ b/ncdump/tst_dimsizes.c
@@ -0,0 +1,80 @@
+#include <nc_tests.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <netcdf.h>
+
+#define FILECLASSIC "tst_dimsize_classic.nc"
+#define FILE64OFFSET "tst_dimsize_64offset.nc"
+#define FILE64DATA "tst_dimsize_64data.nc"
+
+#define DIMMAXCLASSIC (NC_MAX_INT - 3)
+#define DIMMAX64OFFSET (NC_MAX_UINT - 3)
+#define DIMMAX64DATA (NC_MAX_UINT64 - 3)
+
+/*
+Test that at least the meta-data works
+for dimension sizes X modes.
+NC_CLASSIC => NC_INT_MAX - 3
+NC_64BIT_OFFSET => NC_UINT_MAX - 3
+NC_64BIT_DATA => NC_UINT64_MAX - 3
+Note that this will not test the last case when
+|size_t| == 4.
+Also, leave the files around so we can test with ncdump.
+*/
+
+int
+main(int argc, char **argv) 
+{
+    int ncid;
+    size_t dimsize;
+    int dimid;
+    int stat = NC_NOERR;
+
+    printf("\n*** Testing Max Dimension Sizes\n");
+
+    printf("\n|size_t|=%lu\n",(unsigned long)sizeof(size_t));
+
+    printf("\n*** Writing Max Dimension Size For NC_CLASSIC\n");
+    if ((stat=nc_create(FILECLASSIC, NC_CLOBBER, &ncid))) ERRSTAT(stat);
+    dimsize = DIMMAXCLASSIC;
+    if ((stat=nc_def_dim(ncid, "testdim", dimsize, &dimid))) ERRSTAT(stat);
+    if ((stat=nc_close(ncid))) ERRSTAT(stat);
+
+    printf("\n*** Reading Max Dimension Size For NC_CLASSIC\n");
+    if ((stat=nc_open(FILECLASSIC, NC_NOCLOBBER, &ncid))) ERRSTAT(stat);
+    if ((stat=nc_inq_dimid(ncid, "testdim", &dimid))) ERRSTAT(stat);
+    if ((stat=nc_inq_dimlen(ncid, dimid, &dimsize))) ERRSTAT(stat);
+    if(dimsize != DIMMAXCLASSIC) ERR;
+    if ((stat=nc_close(ncid))) ERRSTAT(stat);
+
+    printf("\n*** Writing Max Dimension Size For NC_64BIT_OFFSET\n");
+    if ((stat=nc_create(FILE64OFFSET, NC_CLOBBER | NC_64BIT_OFFSET, &ncid))) ERRSTAT(stat);
+    dimsize = DIMMAX64OFFSET;
+    if ((stat=nc_def_dim(ncid, "testdim", dimsize, &dimid))) ERRSTAT(stat);
+    if ((stat=nc_close(ncid))) ERRSTAT(stat);
+
+    printf("\n*** Reading Max Dimension Size For NC_64BIT_OFFSET\n");
+    if ((stat=nc_open(FILE64OFFSET, NC_NOCLOBBER|NC_64BIT_OFFSET, &ncid))) ERRSTAT(stat);
+    if ((stat=nc_inq_dimid(ncid, "testdim", &dimid))) ERRSTAT(stat);
+    if ((stat=nc_inq_dimlen(ncid, dimid, &dimsize))) ERRSTAT(stat);
+    if(dimsize != DIMMAX64OFFSET) ERR;
+    if ((stat=nc_close(ncid))) ERRSTAT(stat);
+
+    if(sizeof(size_t) == 8) {
+        printf("\n*** Writing Max Dimension Size For NC_64BIT_DATA\n");
+        if ((stat=nc_create(FILE64DATA, NC_CLOBBER | NC_64BIT_DATA, &ncid))) ERRSTAT(stat);
+        dimsize = (size_t)DIMMAX64DATA;
+        if ((stat=nc_def_dim(ncid, "testdim", dimsize, &dimid))) ERRSTAT(stat);
+        if ((stat=nc_close(ncid))) ERRSTAT(stat);
+
+	printf("\n*** Reading Max Dimension Size For NC_64BIT_DATA\n");
+	if ((stat=nc_open(FILE64DATA, NC_NOCLOBBER|NC_64BIT_DATA, &ncid))) ERRSTAT(stat);
+	if ((stat=nc_inq_dimid(ncid, "testdim", &dimid))) ERRSTAT(stat);
+	if ((stat=nc_inq_dimlen(ncid, dimid, &dimsize))) ERRSTAT(stat);
+	if(dimsize != DIMMAX64DATA) ERR;
+	if ((stat=nc_close(ncid))) ERRSTAT(stat);
+    }      
+
+    SUMMARIZE_ERR;
+    FINAL_RESULTS;
+}
diff --git a/ncdump/tst_dimsizes.sh b/ncdump/tst_dimsizes.sh
new file mode 100755
index 0000000..521a707
--- /dev/null
+++ b/ncdump/tst_dimsizes.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+echo "*** Test Maximum dimension sizes X mode"
+
+set -x
+
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
+# This shell script tests max dimension sizes X mode
+
+RETURN=0
+
+if test "x$srcdir" = "x"; then
+    srcdir=`dirname $0`; 
+fi
+# add hack for sunos
+export srcdir;
+
+echo ""
+
+rm -f tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc
+
+echo "*** Generate: tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc"
+./tst_dimsizes
+
+echo "*** Verify that ncdump can read dimsizes"
+
+rm -fr ./tmp
+if ../ncdump/ncdump -h tst_dimsize_classic.nc > ./tmp ; then
+echo "*** PASS: ncdump tst_dimsize_classic.nc"
+else
+echo "*** FAIL: ncdump tst_dimsize_classic.nc"
+RETURN=1
+fi
+
+rm -fr ./tmp
+if ../ncdump/ncdump -h tst_dimsize_64offset.nc > ./tmp ; then
+echo "*** PASS: ncdump tst_dimsize_64offset.nc"
+else
+echo "*** FAIL: ncdump tst_dimsize_64offset.nc"
+RETURN=1
+fi
+
+if test -f tst_dimsize_64data.nc ; then
+  rm -fr ./tmp
+  if ../ncdump/ncdump -h tst_dimsize_64data.nc > ./tmp ; then
+    echo "*** PASS: ncdump tst_dimsize_64data.nc"
+  else
+    echo "*** FAIL: ncdump tst_dimsize_64data.nc"
+  RETURN=1
+  fi
+fi
+
+# Cleanup
+rm -f tmp tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc
+
+exit $RETURN
+
diff --git a/ncdump/tst_fillbug.sh b/ncdump/tst_fillbug.sh
index 5a85200..90361a0 100755
--- a/ncdump/tst_fillbug.sh
+++ b/ncdump/tst_fillbug.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script runs an ncdump bug test for netcdf-4
 # $Id: tst_fillbug.sh,v 1.1 2008/10/02 19:49:52 russ Exp $
 
diff --git a/ncdump/tst_formatx3.sh b/ncdump/tst_formatx3.sh
index ef0bf38..8105ec6 100755
--- a/ncdump/tst_formatx3.sh
+++ b/ncdump/tst_formatx3.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script tests the output several previous tests.
 # $Id: tst_output.sh,v 1.17 2010/05/14 16:21:15 ed Exp $
 
diff --git a/ncdump/tst_formatx4.sh b/ncdump/tst_formatx4.sh
index 3a0b176..fb666c5 100755
--- a/ncdump/tst_formatx4.sh
+++ b/ncdump/tst_formatx4.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script tests the output several previous tests.
 # $Id: tst_output.sh,v 1.17 2010/05/14 16:21:15 ed Exp $
 
diff --git a/ncdump/tst_grp_spec.sh b/ncdump/tst_grp_spec.sh
index c334595..02c49bb 100755
--- a/ncdump/tst_grp_spec.sh
+++ b/ncdump/tst_grp_spec.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script tests ncdump -g option for specifying groups for
 # which data is to be output.
 # $Id$
diff --git a/ncdump/tst_h_scalar.sh b/ncdump/tst_h_scalar.sh
index 62b16dc..896ee64 100755
--- a/ncdump/tst_h_scalar.sh
+++ b/ncdump/tst_h_scalar.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script runs ncdump to verify scalar attribute and variable output
 
 set -e
diff --git a/ncdump/tst_inmemory_nc3.sh b/ncdump/tst_inmemory_nc3.sh
index 315a946..569f942 100755
--- a/ncdump/tst_inmemory_nc3.sh
+++ b/ncdump/tst_inmemory_nc3.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 verbose=1
 set -e
-set -x
 if test "x$builddir" = "x"; then builddir=`pwd`; fi
 if test "x$srcdir" = "x"; then srcdir=`dirname $0`; fi
 
diff --git a/ncdump/tst_inmemory_nc4.sh b/ncdump/tst_inmemory_nc4.sh
index 2283392..5e46761 100755
--- a/ncdump/tst_inmemory_nc4.sh
+++ b/ncdump/tst_inmemory_nc4.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 verbose=1
 set -e
-set -x
 if test "x$builddir" = "x"; then builddir=`pwd`; fi
 if test "x$srcdir" = "x"; then srcdir=`dirname $0`; fi
 
diff --git a/ncdump/tst_inttags.sh b/ncdump/tst_inttags.sh
new file mode 100755
index 0000000..e8d53bc
--- /dev/null
+++ b/ncdump/tst_inttags.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
+
+set -e
+
+if test "x$srcdir" = x ; then
+srcdir=`pwd`
+fi
+
+echo "*** Test integer constant suffixes"
+echo "*** creating inttags.nc from inttags.cdl..."
+../ncgen/ncgen -lb -o inttags.nc $srcdir/inttags.cdl
+echo "*** creating tst_inttags.cdl from inttags.nc..."
+./ncdump inttags.nc > tst_inttags.cdl
+echo "*** comparing tst_inttags.cdl to ref_inttags.nc..."
+diff -b -w tst_inttags.cdl $srcdir/ref_inttags.cdl
+
+rm inttags.nc tst_inttags.cdl
+
+exit 0
diff --git a/ncdump/tst_inttags4.sh b/ncdump/tst_inttags4.sh
new file mode 100755
index 0000000..8fa40e7
--- /dev/null
+++ b/ncdump/tst_inttags4.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
+
+set -e
+
+if test "x$srcdir" = x ; then
+srcdir=`pwd`
+fi
+
+echo "*** Test netcdf-4 integer constant suffixes"
+
+echo "*** creating inttags4.nc from inttags4.cdl..."
+../ncgen/ncgen -lb -o inttags4.nc $srcdir/inttags4.cdl
+echo "*** creating tst_inttags4.cdl from inttags4.nc..."
+./ncdump inttags4.nc > tst_inttags4.cdl
+echo "*** comparing tst_inttags4.cdl to ref_inttags4.nc..."
+diff -b -w tst_inttags4.cdl $srcdir/ref_inttags4.cdl
+
+rm inttags4.nc tst_inttags4.cdl
+
+exit 0
diff --git a/ncdump/tst_iter.sh b/ncdump/tst_iter.sh
index 68327a6..3f9b165 100755
--- a/ncdump/tst_iter.sh
+++ b/ncdump/tst_iter.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script runs an ncdump bug test for netcdf
 # Test if the nciter code is working [NCF-154]
 
diff --git a/ncdump/tst_lengths.sh b/ncdump/tst_lengths.sh
index dead6b2..9fe1cff 100755
--- a/ncdump/tst_lengths.sh
+++ b/ncdump/tst_lengths.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script tests lengths of small netcdf files and tests 
 # that rewriting a numeric value doesn't change file length
 # $Id: tst_lengths.sh,v 1.10 2008/08/07 00:07:52 ed Exp $
@@ -19,7 +20,6 @@
 # }
 # EOF
 # cat > test-len.sh << 'EOF'
-# #!/bin/sh
 # # test that length of file $1 is $2
 # len=`ls -l $1|awk '{print $5}'`
 # if [ $len = $2 ]; then
diff --git a/ncdump/tst_mud.sh b/ncdump/tst_mud.sh
index 2b63484..83bbaa0 100755
--- a/ncdump/tst_mud.sh
+++ b/ncdump/tst_mud.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script tests ncdump and ncgen on netCDF-4 variables with multiple 
 # unlimited dimensions.
 # $Id $
diff --git a/ncdump/tst_nccopy3.sh b/ncdump/tst_nccopy3.sh
index b2d39ea..1482891 100755
--- a/ncdump/tst_nccopy3.sh
+++ b/ncdump/tst_nccopy3.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # For a netCDF-3 build, test nccopy on netCDF files in this directory
 
 set -e
diff --git a/ncdump/tst_nccopy4.sh b/ncdump/tst_nccopy4.sh
index d861927..6b738ff 100755
--- a/ncdump/tst_nccopy4.sh
+++ b/ncdump/tst_nccopy4.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # For a netCDF-4 build, test nccopy on netCDF files in this directory
 
 set -e
diff --git a/ncdump/tst_ncgen4.sh b/ncdump/tst_ncgen4.sh
index a047e72..39d74f4 100755
--- a/ncdump/tst_ncgen4.sh
+++ b/ncdump/tst_ncgen4.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 verbose=1
 set -e
 
diff --git a/ncdump/tst_ncgen4_classic.sh b/ncdump/tst_ncgen4_classic.sh
index ac15c29..e483f19 100755
--- a/ncdump/tst_ncgen4_classic.sh
+++ b/ncdump/tst_ncgen4_classic.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 
 set -e
 echo ""
diff --git a/ncdump/tst_ncgen4_cycle.sh b/ncdump/tst_ncgen4_cycle.sh
index 5fb2ef1..c97d9a3 100755
--- a/ncdump/tst_ncgen4_cycle.sh
+++ b/ncdump/tst_ncgen4_cycle.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 
 . ${srcdir}/tst_ncgen_shared.sh
 
diff --git a/ncdump/tst_ncgen4_diff.sh b/ncdump/tst_ncgen4_diff.sh
index 5a67143..1a2c3f3 100755
--- a/ncdump/tst_ncgen4_diff.sh
+++ b/ncdump/tst_ncgen4_diff.sh
@@ -1,4 +1,11 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
+
+if test "x$srcdir" = "x"; then srcdir=`pwd`; fi
+if test "x$builddir" = "x"; then builddir=`pwd`; fi
+#for sunos
+export srcdir;
+export builddir;
 
 . ${srcdir}/tst_ncgen_shared.sh
 
@@ -18,7 +25,7 @@ echo "*** Testing ncgen with -k${KFLAG}"
 
 cd ${RESULTSDIR}
 for x in ${TESTSET} ; do
-  test $verbose = 1 && echo "*** Testing: ${x}"
+  if test $verbose = 1 ; then echo "*** Testing: ${x}" ; fi
 	# determine if we need the specflag set
 	specflag=
 	headflag=
@@ -56,7 +63,7 @@ cd ..
 
 totalcount=`expr $passcount + $failcount + $xfailcount`
 okcount=`expr $passcount + $xfailcount`
-#set -x
+
 echo "*** PASSED: ${okcount}/${totalcount} ; ${xfailcount} expected failures ; ${failcount} unexpected failures"
 
 if test $failcount -gt 0 ; then
diff --git a/ncdump/tst_ncgen_shared.sh b/ncdump/tst_ncgen_shared.sh
index c8ffd2f..e4780a1 100755
--- a/ncdump/tst_ncgen_shared.sh
+++ b/ncdump/tst_ncgen_shared.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 
 # To add a new test,
 # 1. put the .cdl file in the 'cdl' directory
@@ -46,7 +47,8 @@ ref_tst_chardata \
 ref_tst_nul3 \
 ref_tst_long_charconst \
 tst_chararray \
-unlimtest1"
+unlimtest1 \
+ref_keyword"
 
 NONCLASSIC3="\
 test0 \
diff --git a/ncdump/tst_netcdf4.sh b/ncdump/tst_netcdf4.sh
index 4bce8cb..36ba2d7 100755
--- a/ncdump/tst_netcdf4.sh
+++ b/ncdump/tst_netcdf4.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script tests ncdump for netcdf-4
 # $Id: tst_netcdf4.sh,v 1.34 2009/09/25 18:22:10 dmh Exp $
 
@@ -14,6 +15,7 @@ echo ""
 echo "*** Testing ncgen and ncdump test output for netCDF-4 format."
 # echo "*** creating netcdf-4 file c0_4.nc from c0_4.cdl..."
 ../ncgen/ncgen -k nc4 -b -o c0_4.nc $srcdir/../ncgen/c0_4.cdl
+
 # echo "*** creating c1_4.cdl from c0_4.nc..."
 ./ncdump -n c1 c0_4.nc | sed 's/e+0/e+/g' > c1_4.cdl
 # echo "*** comparing c1_4.cdl with ref_ctest1_nc4.cdl..."
diff --git a/ncdump/tst_netcdf4_4.sh b/ncdump/tst_netcdf4_4.sh
index 9e25fd8..b76da76 100755
--- a/ncdump/tst_netcdf4_4.sh
+++ b/ncdump/tst_netcdf4_4.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script runs extra tests ncdump for netcdf-4
 # $Id: tst_netcdf4_4.sh,v 1.13 2009/05/06 14:51:52 ed Exp $
 
diff --git a/ncdump/tst_output.sh b/ncdump/tst_output.sh
index 1ce461f..641d40e 100755
--- a/ncdump/tst_output.sh
+++ b/ncdump/tst_output.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+if test "x$SETX" = x1 ; then echo "file=$0"; set -x ; fi
 # This shell script tests the output from several previous tests.
 
 set -e
diff --git a/ncdump/vardata.c b/ncdump/vardata.c
index 620554d..483fc29 100644
--- a/ncdump/vardata.c
+++ b/ncdump/vardata.c
@@ -46,11 +46,11 @@ set_max_len(int len) {
 }
 
 
-/* 
+/*
  * Output a string that should not be split across lines.  If it would
  * make current line too long, first output a newline and current
  * (nested group) indentation, then continuation indentation, then
- * output string.  If string ends with a newline to force short line, 
+ * output string.  If string ends with a newline to force short line,
  * reset indentation after output.
  */
 void
@@ -98,19 +98,19 @@ lput2(
     					/*   chars); saved between calls    */
     int len_prefix = strlen (CDL_COMMENT_PREFIX);
     bool_t make_newline;
-    
+
     size_t len1 = strlen(cp);		/* length of input string */
 
     assert (len1 > 0);
 
 /* (1) Single space or newline/indent sequence, as needed. */
-    
+
     linep = linep + 1 + len1;		/* new line position, without newline */
     					/* add 1 extra for preceding space   */
-    
+
     make_newline = (wrap && (first_item || linep > max_line_len + 2));
     					/* NEVER new line in no-wrap mode */
-    
+
     if (make_newline) {			/* start new line, if needed */
         printf ("\n");
 	indent_out();			/* same exact indentation as pr_att */
@@ -164,8 +164,8 @@ print_any_val(
     const void *valp		/* pointer to the value */
 	    )
 {
-    if (varp->has_fillval && 
-	(*(varp->tinfo->val_equals))((const nctype_t *)varp->tinfo, 
+    if (varp->has_fillval &&
+	(*(varp->tinfo->val_equals))((const nctype_t *)varp->tinfo,
 				     (const void*)varp->fillvalp, valp) ) {
 	sbuf_cpy(sb, FILL_STRING);
     } else {
@@ -235,7 +235,7 @@ pr_any_att_vals(
     sbuf_free(sb);
 }
 
-/* 
+/*
  * Prints brief annotation for a row of data values
  */
 static void
@@ -243,7 +243,7 @@ annotate_brief(
     const ncvar_t *vp,		/* variable */
     const size_t *cor,		/* corner coordinates */
     size_t vdims[]		/* variable dimension sizes */
-    ) 
+    )
 {
     int vrank = vp->ndims;
     int id;
@@ -290,7 +290,7 @@ annotate(
 {
     int vrank = vp->ndims;
     int id;
-    
+
     /* print indices according to data_lang */
 /*     printf("  // %s(", vp->name); */
     printf("  // ");
@@ -409,7 +409,7 @@ upcorner(
     return ret;
 }
 
-/*  Print data values for variable varid.  
+/*  Print data values for variable varid.
  *
  * Recursive to handle possibility of variables with multiple
  * unlimited dimensions, for which the CDL syntax requires use of "{"
@@ -417,7 +417,7 @@ upcorner(
  * in a simple linear list of values.
  */
 static int
-print_rows(     
+print_rows(
     int level,          /* 0 at top-level, incremented for each recursive level */
     int ncid,		/* netcdf id */
     int varid,		/* variable id */
@@ -427,7 +427,7 @@ print_rows(
     size_t edg[],      	/* edges of hypercube */
     void *vals,   	/* allocated buffer for ncols values in a row */
     int marks_pending	/* number of pending closing "}" record markers */
-    ) 
+    )
 {
     int rank = vp->ndims;
     size_t ncols = rank > 0 ? vdims[rank - 1] : 1; /* number of values in a row */
@@ -455,11 +455,11 @@ print_rows(
 	local_cor[level] = 0;
 	local_edg[level] = 1;
 	for(i = 0; i < d0 - 1; i++) {
-	    print_rows(level + 1, ncid, varid, vp, vdims, 
+	    print_rows(level + 1, ncid, varid, vp, vdims,
 		       local_cor, local_edg, vals, 0);
 	    local_cor[level] += 1;
 	}
-	print_rows(level + 1, ncid, varid, vp, vdims, 
+	print_rows(level + 1, ncid, varid, vp, vdims,
 		   local_cor, local_edg, vals, marks_pending);
 	free(local_edg);
 	free(local_cor);
@@ -492,25 +492,25 @@ print_rows(
 	/* determine if this is the last row */
 	lastrow = true;
 	for(j = 0; j < rank - 1; j++) {
-	    if (cor[j] != vdims[j] - 1) {
+      if (cor[j] != vdims[j] - 1) {
 		lastrow = false;
 		break;
-	    }
+      }
 	}
 	if (formatting_specs.full_data_cmnts) {
-	    for (j = 0; j < marks_pending; j++) {
+      for (j = 0; j < marks_pending; j++) {
 		sbuf_cat(sb, "}");
-	    }
-	    printf("%s", sbuf_str(sb));
-	    lastdelim (0, lastrow);
-	    annotate (vp, cor, d0);
+      }
+      printf("%s", sbuf_str(sb));
+      lastdelim (0, lastrow);
+      annotate (vp, cor, d0-1);
 	} else {
-	    for (j = 0; j < marks_pending; j++) {
+      for (j = 0; j < marks_pending; j++) {
 		sbuf_cat(sb, "}");
-	    }
-	    lput(sbuf_str(sb));
-	    lastdelim2 (0, lastrow);
-	}    
+      }
+      lput(sbuf_str(sb));
+      lastdelim2 (0, lastrow);
+	}
     }
     sbuf_free(sb);
     return NC_NOERR;
@@ -578,7 +578,7 @@ vardata(
     }
     nrows = nels/ncols;		/* number of "rows" */
     vals = emalloc(ncols * vp->tinfo->size);
-    
+
     NC_CHECK(print_rows(level, ncid, varid, vp, vdims, cor, edg, vals, marks_pending));
     free(vals);
     free(cor);
@@ -753,7 +753,7 @@ vardatax(
     }
     nrows = nels/ncols;		/* number of "rows" */
     vals = emalloc(ncols * vp->tinfo->size);
-    
+
     for (ir = 0; ir < nrows; ir++) {
 	size_t corsav = 0;
 	bool_t lastrow;
@@ -767,16 +767,16 @@ vardatax(
 	    edg[vrank-1] = ncols;
 	NC_CHECK(nc_get_vara(ncid, varid, cor, edg, vals) );
 	/* Test if we should treat array of chars as a string  */
-	if(vp->type == NC_CHAR && 
+	if(vp->type == NC_CHAR &&
 	   (vp->fmt == 0 || STREQ(vp->fmt,"%s") || STREQ(vp->fmt,""))) {
 	    pr_tvalsx(vp, ncols, 0, lastrow, (char *) vals);
 	} else {
 	    pr_any_valsx(vp, ncols, 0, lastrow, vals);
 	}
-	
+
 	if (vrank > 0)
 	    cor[vrank-1] += ncols;
-	
+
 	if (vrank > 0)
 	  cor[vrank-1] = corsav;
 	if (ir < nrows-1)
diff --git a/ncgen/CMakeLists.txt b/ncgen/CMakeLists.txt
index dc0d5e3..41a8d6b 100644
--- a/ncgen/CMakeLists.txt
+++ b/ncgen/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(ncgen_FILES generate.c main.c cdata.c bindata.c genchar.c cvt.c data.c debug.c escapes.c genc.c genbin.c generr.c genlib.c getfill.c odom.c offsets.c semantics.c ncgentab.c dump.c util.c bytebuffer.c list.c genf77.c f77data.c genj.c jdata.c nc_iter.c ConvertUTF.c  )
+SET(ncgen_FILES generate.c main.c cdata.c bindata.c genchar.c cvt.c data.c debug.c escapes.c genc.c genbin.c generr.c genlib.c getfill.c odom.c offsets.c semantics.c ncgeny.c dump.c util.c bytebuffer.c list.c genf77.c f77data.c genj.c jdata.c nc_iter.c ConvertUTF.c  )
 
 IF(USE_X_GETOPT)
   SET(ncgen_FILES ${ncgen_FILES} XGetopt.c)
@@ -14,9 +14,9 @@ TARGET_LINK_LIBRARIES(ncgen netcdf ${ALL_TLL_LIBS})
 # test scripts to work.
 ####
 IF(MSVC)
-  SET_TARGET_PROPERTIES(ncgen PROPERTIES RUNTIME_OUTPUT_DIRECTORY 
+  SET_TARGET_PROPERTIES(ncgen PROPERTIES RUNTIME_OUTPUT_DIRECTORY
     ${CMAKE_CURRENT_BINARY_DIR})
-  SET_TARGET_PROPERTIES(ncgen PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG 
+  SET_TARGET_PROPERTIES(ncgen PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG
     ${CMAKE_CURRENT_BINARY_DIR})
   SET_TARGET_PROPERTIES(ncgen PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE
     ${CMAKE_CURRENT_BINARY_DIR})
@@ -31,7 +31,7 @@ FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
 # Stuff to build if tests are enabled.
 IF(ENABLE_TESTS)
   FILE(GLOB COPY_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cdl ${CMAKE_CURRENT_SOURCE_DIR}/*.sh)
-  FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) 
+  FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
   add_sh_test(ncgen run_tests)
   IF(USE_NETCDF4)
     add_sh_test(ncgen run_nc4_tests)
@@ -46,7 +46,7 @@ ENDIF()
 SET(CLEANFILES c0.nc c0_64.nc c0_4.nc c0_4c.nc ref_camrun.c)
 SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CLEANFILES}")
 
-# These rules are used if someone wants to rebuild ncgenyy.c or ncgentab.c
+# These rules are used if someone wants to rebuild ncgeny.c or ncgenl.c
 # Otherwise never invoked, but records how to do it.
 # BTW: note that renaming is essential because otherwise
 # autoconf will forcibly delete files of the name *.tab.*
@@ -54,20 +54,20 @@ SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CLEANFILES}")
 ADD_CUSTOM_COMMAND(
   OUTPUT ncgentab.h
   COMMAND flex -Pncg -B ncgen.l
-  COMMAND rm -f ncgenyy.c
-  COMMAND mv lex.ncg.c ncgenyy.c
+  COMMAND rm -f ncgenl.c
+  COMMAND mv lex.ncg.c ncgenl.c
   COMMAND bison -pncg -t -d ncgen.y
-  COMMAND rm -f ncgentab.c ncgentab.h
-  COMMAND mv ncgen.tab.c ncgentab.c
-  COMMAND mv ncgen.tab.h ncgentab.h
-  COMMAND mv ncgentab.h ${CMAKE_CURRENT_SOURCE_DIR}
-  COMMAND mv ncgentab.c ${CMAKE_CURRENT_SOURCE_DIR}
-  COMMAND mv ncgenyy.c ${CMAKE_CURRENT_SOURCE_DIR}
+  COMMAND rm -f ncgeny.c ncgeny.h
+  COMMAND mv ncgen.tab.c ncgeny.c
+  COMMAND mv ncgen.tab.h ncgeny.h
+  COMMAND mv ncgeny.h ${CMAKE_CURRENT_SOURCE_DIR}
+  COMMAND mv ncgeny.c ${CMAKE_CURRENT_SOURCE_DIR}
+  COMMAND mv ncgenl.c ${CMAKE_CURRENT_SOURCE_DIR}
 
   )
 ADD_CUSTOM_TARGET(makeparser DEPENDS ncgentab.h)
 
 ## 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} ncgen.y ncgenyy.c ncgen.l internals.html c0.cdl c0_4.cdl ref_camrun.cdl ncf199.cdl CMakeLists.txt Makefile.am ncgen.1)
+SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} ncgen.y ncgenl.c ncgen.l internals.html c0.cdl c0_4.cdl ref_camrun.cdl ncf199.cdl CMakeLists.txt Makefile.am ncgen.1)
 ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")
diff --git a/ncgen/Makefile.am b/ncgen/Makefile.am
index e27b258..6c36e2e 100644
--- a/ncgen/Makefile.am
+++ b/ncgen/Makefile.am
@@ -11,16 +11,17 @@ bin_PROGRAMS = ncgen
 
 ncgen_SOURCES=generate.c main.c cdata.c bindata.c genchar.c cvt.c data.c debug.c	\
 escapes.c genc.c genbin.c generr.c genlib.c getfill.c odom.c offsets.c	\
-semantics.c ncgentab.c dump.c util.c bytebuffer.c list.c data.h		\
+semantics.c dump.c util.c bytebuffer.c list.c data.h		\
 debug.h generr.h genlib.h includes.h ncgen.h odom.h offsets.h dump.h	\
 util.h bytebuffer.h list.h genf77.c f77data.c genj.c jdata.c nc_iter.h	\
-nc_iter.c ConvertUTF.c ConvertUTF.h
+nc_iter.c ConvertUTF.c ConvertUTF.h \
+ncgeny.c ncgeny.h
 
 # This is the man page.
 man_MANS = ncgen.1
 
 # These files all need to be distributed.
-EXTRA_DIST = ncgen.y ncgenyy.c ncgen.l $(man_MANS) internals.html	\
+EXTRA_DIST = ncgen.y ncgen.l ncgenl.c $(man_MANS) internals.html	\
 run_tests.sh run_nc4_tests.sh c0.cdl c0_4.cdl ref_camrun.cdl \
 ncf199.cdl CMakeLists.txt XGetopt.c c5.cdl
 
@@ -36,16 +37,16 @@ endif # USE_NETCDF4
 CLEANFILES = c0.nc c0_64.nc c0_4.nc c0_4c.nc ref_camrun.c \
 		ncf199.nc c5.nc
 
-# These rules are used if someone wants to rebuild ncgenyy.c or ncgentab.c
+# These rules are used if someone wants to rebuild ncgenl.c or ncgeny.c
 # Otherwise never invoked, but records how to do it.
 # BTW: note that renaming is essential because otherwise
 # autoconf will forcibly delete files of the name *.tab.*
 
 makeparser::
-	flex -Pncg -8 ncgen.l
-	rm -f ncgenyy.c
-	sed -e s/lex.ncg.c/ncgenyy.c/g <lex.ncg.c >ncgenyy.c
+	flex -L -Pncg -8 ncgen.l
+	rm -f ncgenl.c
+	sed -e s/lex.ncg.c/ncgenl.c/g <lex.ncg.c >ncgenl.c
 	bison -pncg -t -d ncgen.y
-	rm -f ncgentab.c ncgentab.h
-	sed -e s/ncgen.tab.c/ncgentab.c/g -e s/ncgen.tab.h/ncgentab.h/g <ncgen.tab.c >ncgentab.c
-	sed -e s/ncgen.tab.c/ncgentab.c/g -e s/ncgen.tab.h/ncgentab.h/g <ncgen.tab.h >ncgentab.h
+	rm -f ncgeny.c ncgeny.h
+	sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.c >ncgeny.c
+	sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.h >ncgeny.h
diff --git a/ncgen/Makefile.in b/ncgen/Makefile.in
index c281b93..5af6bad 100644
--- a/ncgen/Makefile.in
+++ b/ncgen/Makefile.in
@@ -126,11 +126,11 @@ am_ncgen_OBJECTS = generate.$(OBJEXT) main.$(OBJEXT) cdata.$(OBJEXT) \
 	data.$(OBJEXT) debug.$(OBJEXT) escapes.$(OBJEXT) \
 	genc.$(OBJEXT) genbin.$(OBJEXT) generr.$(OBJEXT) \
 	genlib.$(OBJEXT) getfill.$(OBJEXT) odom.$(OBJEXT) \
-	offsets.$(OBJEXT) semantics.$(OBJEXT) ncgentab.$(OBJEXT) \
-	dump.$(OBJEXT) util.$(OBJEXT) bytebuffer.$(OBJEXT) \
-	list.$(OBJEXT) genf77.$(OBJEXT) f77data.$(OBJEXT) \
-	genj.$(OBJEXT) jdata.$(OBJEXT) nc_iter.$(OBJEXT) \
-	ConvertUTF.$(OBJEXT)
+	offsets.$(OBJEXT) semantics.$(OBJEXT) dump.$(OBJEXT) \
+	util.$(OBJEXT) bytebuffer.$(OBJEXT) list.$(OBJEXT) \
+	genf77.$(OBJEXT) f77data.$(OBJEXT) genj.$(OBJEXT) \
+	jdata.$(OBJEXT) nc_iter.$(OBJEXT) ConvertUTF.$(OBJEXT) \
+	ncgeny.$(OBJEXT)
 ncgen_OBJECTS = $(am_ncgen_OBJECTS)
 ncgen_LDADD = $(LDADD)
 ncgen_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
@@ -459,7 +459,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
@@ -585,17 +584,18 @@ top_srcdir = @top_srcdir@
 LDADD = ${top_builddir}/liblib/libnetcdf.la
 ncgen_SOURCES = generate.c main.c cdata.c bindata.c genchar.c cvt.c data.c debug.c	\
 escapes.c genc.c genbin.c generr.c genlib.c getfill.c odom.c offsets.c	\
-semantics.c ncgentab.c dump.c util.c bytebuffer.c list.c data.h		\
+semantics.c dump.c util.c bytebuffer.c list.c data.h		\
 debug.h generr.h genlib.h includes.h ncgen.h odom.h offsets.h dump.h	\
 util.h bytebuffer.h list.h genf77.c f77data.c genj.c jdata.c nc_iter.h	\
-nc_iter.c ConvertUTF.c ConvertUTF.h
+nc_iter.c ConvertUTF.c ConvertUTF.h \
+ncgeny.c ncgeny.h
 
 
 # This is the man page.
 man_MANS = ncgen.1
 
 # These files all need to be distributed.
-EXTRA_DIST = ncgen.y ncgenyy.c ncgen.l $(man_MANS) internals.html	\
+EXTRA_DIST = ncgen.y ncgen.l ncgenl.c $(man_MANS) internals.html	\
 run_tests.sh run_nc4_tests.sh c0.cdl c0_4.cdl ref_camrun.cdl \
 ncf199.cdl CMakeLists.txt XGetopt.c c5.cdl
 
@@ -725,7 +725,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/list.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/main.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nc_iter.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ncgentab.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ncgeny.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/odom.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/offsets.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/semantics.Po at am__quote@
@@ -1191,19 +1191,19 @@ uninstall-man: uninstall-man1
 .PRECIOUS: Makefile
 
 
-# These rules are used if someone wants to rebuild ncgenyy.c or ncgentab.c
+# These rules are used if someone wants to rebuild ncgenl.c or ncgeny.c
 # Otherwise never invoked, but records how to do it.
 # BTW: note that renaming is essential because otherwise
 # autoconf will forcibly delete files of the name *.tab.*
 
 makeparser::
-	flex -Pncg -8 ncgen.l
-	rm -f ncgenyy.c
-	sed -e s/lex.ncg.c/ncgenyy.c/g <lex.ncg.c >ncgenyy.c
+	flex -L -Pncg -8 ncgen.l
+	rm -f ncgenl.c
+	sed -e s/lex.ncg.c/ncgenl.c/g <lex.ncg.c >ncgenl.c
 	bison -pncg -t -d ncgen.y
-	rm -f ncgentab.c ncgentab.h
-	sed -e s/ncgen.tab.c/ncgentab.c/g -e s/ncgen.tab.h/ncgentab.h/g <ncgen.tab.c >ncgentab.c
-	sed -e s/ncgen.tab.c/ncgentab.c/g -e s/ncgen.tab.h/ncgentab.h/g <ncgen.tab.h >ncgentab.h
+	rm -f ncgeny.c ncgeny.h
+	sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.c >ncgeny.c
+	sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.h >ncgeny.h
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/ncgen/c0_4.cdl b/ncgen/c0_4.cdl
index dd425f7..7e9dfc6 100644
--- a/ncgen/c0_4.cdl
+++ b/ncgen/c0_4.cdl
@@ -20,7 +20,7 @@ variables:
 		s:b = 0b, 127b, -128b, -1b ;
 		s:s = -32768s, 0s, 32767s ;
 	int i ;
-		i:i = -2147483647, 0, 2147483647 ;
+		i:i = -2147483647, 0, 2147483647L ;
 		i:f = -1.e+36f, 0.f, 1.e+36f ;
 		i:d = -1.e+308, 0., 1.e+308 ;
 	float f ;
@@ -28,9 +28,9 @@ variables:
 	double d ;
 		d:c = "abcd\tZ$&" ;
 	int64 i64 ;
-		i64:att_int64 = 1L ;
+		i64:att_int64 = 1LL ;
 	uint64 ui64 ;
-		ui64:att_uint64 = 1UL ;
+		ui64:att_uint64 = 1ULL ;
 	char cr(Dr) ;
 	byte br(Dr) ;
 	short sr(Dr) ;
@@ -127,9 +127,9 @@ data:
 
  d = -10 ;
 
- i64 = 9223372036854775807L;
+ i64 = 9223372036854775807LL;
 
- ui64 = 18446744073709551615UL;
+ ui64 = 18446744073709551615ULL;
 
  cr = "ab" ;
 
diff --git a/ncgen/cdata.c b/ncgen/cdata.c
index a15d5fd..63c8930 100644
--- a/ncgen/cdata.c
+++ b/ncgen/cdata.c
@@ -64,10 +64,10 @@ c_constant(Generator* generator, NCConstant* con, Bytebuffer* buf,...)
 	    bbprintf(codetmp,"%lf",con->value.doublev);
 	break;
     case NC_UBYTE:
-        bbprintf(codetmp,"%hhu",con->value.uint8v);
+        bbprintf(codetmp,"%hhuU",con->value.uint8v);
 	break;
     case NC_USHORT:
-	bbprintf(codetmp,"%hu",con->value.uint16v);
+	bbprintf(codetmp,"%huU",con->value.uint16v);
 	break;
     case NC_UINT:
 	bbprintf(codetmp,"%uU",con->value.uint32v);
@@ -76,7 +76,7 @@ c_constant(Generator* generator, NCConstant* con, Bytebuffer* buf,...)
 	bbprintf(codetmp,"%lldLL",con->value.int64v);
 	break;
     case NC_UINT64:
-	bbprintf(codetmp,"%lluLLU",con->value.uint64v);
+	bbprintf(codetmp,"%lluULL",con->value.uint64v);
 	break;
     case NC_ECONST:
 	bbprintf(codetmp,"%s",cname(con->value.enumv));
diff --git a/ncgen/data.c b/ncgen/data.c
index 3c8fd6f..1788033 100644
--- a/ncgen/data.c
+++ b/ncgen/data.c
@@ -153,6 +153,12 @@ srcpeek(Datasrc* ds)
     return NULL;
 }
 
+void
+srcreset(Datasrc* ds)
+{
+    ds->index = 0;
+}
+
 NCConstant*
 srcnext(Datasrc* ds)
 {
diff --git a/ncgen/data.h b/ncgen/data.h
index 2fde09a..58502f3 100644
--- a/ncgen/data.h
+++ b/ncgen/data.h
@@ -122,6 +122,8 @@ void srcsetfill(Datasrc* ds, Datalist* list);
 NCConstant* srcnext(Datasrc*);
 int srcmore(Datasrc*);
 int srcline(Datasrc* ds);
+void srcreset(Datasrc* ds);
+#define srclen(s) ((s)==NULL?0:(s)->length)
 
 #define islistconst(con) ((con)!=NULL && (con)->nctype == NC_COMPOUND)
 #define isfillconst(con) ((con)!=NULL && (con)->nctype == NC_FILLVALUE)
diff --git a/ncgen/genbin.c b/ncgen/genbin.c
index 06503aa..26a85c0 100644
--- a/ncgen/genbin.c
+++ b/ncgen/genbin.c
@@ -47,6 +47,11 @@ gen_netcdf(const char *filename)
     ngrps = listlength(grpdefs);
 #endif /*USE_NETCDF4*/
 
+    /* Turn on logging */
+#ifdef LOGGING
+    nc_set_log_level(ncloglevel);
+#endif
+
     /* create netCDF file, uses NC_CLOBBER mode */
     cmode_modifier |= NC_CLOBBER;
 #ifdef USE_NETCDF4
@@ -255,7 +260,8 @@ Generate type definitions
 static void
 genbin_deftype(Symbol* tsym)
 {
-    int i,stat;
+    unsigned long i;
+    int stat;
 
     ASSERT(tsym->objectclass == NC_TYPE);
     switch (tsym->subclass) {
@@ -321,7 +327,7 @@ genbin_deftype(Symbol* tsym)
 				efield->typ.basetype->ncid);
 	    } else {
 		int j;
-		int dimsizes[NC_MAX_VAR_DIMS];
+		int dimsizes[NC_MAX_VAR_DIMS]; /* int because inside compound */
 		/* Generate the field dimension constants*/
 		for(j=0;j<efield->typ.dimset.ndims;j++) {
 		     unsigned int size = efield->typ.dimset.dimsyms[j]->dim.declsize;
diff --git a/ncgen/genc.c b/ncgen/genc.c
index b421244..42fe04f 100644
--- a/ncgen/genc.c
+++ b/ncgen/genc.c
@@ -131,7 +131,7 @@ gen_ncc(const char *filename)
     bbprintf0(stmt,"%s() {/* create %s */\n", mainname, filename);
     codedump(stmt);
     /* create necessary declarations */
-    codeline("");    
+    codeline("");
     codelined(1,"int  stat;  /* return status */");
     codelined(1,"int  ncid;  /* netCDF id */");
     codeflush();
@@ -142,7 +142,7 @@ gen_ncc(const char *filename)
         codeline("");
         codelined(1,"/* group ids */");
     }
-    if(!usingclassic && ngrps > 0) {    
+    if(!usingclassic && ngrps > 0) {
         for(igrp = 0; igrp < ngrps; igrp++) {
 	    Symbol* gsym = (Symbol*)listget(grpdefs,igrp);
 	    bbprintf0(stmt,"%sint %s;\n",indented(1),groupncid(gsym));
@@ -241,7 +241,7 @@ gen_ncc(const char *filename)
     } else if (cmode_modifier & NC_CLASSIC_MODEL) {
 	cmode_string = "NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL";
     } else if (cmode_modifier & NC_NETCDF4) {
-	cmode_string = "NC_CLOBBER|NC_NETCDF4";	
+	cmode_string = "NC_CLOBBER|NC_NETCDF4";
 #endif
     } else {
         derror("unknown cmode modifier");
@@ -252,7 +252,7 @@ gen_ncc(const char *filename)
     codedump(stmt);
     codelined(1,"check_err(stat,__LINE__,__FILE__);");
     codeflush();
-    
+
 #ifdef USE_NETCDF4
     genc_defineglobalspecials();
 #endif /*USE_NETCDF4*/
@@ -351,19 +351,19 @@ gen_ncc(const char *filename)
 	}
     }
     codeflush();
-    
+
     /* Define the global attributes*/
     if(ngatts > 0) {
 	codeline("");
 	codelined(1,"/* assign global attributes */");
 	for(iatt = 0; iatt < ngatts; iatt++) {
 	    Symbol* gasym = (Symbol*)listget(gattdefs,iatt);
-	    genc_defineattr(gasym);	    
+	    genc_defineattr(gasym);
 	}
 	codeline("");
     }
     codeflush();
-    
+
     /* Define the variable specific attributes*/
     if(natts > 0) {
 	codeline("");
@@ -440,11 +440,11 @@ genc_definespecialattributes(Symbol* vsym)
             codepartial("NULL");
         else {
             bbprintf0(stmt,"%s_chunksizes",cname(vsym));
-            codedump(stmt);                 
+            codedump(stmt);
         }
         codeline(");");
         codelined(1,"check_err(stat,__LINE__,__FILE__);");
-    }   
+    }
     if(special->flags & _FLETCHER32_FLAG) {
         bbprintf0(stmt,
                 "    stat = nc_def_var_fletcher32(%s, %s, %d);\n",
@@ -464,7 +464,7 @@ genc_definespecialattributes(Symbol* vsym)
                 (special->_DeflateLevel >= 0?special->_DeflateLevel:0));
         codedump(stmt);
         codelined(1,"check_err(stat,__LINE__,__FILE__);");
-    }   
+    }
     if(special->flags & _ENDIAN_FLAG) {
         bbprintf0(stmt,
                 "    stat = nc_def_var_endian(%s, %s, %s);\n",
@@ -475,7 +475,7 @@ genc_definespecialattributes(Symbol* vsym)
                 );
         codedump(stmt);
         codelined(1,"check_err(stat,__LINE__,__FILE__);");
-    }   
+    }
     if(special->flags & _NOFILL_FLAG) {
         bbprintf0(stmt,
                 "    stat = nc_def_var_fill(%s, %s, %s, NULL);\n",
@@ -485,7 +485,7 @@ genc_definespecialattributes(Symbol* vsym)
                 );
         codedump(stmt);
         codelined(1,"check_err(stat,__LINE__,__FILE__);");
-    }   
+    }
 }
 #endif /*USE_NETCDF4*/
 
@@ -537,7 +537,7 @@ nctype(nc_type type)
 /*
  * Return C type name for netCDF type, given type code.
  */
-const char* 
+const char*
 ncctype(nc_type type)
 {
     switch (type) {
@@ -574,7 +574,7 @@ ncctype(nc_type type)
 /*
  * Return C type name for netCDF type suffix, given type code.
  */
-const char* 
+const char*
 ncstype(nc_type nctype)
 {
     switch (nctype) {
@@ -845,7 +845,7 @@ genc_deftype(Symbol* tsym)
 	    int j;
 	    Symbol* efield = (Symbol*)listget(tsym->subnodes,i);
 	    ASSERT(efield->subclass == NC_FIELD);
-	    if(efield->typ.dimset.ndims == 0) continue;	    
+	    if(efield->typ.dimset.ndims == 0) continue;
 	    bbprintf0(stmt,"%sstatic int %s_dims[%d] = {\n",
 			indented(1),
 			cname(efield),efield->typ.dimset.ndims);
@@ -870,7 +870,7 @@ genc_deftype(Symbol* tsym)
 	    snprintf(tmp,sizeof(tmp),"NC_COMPOUND_OFFSET(%s,%s)",
 			ctypename(tsym), cname(efield));
 #endif
-	    if(efield->typ.dimset.ndims > 0){ 
+	    if(efield->typ.dimset.ndims > 0){
 	        bbprintf0(stmt,"%sstat = nc_insert_array_compound(%s, %s, \"%s\", %s, %s, %d, %s_dims);",
 		    indented(1),
 		    groupncid(tsym->container),
@@ -968,7 +968,7 @@ genc_writevar(Generator* generator, Symbol* vsym, Bytebuffer* code,
 	}
 	listfree(vlendecls);
 	generator_reset(generator,NULL);
-    }       
+    }
 
     if(rank == 0) {
 	codelined(1,"size_t count = 0;");
@@ -1005,7 +1005,7 @@ genc_writevar(Generator* generator, Symbol* vsym, Bytebuffer* code,
 	    codedump(code);
 	    codeline(" ;");
 	} else {
-	    /* Compute total size */ 
+	    /* Compute total size */
 	    length = 1;
     	    for(i=0;i<rank;i++) length *= count[i];
 	    /* generate data constant */
@@ -1021,9 +1021,9 @@ genc_writevar(Generator* generator, Symbol* vsym, Bytebuffer* code,
 	    codedump(code);
 	    codeline("} ;");
 	}
-	
+
 	/* generate constants for startset, countset*/
-	bbprintf0(stmt,"%ssize_t %s_startset[%lu] = {",
+	bbprintf0(stmt,"%ssize_t %s_startset[%u] = {",
 			indented(1),
 			cname(vsym),
 			rank);
@@ -1032,8 +1032,8 @@ genc_writevar(Generator* generator, Symbol* vsym, Bytebuffer* code,
 	}
 	codedump(stmt);
 	codeline("} ;");
-	
-	bbprintf0(stmt,"%ssize_t %s_countset[%lu] = {",
+
+	bbprintf0(stmt,"%ssize_t %s_countset[%u] = {",
 			indented(1),
 			cname(vsym),
 			rank);
@@ -1042,7 +1042,7 @@ genc_writevar(Generator* generator, Symbol* vsym, Bytebuffer* code,
 	}
 	codedump(stmt);
 	codeline("};");
-	
+
 	bbprintf0(stmt,"%sstat = nc_put_vara(%s, %s, %s_startset, %s_countset, %s_data);\n",
 			indented(1),
 			groupncid(vsym->container), varncid(vsym),
@@ -1051,13 +1051,13 @@ genc_writevar(Generator* generator, Symbol* vsym, Bytebuffer* code,
 			cname(vsym));
 	codedump(stmt);
 	codelined(1,"check_err(stat,__LINE__,__FILE__);");
-	
+
     }
     /* end defined block*/
     codelined(1,"}\n");
     codeflush();
 }
-	
+
 static void
 genc_writeattr(Generator* generator, Symbol* asym, Bytebuffer* code,
                int rank, size_t* start, size_t* count)
@@ -1090,7 +1090,7 @@ genc_writeattr(Generator* generator, Symbol* asym, Bytebuffer* code,
             }
             listfree(vlendecls);
             generator_reset(generator,NULL);
-        }       
+        }
         commify(code);
         bbprintf0(stmt,"%sstatic const %s %s_att[%ld] = ",
                         indented(1),
@@ -1120,7 +1120,7 @@ genc_writeattr(Generator* generator, Symbol* asym, Bytebuffer* code,
 		(asym->att.var == NULL?"NC_GLOBAL"
 			              :varncid(asym->att.var)),
 		escapifyname(asym->name),
-		typencid(basetype),		
+		typencid(basetype),
 	 	len,
 		cname(asym));
 	codedump(stmt);
@@ -1157,7 +1157,7 @@ genc_writeattr(Generator* generator, Symbol* asym, Bytebuffer* code,
 		(asym->att.var == NULL?"NC_GLOBAL"
 			              :varncid(asym->att.var)),
 		escapifyname(asym->name),
-		typencid(basetype),		
+		typencid(basetype),
 	 	len,
 		cname(asym));
 	codedump(stmt);
@@ -1221,9 +1221,8 @@ cname(Symbol* sym)
     if(sym->grp.is_root)
 	name = codify(sym->name);
     else
-	name = codify(sym->fqn);    
+	name = codify(sym->fqn);
     return name;
 }
 
 #endif /*ENABLE_C*/
-
diff --git a/ncgen/generr.c b/ncgen/generr.c
index b1ec973..348816f 100644
--- a/ncgen/generr.c
+++ b/ncgen/generr.c
@@ -28,10 +28,26 @@ void
 vderror(fmt,va_alist) const char* fmt; va_dcl
 #endif
 {
+    (void) vdwarn(fmt,argv);
+    error_count++;
+}
+
+/*
+ * For logging error conditions.
+ * Designed to be called by other vararg procedures
+ */
+#ifndef NO_STDARG
+void
+vdwarn(const char *fmt, va_list argv)
+#else
+/* Technically illegal; va_alist should be only arg */
+void
+vdwarn(fmt,va_alist) const char* fmt; va_dcl
+#endif
+{
     (void) vfprintf(stderr,fmt,argv) ;
     (void) fputc('\n',stderr) ;
     (void) fflush(stderr);	/* to ensure log files are current */
-    error_count++;
 }
 
 #ifndef NO_STDARG
@@ -76,7 +92,7 @@ semwarn(lno,fmt,va_alist) const int lno; const char* fmt; va_dcl
     va_list argv;
     vastart(argv,fmt);
     (void)fprintf(stderr,"%s: %s line %d: ", progname, cdlname, lno);
-    vderror(fmt,argv);
+    vdwarn(fmt,argv);
 }
 
 #ifndef NO_STDARG
diff --git a/ncgen/generr.h b/ncgen/generr.h
index 2981892..96b0094 100644
--- a/ncgen/generr.h
+++ b/ncgen/generr.h
@@ -19,17 +19,23 @@ extern int error_count;
 #ifndef NO_STDARG
 #include <stdarg.h>
 extern void vderror(const char *fmt, va_list argv);
+extern void vdwarn(const char *fmt, va_list argv);
 extern void derror(const char *fmt, ...);
 extern int panic(const char* fmt, ...);
 extern void nprintf(char* buffer, size_t size, const char *fmt, ...);
+extern  void semerror(const int, const char *fmt, ...);
+extern  void semwarn(const int, const char *fmt, ...);
 #else
 #include <varargs.h>
 /* Technically illegal; va_alist should be only arg */
 extern void vderror(fmt,va_alist) const char* fmt; va_dcl;
+extern void vdwarn(fmt,va_alist) const char* fmt; va_dcl;
 extern void derror(fmt,va_alist) const char* fmt; va_dcl;
 extern void panic(fmt,va_alist) const char* fmt; va_dcl;
 extern void nprintf(buffer,size,fmt)
 	char* buffer; size_t size; const char* fmt; va_dcl;
+extern  void semerror(lno,fmt,va_alist) const int lno; const char* fmt; va_dcl;
+extern  void semwarnlno,fmt,va_alist) const int lno; const char* fmt; va_dcl;
 #endif
 
 #endif /*GENERR_H*/
diff --git a/ncgen/genlib.h b/ncgen/genlib.h
index 2c6c87e..b5974d0 100644
--- a/ncgen/genlib.h
+++ b/ncgen/genlib.h
@@ -97,13 +97,6 @@ extern  Symbol* locate(Symbol* refsym);
 extern  Symbol* lookup(nc_class objectclass, Symbol* pattern);
 extern  Symbol* lookupingroup(nc_class objectclass, char* name, Symbol* grp);
 extern  Symbol* lookupgroup(List* prefix);
-#ifndef NO_STDARG
-extern  void semerror(const int, const char *fmt, ...);
-extern  void semwarn(const int, const char *fmt, ...);
-#else
-extern  void semerror(lno,fmt,va_alist) const int lno; const char* fmt; va_dcl;
-extern  void semwarnlno,fmt,va_alist) const int lno; const char* fmt; va_dcl;
-#endif
 extern int nounlimited(Dimset* dimset, int from);
 extern int lastunlimited(Dimset* dimset);
 extern void padstring(NCConstant* con, size_t desiredlength, int fillchar);
@@ -166,6 +159,7 @@ extern int cdf5_flag; /* 1 => cdf-5 unsigned types in the parse */
 extern int specials_flag; /* 1 => special attributes are present */
 extern int usingclassic;   /* 1 => k_flag == 1|2|5 */
 extern int k_flag;
+extern int ncloglevel;
 
 /* Global data */
 
diff --git a/ncgen/getfill.c b/ncgen/getfill.c
index c3e5c15..8b50d64 100644
--- a/ncgen/getfill.c
+++ b/ncgen/getfill.c
@@ -50,7 +50,7 @@ getfiller(Symbol* tvsym)
 static void
 fill(Symbol* tsym, Datalist* filler)
 {
-    int i;
+    unsigned long i;
     NCConstant con = nullconstant;
     Datalist* sublist;
 
@@ -165,7 +165,7 @@ nc_getfill(NCConstant* value)
       case NC_UINT64: value->value.uint64v = NC_FILL_UINT64; break;
       case NC_STRING:
         value->value.stringv.stringv = nulldup(NC_FILL_STRING);
-        value->value.stringv.len = strlen(NC_FILL_STRING);
+        value->value.stringv.len = (int)strlen(NC_FILL_STRING);
 	/* Exception: if string is null, then make it's length be 1 */
 	if(value->value.stringv.len == 0)
 	    value->value.stringv.len = 1;
diff --git a/ncgen/main.c b/ncgen/main.c
index 8181b61..40fb998 100644
--- a/ncgen/main.c
+++ b/ncgen/main.c
@@ -45,8 +45,8 @@ int cdf5_flag; /* 1 => cdf5 | maybe netcdf-4 */
 int specials_flag; /* 1=> special attributes are present */
 int usingclassic;
 int cmode_modifier;
-
 int diskless;
+int ncloglevel;
 
 char* binary_ext = ".nc";
 
@@ -236,15 +236,19 @@ main(
     enhanced_flag = 0;
     cdf5_flag = 0;
     specials_flag = 0;
-
     diskless = 0;
+#ifdef LOGGING
+    ncloglevel = NC_TURN_OFF_LOGGING;
+#else
+    ncloglevel = -1;
+#endif
 
 #if _CRAYMPP && 0
     /* initialize CRAY MPP parallel-I/O library */
     (void) par_io_init(32, 32);
 #endif
 
-    while ((c = getopt(argc, argv, "134567bB:cdD:fhk:l:M:no:Pv:x")) != EOF)
+    while ((c = getopt(argc, argv, "134567bB:cdD:fhHk:l:M:no:Pv:xL:")) != EOF)
       switch(c) {
 	case 'd':
 	  debug = 1;
@@ -278,6 +282,9 @@ main(
 	case 'h':
 	  header_only = 1;
 	  break;
+	case 'H':
+	  usage();
+	  exit(0);
         case 'l': /* specify language, instead of using -c or -f or -b */
 	{
 	    if(l_flag != 0) {
@@ -301,6 +308,9 @@ main(
               return(1);
 	    }
 	}; break;
+	case 'L':
+	    ncloglevel = atoi(optarg);
+	    break;
 	case 'n':		/* old version of -b, uses ".cdf" extension */
 	  if(l_flag != 0) {
 	    fprintf(stderr,"Please specify only one language\n");
@@ -317,7 +327,7 @@ main(
 	  break;
         case 'v': /* a deprecated alias for "kind" option */
 	    /*FALLTHRU*/
-	case 'k': /* for specifying variant of netCDF format to be generated
+	case 'k': { /* for specifying variant of netCDF format to be generated
 		     Possible values are:
 		     Format names:
 		       "classic" or "nc3"
@@ -333,28 +343,27 @@ main(
 		       4 (=> netCDF-4 classic model)
                        5 (=> classic 64 bit data aka CDF-5)
 		   */
-	    {
-		struct Kvalues* kvalue;
-		char *kind_name = (optarg != NULL ? (char *) emalloc(strlen(optarg)+1)
-                           : emalloc(1));
-		if (! kind_name) {
-		    derror ("%s: out of memory", progname);
-		    return(1);
-		}
-        if(optarg != NULL)
-          (void)strcpy(kind_name, optarg);
-        for(kvalue=legalkinds;kvalue->name;kvalue++) {
-          if(strcmp(kind_name,kvalue->name) == 0) {
-            k_flag = kvalue->k_flag;
-			break;
-          }
-		}
-		if(kvalue->name == NULL) {
-		   derror("Invalid format: %s",kind_name);
-		   return 2;
-		}
+	    struct Kvalues* kvalue;
+	    char *kind_name = (optarg != NULL
+				? (char *) emalloc(strlen(optarg)+1)
+				: emalloc(1));
+	    if (! kind_name) {
+		derror ("%s: out of memory", progname);
+		return(1);
 	    }
-	  break;
+            if(optarg != NULL)
+              (void)strcpy(kind_name, optarg);
+            for(kvalue=legalkinds;kvalue->name;kvalue++) {
+              if(strcmp(kind_name,kvalue->name) == 0) {
+                k_flag = kvalue->k_flag;
+                break;
+              }
+            }
+            if(kvalue->name == NULL) {
+                derror("Invalid format: %s",kind_name);
+                return 2;
+            }
+	} break;
 	case '3':		/* output format is classic (netCDF-3) */
 	    k_flag = NC_FORMAT_CLASSIC;
 	    break;
@@ -463,7 +472,7 @@ main(
 		return 1;
 	    case '\xEF':
 		/* skip the BOM */
-	        fread(bom,1,1,fp);
+	        (void)fread(bom,1,1,fp);
 	        break;
 	    default: /* legal printable char, presumably; rewind */
 	        rewind(fp);
@@ -479,8 +488,6 @@ main(
 	}
     }
 
-    /* Standard Unidata java interface => usingclassic */
-
     parse_init();
     ncgin = fp;
     if(debug >= 2) {ncgdebug=1;}
@@ -529,15 +536,32 @@ main(
     if(k_flag == 0)
 	k_flag = 1;
 
-    usingclassic = (k_flag <= 2 || k_flag == 4 || k_flag == 5)?1:0;
+    /* Figure out usingclassic */
+    switch (k_flag) {
+    case NC_FORMAT_64BIT_DATA:
+    case NC_FORMAT_CLASSIC:
+    case NC_FORMAT_64BIT_OFFSET:
+    case NC_FORMAT_NETCDF4_CLASSIC:
+	usingclassic = 1;
+	break;
+    case NC_FORMAT_NETCDF4:
+    default:
+	usingclassic = 0;
+	break;
+    }
 
     /* compute cmode_modifier */
     switch (k_flag) {
-    case 1: cmode_modifier = 0; break;
-    case 2: cmode_modifier = NC_64BIT_OFFSET; break;
-    case 3: cmode_modifier = NC_NETCDF4; break;
-    case 4: cmode_modifier = NC_NETCDF4 | NC_CLASSIC_MODEL; break;
-    case 5: cmode_modifier = NC_CDF5; break;
+    case NC_FORMAT_CLASSIC:
+	cmode_modifier = 0; break;
+    case NC_FORMAT_64BIT_OFFSET:
+	cmode_modifier = NC_64BIT_OFFSET; break;
+    case NC_FORMAT_NETCDF4:
+	cmode_modifier = NC_NETCDF4; break;
+    case NC_FORMAT_NETCDF4_CLASSIC:
+	cmode_modifier = NC_NETCDF4 | NC_CLASSIC_MODEL; break;
+    case NC_FORMAT_64BIT_DATA:
+	cmode_modifier = NC_CDF5; break;
     default: ASSERT(0); /* cannot happen */
     }
 
diff --git a/ncgen/ncf345.cdl b/ncgen/ncf345.cdl
new file mode 100644
index 0000000..c80576a
--- /dev/null
+++ b/ncgen/ncf345.cdl
@@ -0,0 +1,1743 @@
+// -*-C++-*-
+
+// Purpose: CDL file to generate netCDF test file for NCO
+
+// Usage:
+// netCDF4: ncgen arguments depend on version:
+// "-k netCDF-4" for netCDF >= 3.6.3, "-k hdf5" for netCDF < 3.6.3
+// "-k netCDF-4 classic model" for netCDF >= 3.6.3, "-k hdf5-nc3" for netCDF < 3.6.3
+// /usr/local/bin/ncgen -k netCDF-4 -b -o in_4.nc in.cdl
+// /usr/local/bin/ncgen -k netCDF-4 -b -o ${HOME}/nco/data/in_4.nc ${HOME}/nco/data/in.cdl
+// NB: netCDF-classic files will be enormous unless/until _ChunkSizes attributes added to time
+// /usr/local/bin/ncgen -k hdf5-nc3 -b -o in_4c.nc in.cdl
+// /usr/local/bin/ncgen -k hdf5-nc3 -b -o ${HOME}/nco/data/in_4c.nc ${HOME}/nco/data/in.cdl
+
+// URL:
+// http://dust.ess.uci.edu/nco/in.nc
+// http://dust.ess.uci.edu/nco/in_4.nc
+// http://thredds-test.ucar.edu/thredds/dodsC/testdods/in.nc
+// http://thredds-test.ucar.edu/thredds/dodsC/testdods/in_4.nc
+
+// netCDF3:
+// ncgen -b -o in.nc in.cdl
+// ncgen -b -o ${HOME}/nco/data/in.nc ${HOME}/nco/data/in.cdl
+// scp ~/nco/data/in.cdl ~/nco/data/in_4.nc dust.ess.uci.edu:nco/data
+// scp ~/nco/data/in.nc ~/nco/data/in_4.nc dust.ess.uci.edu:/var/www/html/nco
+// scp ~/nco/data/in.nc ~/nco/data/in_4.nc dust.ess.uci.edu:/var/www/html/dodsdata
+// mswrite -t 365 ~/nco/data/in.nc /ZENDER/tmp/in.nc
+// mswrite -t 365 ~/nco/data/in.nc /ZENDER/tmp/h0001.nc
+// mswrite -t 365 ~/nco/data/in.nc /ZENDER/tmp/h0002.nc
+// mswrite -t 365 ~/nco/data/in.nc /ZENDER/tmp/h0003.nc
+// mswrite -t 365 ~/nco/data/in.nc /ZENDER/tmp/h0004.nc
+// msrcp -period 365 ~/nco/data/in.nc mss:/ZENDER/tmp/in.nc
+// msrcp -period 365 ~/nco/data/in.nc mss:/ZENDER/tmp/h0001.nc
+// msrcp -period 365 ~/nco/data/in.nc mss:/ZENDER/tmp/h0002.nc
+// msrcp -period 365 ~/nco/data/in.nc mss:/ZENDER/tmp/h0003.nc
+// msrcp -period 365 ~/nco/data/in.nc mss:/ZENDER/tmp/h0004.nc
+
+// WARNING: Changing values of variables below, especially coordinate variables, affects outcome of nco_tst.pl test script
+// Other programs, e.g., ~/f/fff.F90, ~/c++/ccc.cc, ~/c/c.c may also break
+// In particular, do not change number of elements in record coordinate, time, without simultaneously changing number of data in all record variables
+// My (and NCO's) convention is that the _FillValue, if any, of any packed variable should be of the same type as the expanded variable. Hence _FillValue, add_offset, and scale_factor should all be of the same type. Variables that do not adhere to this convention are not supported.
+
+// Bugs:
+// Some triggering bugs were moved to buggy.cdl to prevent non-builds
+// ncgen 4.0.0--4.3.2 crashes on 'l' or 'L' syntax when generating netCDF4-classic (but not netCDF3 or netCDF4) files until 20141010 (NCF-318)
+
+// CDL Data constants:
+// http://www.unidata.ucar.edu/software/netcdf/docs/netcdf/CDL-Syntax.html
+// byte: 'a'
+// char: "a"
+// short: 1s
+// int: 1 (no decimal point)
+// long: 1 (_not_ 1l;) (long is synonym for int in netCDF3)
+// float: 1.f (decimal point is required, f is required to distinguish from double)
+// double: 1.0, 1.d, 1.0e-20 (decimal point is required, d is not required)
+// CDL complex types:
+// roulee:/data/zender/tmp/netcdf-4.2.1/nc_test/ref_tst_diskless2.cdl
+
+// NCL usage:
+// id_in=addfile("/home/zender/nco/data/in.nc","r")
+// print(id_in)
+// list_filevars(id_in)
+
+netcdf ncf345 {
+dimensions:
+  dgn=1,bnd=2,lat=2,lat_grd=3,lev=3,rlev=3,ilev=4,lon=4,lon_grd=5,char_dmn_lng80=80,char_dmn_lng26=26,char_dmn_lng04=4,date_dmn=5,fl_dmn=3,lsmlev=6,wvl=2,time_udunits=3;lon_T42=128,lat_T42=64,lat_times_lon=8,gds_crd=8,gds_ncd=8,vrt_nbr=2,lon_cal=10,lat_cal=10,Lon=4,Lat=2,time=unlimited;
+variables:
+  :Conventions = "CF-1.5";
+  :history = "History global attribute.\nTextual attributes like history often have embedded newlines like this.\nSuch newlines should serve as linebreaks on the screen to enhance legibility like this.\nFriendly CDL converters print a single NC_CHAR attribute as a comma-separated list of strings where each embedded delimiter marks a linebreak. This makes poetry embedded in CDL much nicer to read:\n\nA POET by Hafiz\n\nA poet is someone\nWho can pour light into a cup,\nThen raise it to no [...]
+  :lorem_ipsum = "The Lorem Ipsum attribute demonstrates the legibility of text without embedded linebreaks:\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lady Gaga amat indueris vestimento laetus. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Exce [...]
+  :julian_day = 200000.04;
+  :RCS_Header = "$Header$";
+
+	int date_int(date_dmn);
+	date_int:long_name = "Date (as array of ints: YYYY,MM,DD,HH,MM)";
+
+	float dgn(dgn);
+	dgn:long_name = "degenerate coordinate (dgn means degenerate, i.e., of size 1)";
+
+	float dgn_var(dgn);
+	dgn_var:long_name = "degenerate variable (dgn means degenerate, i.e., of size 1)";
+
+	float lat(lat);
+	lat:long_name = "Latitude (typically midpoints)";
+	lat:units = "degrees_north";
+	lat:bounds = "lat_bnd";
+
+	float lat_bnd(lat,vrt_nbr);
+	lat_bnd:purpose = "Cell boundaries for lat coordinate";
+
+	float lat_grd(lat_grd);
+	lat_grd:long_name = "Latitude grid (typically interfaces)";
+	lat_grd:units = "degrees_north";
+
+	float lat_cpy(lat);
+	float lev_cpy(lev);
+	float lat_var(lat);
+	float lat_wgt(lat);
+	float lon_T42(lon_T42);
+	float lat_T42(lat_T42);
+
+	float lat_1D_rct(lat_times_lon);
+	lat_1D_rct:long_name = "Latitude for 2D rectangular grid stored as 1D arrays";
+	lat_1D_rct:units = "degrees_north";
+
+	float lon_1D_rct(lat_times_lon);
+	lon_1D_rct:long_name = "Longitude for 2D rectangular grid stored as 1D arrays";
+	lon_1D_rct:units = "degrees_east";
+
+	float lat_1D_rrg(lat_times_lon);
+	lat_1D_rrg:long_name = "Latitude for 2D irregular grid stored as 1D arrays";
+	lat_1D_rrg:units = "degrees_north";
+
+	float lon_1D_rrg(lat_times_lon);
+	lon_1D_rrg:long_name = "Longitude for 2D irregular grid stored as 1D arrays";
+	lon_1D_rrg:units = "degrees_east";
+
+	int lat_times_lon(lat_times_lon);
+	lat_times_lon:long_name = "Element index (i.e., C-based storage order) for 2D coordinate grids stored as 1D arrays";
+
+	float lat_2D_rct(lat,lon);
+	lat_2D_rct:long_name = "Latitude for 2D rectangular grid stored as 2D array";
+	lat_2D_rct:units = "degrees_north";
+
+	float lon_2D_rct(lat,lon);
+	lon_2D_rct:long_name = "Longitude for 2D rectangular grid stored as 2D array";
+	lon_2D_rct:units = "degrees_east";
+
+	float lat_2D_rrg(lat,lon);
+	lat_2D_rrg:long_name = "Latitude for 2D irregular grid stored as 2D array";
+	lat_2D_rrg:units = "degrees_north";
+
+	float lon_2D_rrg(lat,lon);
+	lon_2D_rrg:long_name = "Longitude for 2D irregular grid stored as 2D array";
+	lon_2D_rrg:units = "degrees_east";
+
+	int lat_times_lon_nbr;
+	lat_times_lon_nbr:long_name = "Number of elements in 2D coordinate grids. Rectangular and irregular test grids have this many total elements. The coordinates and elements are stored as 1D or 2D arrays for grid types 1D and 2D respectively.";
+
+	float lev(lev);
+	lev:purpose = "Monotonically increasing coordinate pressure";
+	lev:long_name = "hybrid level at midpoints (1000*(A+B))";
+	lev:units = "hPa";
+	lev:positive = "down";
+	lev:A_var = "hyam";
+	lev:B_var = "hybm";
+	lev:P0_var = "P0";
+	lev:PS_var = "PS";
+	lev:bounds = "lev_bnd";
+        lev:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate";
+        lev:formula_terms = "a: hyam b: hybm p0: P0 ps: PS";
+        lev:formula_readable = "prs_mdp[time,lat,lon,lev]=P0*hyam+PS*hybm";
+
+	float ilev(ilev);
+	ilev:purpose = "Monotonically increasing coordinate pressure";
+	ilev:long_name = "hybrid level at interfaces (1000*(A+B))";
+	ilev:units = "hPa";
+	ilev:positive = "down";
+	ilev:A_var = "hyai";
+	ilev:B_var = "hybi";
+	ilev:P0_var = "P0";
+	ilev:PS_var = "PS";
+        ilev:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate";
+        ilev:formula_terms = "a: hyai b: hybi p0: P0 ps: PS";
+        ilev:formula_readable = "prs_ntf[time,lat,lon,ilev]=P0*hyai+PS*hybi";
+
+	float lev_bnd(lev,vrt_nbr);
+	lev_bnd:purpose = "Cell boundaries for lev coordinate";
+
+ 	float rlev(rlev);
+	rlev:purpose = "Monotonically decreasing coordinate pressure";
+
+	float lon(lon);
+	lon:long_name = "Longitude (typically midpoints)";
+	lon:units = "degrees_east";
+
+	double Lon(Lon);
+	Lon:long_name = "Longitude";
+	Lon:units = "degrees";
+	Lon:purpose = "Longitude coordinate originally stored as -180 to 180";
+	Lon:notes = "Longitude = [-180.0,180.0) is not CF-compliant, yet is common";
+
+	double LatLon(Lat,Lon);
+	LatLon:long_name = "2D variable originally stored on -180 to 180 longitude grid";
+	LatLon:units = "fraction";
+	LatLon:purpose = "Demonstrate remapping of [-180,180) to [0,360) longitude-grid data";
+
+	double Lat(Lat);
+	Lat:long_name = "Latitude";
+	Lat:units = "degrees_north";
+	Lat:purpose = "Latitude paired with Longitude coordinate originally stored as -180 to 180.";
+
+	double lond(lon);
+	lond:long_name = "Longitude (typically midpoints), double precision";
+	lond:units = "degrees_east";
+
+	float lonf(lon);
+	lonf:long_name = "Longitude (typically midpoints), single precision";
+	lonf:units = "degrees_east";
+
+	float lon_grd(lon_grd);
+	lon_grd:long_name = "Longitude grid (typically interfaces)";
+	lon_grd:units = "degrees_east";
+
+	double time(time);
+	time:long_name = "time";
+	time:units = "days since 1964-03-12 12:09:00 -9:00";
+	time:calendar = "gregorian";
+	time:bounds = "time_bnds";
+	time:climatology = "climatology_bounds";
+
+	float time_bnds(time,vrt_nbr);
+	time_bnds:purpose = "Cell boundaries for time coordinate";
+
+	float climatology_bounds(time,vrt_nbr);
+	climatology_bounds:purpose = "Variable containing CF-compliant climatology bounds for time dimension";
+
+	double lon_cal(lon_cal);
+	lon_cal:long_name = "lon_cal";
+	lon_cal:units = "days since 1964-2-28";
+	lon_cal:calendar = "365_day";
+
+	double lat_cal(lat_cal);
+	lat_cal:long_name = "lat_cal";
+	lat_cal:units = "days since 1964-2-28";
+	lat_cal:calendar = "360_day";
+
+	double tm_std;
+        tm_std:units = "days since 2013-01-01";
+
+	double tm_grg;
+        tm_grg:units = "days since 2013-01-01";
+        tm_grg:calendar = "gregorian"; // Same as "standard"
+
+	double tm_jln;
+        tm_jln:units = "days since 2013-01-01";
+        tm_jln:calendar = "julian";
+
+	double tm_360;
+        tm_360:units = "days since 2013-01-01";
+        tm_360:calendar = "360_day";
+
+	double tm_365;
+        tm_365:units = "days since 2013-01-01";
+        tm_365:calendar = "365_day"; // Same as "noleap"
+
+	double tm_366;
+        tm_366:units = "days since 2013-01-01";
+        tm_366:calendar = "366_day"; // Same as "all_leap"
+
+	float lsmlev(lsmlev);
+	lsmlev:purpose = "Homebrew level coordinate for LSM";
+	lsmlev:long_name = "Soil depth";
+	lsmlev:units = "meter";
+	float wvl(wvl);
+	wvl:long_name = "Wavelength";
+	wvl:units = "meter";
+
+	int od(time);
+
+	float area(lat);
+	area:long_name = "area";
+	area:units = "meter2";
+
+	float area2(lat);
+	area2:long_name = "area version 2";
+	area2:units = "meter2";
+
+	float area_asm(lat);
+	area_asm:long_name = "area asymmetric";
+	area_asm:units = "meter2";
+
+	float hyam(lev);
+	hyam:long_name = "hybrid A coefficient at layer midpoints";
+
+	float hybm(lev);
+	hybm:long_name = "hybrid B coefficient at layer midpoints";
+
+	float hyai(ilev);
+	hyai:long_name = "hybrid A coefficient at layer interfaces";
+
+	float hybi(ilev);
+	hybi:long_name = "hybrid B coefficient at layer interfaces";
+
+	float P0;
+	P0:long_name = "reference pressure";
+	P0:units = "pascal";
+
+	float cnv_CF_crd(gds_crd);
+	cnv_CF_crd:long_name = "test CF coordinates conventions";
+	cnv_CF_crd:coordinates = "lat_gds lon_gds ";
+	cnv_CF_crd:reason = "Test whether coordinates attribute strings that end with a space break after nco_var_lst_crd_ass_add() call to nco_lst_prs_2d()";
+
+	float cnv_CF_ncl(time);
+	cnv_CF_ncl:long_name = "test CF ancillary_variables convention";
+        cnv_CF_ncl:standard_name = "specific_humidity";
+        cnv_CF_ncl:ancillary_variables = "cnv_CF_ncl_var_1 cnv_CF_ncl_var_2";
+        cnv_CF_ncl:purpose = "Main variable that has ancillary variables named cnv_CF_ncl_var_1 and cnv_CF_ncl_var_2";
+
+	float cnv_CF_ncl_var_1(time);
+	cnv_CF_ncl_var_1:long_name = "test CF ancillary_variables convention";
+        cnv_CF_ncl_var_1:standard_name = "specific_humidity standard_error";
+        cnv_CF_ncl_var_1:purpose = "Ancillary variable for cnv_CF_ncl. Other ancillary variable is cnv_CF_ncl_var_2.";
+
+	float cnv_CF_ncl_var_2(time);
+	cnv_CF_ncl_var_2:long_name = "test CF ancillary_variables convention";
+        cnv_CF_ncl_var_2:standard_name = "specific_humidity detection_limit";
+        cnv_CF_ncl_var_2:purpose = "Ancillary variable for cnv_CF_ncl. Other ancillary variable is cnv_CF_ncl_var_1.";
+
+	float PS(time,lat,lon);
+	PS:long_name = "surface pressure";
+	PS:units = "pascal";
+
+	char fl_dmn(fl_dmn);
+	fl_dmn:long_name = "Character coordinate";
+	fl_dmn:units = "[chr]";
+
+	double lat_gds(gds_crd);
+	lat_gds:long_name = "Latitude";
+	lat_gds:standard_name = "latitude";
+	lat_gds:units="degree";
+	lat_gds:purpose = "1-D latitude coordinate referred to by geodesic grid variables";
+
+	double lon_gds(gds_crd);
+	lon_gds:long_name = "Longitude";
+	lon_gds:standard_name = "longitude";
+	lon_gds:units="degree";
+	lon_gds:purpose = "1-D longitude coordinate referred to by geodesic grid variables";
+
+	float gds_crd(gds_crd);
+	gds_crd:long_name = "Geodesic coordinate";
+	gds_crd:units = "degree";
+	gds_crd:purpose = "enumerated coordinate like those that might define points in a geodesic grid";
+	gds_crd:coordinates = "lat_gds lon_gds";
+
+	float gds_var(gds_crd);
+	gds_var:long_name = "Geodesic variable";
+	gds_var:units = "meter";
+	gds_var:purpose = "Test auxiliary coordinates like those that define geodesic grids";
+	gds_var:coordinates = "lat_gds lon_gds";
+
+	float gds_3dvar(time,gds_crd);
+	gds_3dvar:long_name = "Geodesic variable";
+	gds_3dvar:units = "meter";
+	gds_3dvar:coordinates = "lat_gds lon_gds";
+	gds_3dvar:purpose = "Test auxiliary coordinates like those that define geodesic grids";
+
+	float gds_var_ncd(gds_ncd);
+	gds_var_ncd:long_name = "Geodesic variable on non-coordinate grid";
+	gds_var_ncd:units = "meter";
+	gds_var_ncd:purpose = "Test auxiliary coordinates like those that define geodesic grids but where underlying dimension is a non-coordinate dimension";
+	gds_var_ncd:coordinates = "lat_gds_ncd lon_gds_ncd";
+
+	double lat_gds_ncd(gds_ncd);
+	lat_gds_ncd:long_name = "Latitude";
+	lat_gds_ncd:standard_name = "latitude";
+	lat_gds_ncd:units="degree";
+	lat_gds_ncd:purpose = "1-D latitude coordinate referred to by \"non-coordinate\" (ncd) geodesic grid variables";
+
+	double lon_gds_ncd(gds_ncd);
+	lon_gds_ncd:long_name = "Longitude";
+	lon_gds_ncd:standard_name = "longitude";
+	lon_gds_ncd:units="degree";
+	lon_gds_ncd:purpose = "1-D longitude coordinate referred to by \"non-coordinate\" (ncd) geodesic grid variables";
+
+	int nbdate;
+	nbdate:long_name = "base date as 6- or 8-digit integer (YYMMDD or YYYYMMDD)";
+
+	int date(time);
+	date:long_name = "current date as 6- or 8-digit integer (YYMMDD or YYYYMMDD)";
+
+	float lon_wgt(lon);
+	lon_wgt:long_name = "Gaussian weights";
+	lon_wgt:purpose = "Gaussian weights which sum to two for n = 4. These weights are all have floor of 0.0 so should cause SIGFPE when applied to integer types in weighted average.";
+
+	double ppc_dbl(time);
+        ppc_dbl:long_name = "Precision-Preserving Compression, double precision";
+        ppc_dbl:purpose = "test --ppc switches";
+        ppc_dbl:original_values="0.0,0.1,0.12,0.123,0.1234,0.12345,0.123456,0.1234567,0.12345678,0.123456789";
+
+	float ppc_flt(time);
+        ppc_flt:long_name = "Precision-Preserving Compression, single precision";
+        ppc_flt:purpose = "test --ppc switches";
+        ppc_flt:original_values="0.0,0.1,0.12,0.123,0.1234,0.12345,0.123456,0.1234567,0.12345678,0.123456789";
+
+	double ppc_big(time);
+        ppc_big:long_name = "Precision-Preserving Compression, big numbers";
+        ppc_big:purpose = "test --ppc switches";
+        ppc_big:original_values="123456789e-10,123456789e-9,123456789e-8,123456789e-7,123456789e-6,123456789e-5,123456789e-4,123456789e-3,123456789e-2,123456789e-1";
+
+	float ppc_bgr(time);
+        ppc_bgr:long_name = "Precision-Preserving Compression, bigger numbers";
+        ppc_bgr:purpose = "test --ppc switches";
+        ppc_bgr:original_values="1234567890e20,1234567890e19,1234567890e18,1234567890e17,1234567890e16,1234567890e15,1234567890e14,1234567890e13,1234567890e12,1234567890e11";
+
+	float ppc_bgr_scl;
+        ppc_bgr_scl:long_name = "Precision-Preserving Compression, bigger numbers, scalar";
+        ppc_bgr_scl:purpose = "test --ppc switches";
+        ppc_bgr_scl:original_value="1234567890e11";
+
+	double ppc_hgh(time);
+        ppc_hgh:long_name = "Precision-Preserving Compression, high precision";
+        ppc_hgh:purpose = "test --ppc switches";
+
+	double ppc_hgr(time);
+        ppc_hgr:long_name = "Precision-Preserving Compression, higher precision";
+        ppc_hgr:purpose = "test --ppc switches";
+
+	char md5_a;
+	md5_a:long_name = "the letter a";
+	md5_a:purpose = "String with known MD5 digest";
+	md5_a:MD5_known_checksum = "0cc175b9c0f1b6a831c399e269772661";
+
+	char md5_abc(lev);
+	md5_abc:long_name = "the letters abc";
+	md5_abc:purpose = "String with known MD5 digest";
+	md5_abc:MD5_known_checksum = "900150983cd24fb0d6963f7d28e17f72";
+
+	float msk_prt_mss_prt(lon);
+	msk_prt_mss_prt:long_name = "partial mask, partial missing value example";
+	msk_prt_mss_prt:_FillValue = 1.0e36f;
+
+	float mss_val(lon);
+	mss_val:long_name = "partial missing value example";
+	mss_val:_FillValue = 1.0e36f;
+
+	float mss_val_scl;
+	mss_val_scl:long_name = "scalar missing value";
+	mss_val_scl:_FillValue = 1.0e36f;
+
+	float mss_val_fst(lon);
+	mss_val_fst:long_name = "offset partial missing value example";
+	mss_val_fst:_FillValue = -999.0f;
+
+	float fll_val(lon);
+	fll_val:long_name = "_FillValue example";
+	fll_val:_FillValue = -999.0f;
+
+	float fll_val_mss_val(lon);
+	fll_val_mss_val:long_name = "_FillValue example";
+	fll_val_mss_val:_FillValue = -999.0f;
+	fll_val_mss_val:missing_value = -999.0f;
+
+	float nan_arr(lat);
+	nan_arr:long_name = "Intended for array representation of IEEE NaN";
+	nan_arr:note = "20120308 Apparently netCDF ncgen chokes on variable names of nan and NaN";
+	nan_arr:note2 = "20120330 netCDF ncgen on AIX/bluefire chokes on variable/attribute values of nan";
+	nan_arr:note3 = "20120625 netCDF ncgen on netCDF 4.1.1 on apparently chokes on variable/attribute values of nan";
+	nan_arr:note4 = "If your NCO build fails because your version of netCDF does not support nan, then cd to the directory that contains the file nco/data/in.cdl and run the command in note5 first and then try to build again";
+	nan_arr:note5 = "sed -e 's/nan;/1.0f;/' in.cdl > foo.cdl;ncgen -b -o in.nc foo.cdl";
+	nan_arr:note6 = "It is too troublesome to distribute in.cdl with references to NaNs because users always build with old netCDF versions that do not support it. So just comment out nan's for now.";
+	//	nan_arr:_FillValue = nan;
+		nan_arr:_FillValue = 1.0f;
+
+	float nan_scl;
+	nan_scl:long_name = "Intended for scalar representation of IEEE NaN";
+	nan_scl:note = "20120308 Apparently netCDF ncgen chokes on variable names of nan and NaN";
+	nan_scl:note2 = "20120330 netCDF ncgen on AIX/bluefire chokes on variable/attribute values of nan";
+	nan_scl:note3 = "20120625 netCDF ncgen on netCDF 4.1.1 on apparently chokes on variable/attribute values of nan";
+	nan_scl:note6 = "It is too troublesome to distribute in.cdl with references to NaNs because users always build with old netCDF versions that do not support it. So just comment out nan's for now.";
+	// nan_scl:_FillValue = nan;
+        nan_scl:_FillValue = 1.0f;
+
+	float nm_spc;
+	nm_spc:long_name = "Variable name with space (invalid)";
+
+	float nm_pnd;
+	nm_pnd:long_name = "Variable name with pound symbol (invalid)";
+
+	float no_mss_val(lon);
+	no_mss_val:long_name = "no missing value";
+
+	float val_one_mss(lat);
+	val_one_mss:long_name = "one regular value, one missing value";
+	val_one_mss:_FillValue = 1.0e36f;
+
+	short rec_var_pck_scale_factor_only(time);
+	rec_var_pck_scale_factor_only:long_name = "Array packed with scale factor only";
+	rec_var_pck_scale_factor_only:note = "Original packed value was 1s..10s with scale_factor = 10.0d no add_offset. Unpacked value should be 10.0 = 10.0d*1s + 0.0d through 100 = 10.0d*1s + 0.0d. Average value should be 55.";
+	rec_var_pck_scale_factor_only:scale_factor = 10.0d;
+
+	short pck;
+	pck:long_name = "Scalar variable, double, packed as short";
+	pck:note = "Original packed value was 1s with scale_factor = 2.0d and add_offset = 1.0d. Unpacked value (netCDF convention) should be 3.0 = 2.0d*1s + 1.0d. Unpacked value (HDF convention) should be 0.0 = 2.0d*(1s-1.0d). NCO algorithms would pack this variable as scale_factor = 0.0d and add_offset = 3.0d.";
+	pck:scale_factor = 2.0d;
+	pck:add_offset = 1.0d;
+
+	short pck_3;
+	pck_3:long_name = "Scalar variable, double, packed as short";
+	pck_3:note = "Original packed value was 1s with scale_factor = 2.0d and add_offset = 1.0d. Unpacked value (netCDF convention) should be 3.0 = 2.0d*1s + 1.0d. Unpacked value (HDF convention) should be 0.0 = 2.0d*(1s-1.0d). NCO algorithms would pack this variable as scale_factor = 0.0d and add_offset = 3.0d.";
+	pck_3:scale_factor = 2.0d;
+	pck_3:add_offset = 1.0d;
+
+	short pck_5;
+	pck_5:long_name = "Scalar variable, double, packed as short";
+	pck_5:note = "Original packed value was 2s with scale_factor = 2.0d and add_offset = 1.0d. Unpacked value (netCDF convention) should be 5.0 = 2.0d*2s + 1.0d. Unpacked value (HDF convention) should be 2.0 = 2.0d*(2s-1.0d). NCO algorithms would pack this variable as scale_factor = 0.0d and add_offset = 5.0d.";
+	pck_5:scale_factor = 2.0d;
+	pck_5:add_offset = 1.0d;
+
+	short pck_7;
+	pck_7:long_name = "Scalar variable, double, packed as short";
+	pck_7:note = "Original packed value was 1s with scale_factor = 4.0d and add_offset = 3.0d. Unpacked value (netCDF convention) should be 7.0 = 4.0d*1s + 3.0d. Unpacked value (HDF convention) should be -8.0 = 4.0d*(1s-3.0d). NCO algorithms would pack this variable as scale_factor = 0.0d and add_offset = 7.0d.";
+	pck_7:scale_factor = 4.0d;
+	pck_7:add_offset = 3.0d;
+
+	short pck_arr(lon);
+	pck_arr:long_name = "Array variable, double, packed as short";
+	pck_arr:note = "Packed value is -32767s, 0s, 1s, 32767s, unpacked is same in double";
+	pck_arr:scale_factor = 1.0d;
+	pck_arr:add_offset = 0.0d;
+
+	double upk;
+	upk:long_name = "Unpacked scalar variable";
+	upk:note = "Unpacked value is 3.0d0, upk=unpack(pck)= 2.0d0*1s + 1.0d0 = 3.0d0. Packing this variable should create an NC_SHORT scalar = 0s with packing attribute add_offset=3.0d and either no scale_factor (ncap) or scale_factor = 0.0d (ncpdq).";
+
+	double upk_arr(lon);
+	upk_arr:long_name = "Unpacked array";
+	upk_arr:note = "Unpacked value is -32767.d, 0.d, 1.d, 32767.d, packed is same in short. Packing algorithm should yield an NC_SHORT array = [] with packing attributes scale_factor=1.0d, add_offset=0.0d";
+
+	float val_eminusten;
+	val_eminusten:long_name = "Floating point number with exponent ending in zero to test sng_trm_trl_zro()";
+        val_eminusten:att_eminusten = 1.1e-10f;
+
+	int val_one_int;
+	val_one_int:long_name = "scalar integer equal to 1";
+	val_one_int:_FillValue = -99l;
+
+	int val_one_one_int(lat);
+	val_one_one_int:long_name = "1, 1";
+	val_one_one_int:_FillValue = -99l;
+
+	short val_max_max_sht(lat);
+	val_max_max_sht:long_name = "17000, 17000";
+	val_max_max_sht:_FillValue = -99s;
+
+	int val_one_mss_int(lat);
+	val_one_mss_int:long_name = "1, mss_val";
+	val_one_mss_int:_FillValue = -99l;
+
+	float val_half;
+	val_half:long_name = "Scalar with value 0.5";
+	val_half:_FillValue = 1.0e36f;
+
+	float val_half_half(lat);
+	val_half_half:long_name = "0.5,0.5";
+	val_half_half:_FillValue = 1.0e36f;
+
+	float wgt_one(lat);
+	wgt_one:long_name = "all values are one";
+
+	float mss_val_all(lon);
+	mss_val_all:long_name = "all missing values example";
+	mss_val_all:_FillValue = 1.0e36f;
+
+	float scalar_var;
+	scalar_var:long_name = "scalar variable";
+	scalar_var:units = "fraction";
+
+	float float_var;
+	float_var:long_name = "float";
+
+	double double_var;
+	double_var:long_name = "double";
+
+	double double_var2;
+	double_var2:long_name = "double";
+	double_var2:_FillValue = 1.0e36;
+
+	double pi;
+	pi:long_name = "Pi";
+	pi:units = "fraction";
+
+	int int_var;
+	int_var:long_name = "int";
+
+	long long_var;
+	long_var:long_name = "long";
+	long_var:purpose = "Variable of CDL type=long, which is deprecated for int. Included to test back-compatibility";
+
+	short short_var;
+	short_var:long_name = "short";
+
+	char char_var;
+	char_var:long_name = "char";
+
+	char char_var_space;
+	char_var_space:long_name = "Character variable with whitespace on ends";
+
+	char char_var_nul;
+	char_var_nul:long_name = "Character variable containing one NUL";
+
+	// 20131015: This confuses the XML parser. Omit it for now.
+	// char char_var_multinul(lev);
+	// char_var_multinul:long_name = "Character variable containing multiple NULs";
+
+	char fl_nm(char_dmn_lng80);
+	fl_nm:long_name = "Variable contains a file name";
+
+	char fl_nm_arr(fl_dmn,char_dmn_lng80);
+	fl_nm_arr:long_name = "Variable that contains a short array of file names";
+	fl_nm_arr:units = "[sng]";
+
+	char fl_nm_rec(time,char_dmn_lng80);
+	fl_nm_rec:long_name = "A record variable of file names";
+	fl_nm_rec:units = "[sng]";
+
+	char date_rec(time,char_dmn_lng26);
+	date_rec:long_name = "A record variable of date strings";
+	date_rec:units = "[sng]";
+
+	char non_nul_trm_char_one_dmn(char_dmn_lng04);
+	non_nul_trm_char_one_dmn:long_name = "Variable contains a one-dimensional array of characters that is not NUL-terminated";
+	non_nul_trm_char_one_dmn:units = "[chr]";
+
+	char non_nul_trm_char_two_dmn(fl_dmn,char_dmn_lng04);
+	non_nul_trm_char_two_dmn:long_name = "Variable contains a two-dimensional array of characters that are not NUL-terminated";
+	non_nul_trm_char_two_dmn:units = "[chr]";
+
+	byte byt_arr(lat,lon);
+	byt_arr:long_name = "byte array";
+
+	byte byt_2D(lat,lon);
+
+	byte byt_3D(lat,lev,lon);
+
+	byte byt_3D_rec(time,lat,lon);
+
+	byte byte_var;
+	byte_var:long_name = "byte";
+
+	byte byte_var_neg;
+	byte_var_neg:long_name = "negative byte";
+
+	float zero;
+	zero:long_name = "zero";
+
+	float ppc_zro_flt(time);
+	zero:long_name = "array of single precision floating point zeros";
+
+	double ppc_zro_dbl(time);
+	zero:long_name = "array of double precision floating point zeros";
+
+	int ppc_zro_int(time);
+	zero:long_name = "array of integer zeros";
+
+	float one;
+	one:long_name = "one";
+
+	float two;
+	two:long_name = "two";
+
+	double e_dbl;
+	e_dbl:long_name = "e, natural logarithm base";
+
+	float e_flt;
+	e_flt:long_name = "e, natural logarithm base";
+
+	float three;
+	three:long_name = "three";
+
+	float four;
+	four:long_name = "four";
+
+	float negative_one;
+	negative_one:long_name = "negative one";
+
+	float lev_var(lev);
+	lev_var:long_name = "lev_var";
+
+	float lev_wgt(lev);
+	lev_wgt:long_name = "lev_wgt";
+
+	float g;
+	g:long_name = "g";
+
+	float dps_dry;
+	dps_dry:long_name = "Dry Deposition";
+
+	float dps_wet;
+	dps_wet:long_name = "Wet Deposition";
+
+	float dps_ttl;
+	dps_ttl:long_name = "Total Deposition";
+
+	float z(lev);
+	z:long_name = "Height";
+	z:units = "meter";
+	z:purpose = "Height stored with a monotonically increasing coordinate";
+
+	float rz(rlev);
+	rz:long_name = "Height";
+	rz:units = "meter";
+	rz:purpose = "Height stored with a monotonically decreasing coordinate";
+
+	float one_dmn_var(bnd);
+
+	int one_dmn_int_val_one(lat);
+	int one_dmn_int_val_two(lat);
+
+	float att_var(time);
+	att_var:byte_att = '\000','\001','\002','\177','\200','\201','\376','\377';
+	att_var:char_att = "Sentence one.\nSentence two.\n";
+	att_var:short_att = 37s;
+	att_var:int_att = 73;
+	att_var:long_att = 73l;
+        att_var:float_att = 73.0f,72.0f,71.0f,70.010f,69.0010f,68.010000f,67.01000100f;
+	att_var:double_att = 73.0,72.0,71.0,70.010,69.0010,68.010000,67.01000100;
+
+	int bnd_var(lev,bnd);
+	bnd_var:byte_att = '\0';
+	bnd_var:char_att = "Sentence one.\nSentence two.\n";
+	bnd_var:short_att = 37s;
+	bnd_var:int_att = 73;
+	bnd_var:long_att = 73l;
+	bnd_var:float_att = 73.f;
+	bnd_var:double_att = 73.d;
+
+	float three_dmn_var(lat,lev,lon);
+	three_dmn_var:long_name = "three dimensional variable with CCM coordinate convention C=[lat,lev,lon], Fortran=(lon,lev,lat)";
+	three_dmn_var:units = "fraction";
+
+	float three_dmn_var_crd(lev,lat,lon);
+	three_dmn_var_crd:long_name = "three dimensional variable with COORDS coordinate convention C=[lev,lat,lon], Fortran=(lon,lat,lev)";
+	three_dmn_var_crd:units = "fraction";
+
+	float prs_sfc(time,lat,lon);
+	prs_sfc:long_name = "Surface pressure";
+	prs_sfc:units = "pascal";
+
+	float H2O;
+	float H2OH2O;
+	float H2SO4;
+	float H2O_lqd;
+	float H2O_ice;
+	float Q;
+	float Q1;
+	float AQ01;
+	float QQ01;
+	float QA01;
+	float Q01Q;
+	float Q01;
+	float Q02;
+	float Q03;
+	float Q04;
+	float Q05;
+	float Q06;
+	float Q07;
+	float Q08;
+	float Q09;
+	float Q10;
+	float Q11;
+	float Q12;
+	float Q13;
+	float Q14;
+	float Q15;
+	float Q16;
+	float Q17;
+	float Q18;
+	float Q19;
+	float Q20;
+	float Q21;
+	float Q22;
+	float Q23;
+	float Q24;
+	float Q25;
+	float Q26;
+	float Q27;
+	float Q28;
+	float Q29;
+	float Q30;
+	float Q31;
+	float Q32;
+	float Q33;
+	float Q34;
+	float Q35;
+	float Q36;
+	float Q37;
+	float Q38;
+	float Q39;
+	float Q40;
+	float Q41;
+	float Q42;
+	float Q43;
+	float Q44;
+	float Q45;
+	float Q46;
+	float Q47;
+	float Q48;
+	float Q49;
+	float Q50;
+	float Q51;
+	float Q52;
+	float Q53;
+	float Q54;
+	float Q55;
+	float Q56;
+	float Q57;
+	float Q58;
+	float Q59;
+	float Q60;
+	float Q61;
+	float Q62;
+	float Q63;
+	float Q64;
+	float Q65;
+	float Q66;
+	float Q67;
+	float Q68;
+	float Q69;
+	float Q70;
+	float Q71;
+	float Q72;
+	float Q73;
+	float Q74;
+	float Q75;
+	float Q76;
+	float Q77;
+	float Q78;
+	float Q79;
+	float Q80;
+	float Q81;
+	float Q82;
+	float Q83;
+	float Q84;
+	float Q85;
+	float Q86;
+	float Q87;
+	float Q88;
+	float Q89;
+	float Q90;
+	float Q91;
+	float Q92;
+	float Q93;
+	float Q94;
+	float Q95;
+	float Q96;
+	float Q97;
+	float Q98;
+	float Q99;
+	float Q100;
+
+	float two_dmn_var(lat,lev);
+	two_dmn_var:long_name = "two dimensional variable";
+	two_dmn_var:units = "fraction";
+
+	float var_msk(lat,lon);
+	var_msk:long_name = "Float field for testing masks and wheres";
+	var_msk:units = "fraction";
+
+	float mask(lat,lon);
+	mask:long_name = "Purpose is to mask a variable like ORO";
+	mask:units = "fraction";
+
+	float ORO(lat,lon);
+	ORO:long_name = "Orography, an enumerated yet continuous type: ocean=0.0, land=1.0, sea ice=2.0";
+	ORO:units = "fraction";
+
+	float weight(lat);
+	weight:long_name = "Gaussian weight";
+	weight:units = "fraction";
+
+	float gw(lat);
+	gw:long_name = "gw variable like gw";
+	gw:units = "fraction";
+
+	float gw_T42(lat_T42);
+	gw_T42:long_name = "gw variable like gw_T42";
+	gw_T42:units = "fraction";
+
+	float rec_var_flt(time);
+	rec_var_flt:long_name = "record variable, float";
+
+	double rec_var_dbl(time);
+	rec_var_dbl:long_name = "record variable, double";
+
+	int one_dmn_rec_var(time);
+	one_dmn_rec_var:long_name = "one dimensional record variable";
+	one_dmn_rec_var:coordinates = "time";
+	one_dmn_rec_var:units = "kelvin";
+
+	double one_dmn_rec_wgt(time);
+	one_dmn_rec_wgt:long_name = "one dimensional record variable weight";
+
+	int one_dmn_rec_var_mdn(time);
+	one_dmn_rec_var_mdn:long_name = "one dimensional record variable to test median";
+
+	int one_dmn_rec_var_mdn__FillValue(time);
+	one_dmn_rec_var_mdn__FillValue:long_name = "one dimensional record variable to test median with _FillValue";
+	one_dmn_rec_var_mdn__FillValue:_FillValue = -999;
+
+	int one_dmn_rec_var_unsorted(time);
+	one_dmn_rec_var_unsorted:long_name = "one dimensional record variable, unsorted";
+
+	float one_dmn_rec_var_flt(time);
+	one_dmn_rec_var_flt:long_name = "one dimensional record variable, single precision";
+
+	float one_dmn_rec_var_flt_mss(time);
+	one_dmn_rec_var_flt_mss:long_name = "one dimensional record variable, single precision, missing values";
+	one_dmn_rec_var_flt_mss:_FillValue = 1.0e36f;
+
+	float one_dmn_rec_var_flt_scl(time);
+	one_dmn_rec_var_flt_scl:long_name = "one dimensional record variable, single precision, scaled";
+	one_dmn_rec_var_flt_scl:scale_factor = 1.0f;
+
+	float one_dmn_rec_var_flt_mss_scl(time);
+	one_dmn_rec_var_flt_mss_scl:long_name = "one dimensional record variable, single precision, missing values, scaled";
+	one_dmn_rec_var_flt_mss_scl:scale_factor = 1.0f;
+	one_dmn_rec_var_flt_mss_scl:_FillValue = 1.0e36f;
+
+	float one_dmn_rec_var_dbl(time);
+	one_dmn_rec_var_dbl:long_name = "one dimensional record variable, double precision";
+	one_dmn_rec_var_dbl:units = "second";
+
+	float one_dmn_rec_var_missing_value(time);
+	one_dmn_rec_var_missing_value:long_name = "One dimensional record variable with missing data indicated by missing_value attribute only. No _FillValue attribute exists.";
+	one_dmn_rec_var_missing_value:missing_value = 1.0e36f;
+
+	float one_dmn_rec_var_mss_val(time);
+	one_dmn_rec_var_mss_val:long_name = "One dimensional record variable with all missing data.";
+	one_dmn_rec_var_mss_val:_FillValue = 1.0e36f;
+
+	float one_dmn_rec_var__FillValue(time);
+	one_dmn_rec_var__FillValue:long_name = "One dimensional record variable with missing data indicated by _FillValue attribute only. No missing_value attribute exists.";
+	one_dmn_rec_var__FillValue:_FillValue = 1.0e36f;
+
+	float one_dmn_rec_var_unsorted__FillValue(time);
+	one_dmn_rec_var_unsorted__FillValue:long_name = "Unsorted, one dimensional record variable with missing data indicated by _FillValue attribute only. No missing_value attribute exists.";
+	one_dmn_rec_var_unsorted__FillValue:_FillValue = 1.0e36f;
+
+	float one_dmn_rec_var_mss_val_arr(time);
+	one_dmn_rec_var_mss_val_arr:long_name = "One dimensional record variable with missing data indicated by a _FillValue attribute that is an array. This can be tested with ncrcat. 20120905: ncgen chokes on _FillValue arrays and produces this error: _FillValue: must be a single (possibly compound) value. Deprecate the array for normal use since it prevents ncgen from completing. Uncommment following line when testing for compatibility with software changes.";
+//	one_dmn_rec_var_mss_val_arr:_FillValue = 1.0f,2.0f,3.0f;
+	one_dmn_rec_var_mss_val_arr:_FillValue = 1.0f;
+
+	int RDM(time);
+
+	float tpt(time);
+	tpt:long_name = "Temperature";
+	tpt:units = "kelvin";
+	tpt:hieght = "Leave hieght mispelled for NCO User's guide example";
+
+	double tpt_dbl(time);
+	tpt_dbl:long_name = "Temperature stored as double precision floating point";
+	tpt_dbl:units = "kelvin";
+
+	float tpt_flt(time);
+	tpt_flt:long_name = "Temperature stored as single precision floating point";
+	tpt_flt:units = "kelvin";
+
+	double rec_var_dbl_mss_val_dbl_upk(time);
+	rec_var_dbl_mss_val_dbl_upk:long_name = "record variable, double, with double missing values";
+	rec_var_dbl_mss_val_dbl_upk:purpose = "This variable is used to generate the packed variable rec_var_dbl_mss_val_dbl_pck, so its _FillValue should not be out of range, i.e., it should be representable by a short. However, the _FillValue should itself be the same type as the unpacked variable, NC_DOUBLE in this case.";
+	rec_var_dbl_mss_val_dbl_upk:_FillValue = -999.;
+	rec_var_dbl_mss_val_dbl_upk:missing_value = -999.;
+
+	double rec_var_dbl_mss_val_sht_upk(time);
+	rec_var_dbl_mss_val_sht_upk:long_name = "record variable, double, with double missing values";
+	rec_var_dbl_mss_val_sht_upk:purpose = "This variable is used to generate the packed variable rec_var_dbl_mss_val_sht_pck, so its _FillValue should not be out of range, i.e., it should be representable by a short. However, the _FillValue should itself be the same type as the unpacked variable, NC_DOUBLE in this case.";
+//	Using intended _FillValue type breaks ncgen (with "_FillValue type mismatch")in netCDF 4.1.1 so comment-out for simplicity
+//	rec_var_dbl_mss_val_sht_upk:_FillValue = -999s;
+	rec_var_dbl_mss_val_sht_upk:_FillValue = -999.0;
+	rec_var_dbl_mss_val_sht_upk:missing_value = -999s;
+
+	short rec_var_dbl_mss_val_dbl_pck(time);
+	rec_var_dbl_mss_val_dbl_pck:long_name = "record variable, double, packed as short, with double missing values";
+	rec_var_dbl_mss_val_dbl_pck:purpose = "Packed version of rec_var_dbl_mss_val_dbl_upk";
+//	Using intended _FillValue type breaks ncgen (with "_FillValue type mismatch")in netCDF 4.1.1 so comment-out for simplicity
+//	rec_var_dbl_mss_val_dbl_pck:_FillValue = -999.;
+	rec_var_dbl_mss_val_dbl_pck:_FillValue = -999s;
+	rec_var_dbl_mss_val_dbl_pck:missing_value = -999.;
+        rec_var_dbl_mss_val_dbl_pck:scale_factor = -9.15541313801785e-05;
+        rec_var_dbl_mss_val_dbl_pck:add_offset = 5.;
+
+	short rec_var_dbl_mss_val_sht_pck(time);
+	rec_var_dbl_mss_val_sht_pck:long_name = "record variable, double, packed as short, with short missing values";
+	rec_var_dbl_mss_val_sht_pck:purpose = "Packed version of rec_var_dbl_mss_val_sht_upk";
+	rec_var_dbl_mss_val_sht_pck:_FillValue = -999s;
+	rec_var_dbl_mss_val_sht_pck:missing_value = -999s;
+        rec_var_dbl_mss_val_sht_pck:scale_factor = -9.15541313801785e-05;
+        rec_var_dbl_mss_val_sht_pck:add_offset = 5.;
+
+	short scl_dbl_pck;
+	scl_dbl_pck:long_name = "scalar variable, double, packed";
+	scl_dbl_pck:purpose = "Packed version of number with ncdiff subtraction bug";
+        scl_dbl_pck:scale_factor = -9.15541313801785e-05;
+        scl_dbl_pck:add_offset = 5.;
+
+	float rec_var_flt_mss_val_flt(time);
+	rec_var_flt_mss_val_flt:long_name = "record variable, float, with float missing values";
+	rec_var_flt_mss_val_flt:_FillValue = 1.0e36f;
+
+	float rec_var_flt_mss_val_flt_all(time);
+	rec_var_flt_mss_val_flt_all:long_name = "record variable, float, with float missing values in every position";
+	rec_var_flt_mss_val_flt_all:_FillValue = 1.0e36f;
+
+	float rec_var_flt_mss_val_flt_all_but_one(time);
+	rec_var_flt_mss_val_flt_all_but_one:long_name = "record variable, float, with float missing values in every position but one";
+	rec_var_flt_mss_val_flt_all_but_one:_FillValue = 1.0e36f;
+
+	float rec_var_flt_mss_val_flt_all_but_two(time);
+	rec_var_flt_mss_val_flt_all_but_two:long_name = "record variable, float, with float missing values in every position but two";
+	rec_var_flt_mss_val_flt_all_but_two:_FillValue = 1.0e36f;
+
+	short rec_var_flt_pck(time);
+	rec_var_flt_pck:long_name = "record variable, float, packed into short";
+        rec_var_flt_pck:purpose = "Demonstrate that rounding of means of packed data are handled correctly";
+        rec_var_flt_pck:scale_factor = 0.1f;
+        rec_var_flt_pck:add_offset = 100.0f;
+
+	short rec_var_dbl_pck(time);
+	rec_var_dbl_pck:long_name = "record variable, double, packed into short";
+        rec_var_dbl_pck:purpose = "Demonstrate that rounding of means of packed data are handled correctly";
+        rec_var_dbl_pck:scale_factor = 0.1;
+	rec_var_dbl_pck:add_offset = 100.0;
+
+	short non_rec_var_flt_pck(lon);
+	non_rec_var_flt_pck:long_name = "regular variable, float, packed into short";
+        non_rec_var_flt_pck:purpose = "Demonstrate that non-rec dim packed vars are handled correctly";
+        non_rec_var_flt_pck:scale_factor = 0.1f;
+        non_rec_var_flt_pck:add_offset = 100.0f;
+
+	float rec_var_flt_mss_val_dbl(time);
+	rec_var_flt_mss_val_dbl:long_name = "record variable, float, with double missing values";
+	rec_var_flt_mss_val_dbl:_FillValue = 1.0e36f;
+	rec_var_flt_mss_val_dbl:missing_value = 1.0e36f;
+	rec_var_flt_mss_val_dbl:note = "The correct average of this variable is 5.0. The correct sum of this variable is 35.";
+
+	float rec_var_flt_mss_val_int(time);
+	rec_var_flt_mss_val_int:long_name = "record variable, float, with integer missing values";
+//	Using intended _FillValue type breaks ncgen (with "_FillValue type mismatch")in netCDF 4.1.1 so comment-out for simplicity
+//	rec_var_flt_mss_val_int:_FillValue = -999;
+	rec_var_flt_mss_val_int:_FillValue = -999.0f;
+	rec_var_flt_mss_val_int:missing_value = -999;
+
+	int rec_var_int_mss_val_int(time);
+	rec_var_int_mss_val_int:long_name = "record variable, integer, with integer missing values";
+	rec_var_int_mss_val_int:_FillValue = -999;
+
+	int rec_var_int_mss_val_flt(time);
+	rec_var_int_mss_val_flt:long_name = "record variable, integer, with float missing values";
+//	Using intended _FillValue type breaks ncgen (with "_FillValue type mismatch")in netCDF 4.1.1 so comment-out for simplicity
+//	rec_var_int_mss_val_flt:_FillValue = -999.0f;
+	rec_var_int_mss_val_flt:_FillValue = -999;
+	rec_var_int_mss_val_flt:missing_value = -999.0f;
+
+	int rec_var_int_mss_val_dbl(time);
+	rec_var_int_mss_val_dbl:long_name = "record variable, integer, with double missing values";
+//	Using intended _FillValue type breaks ncgen (with "_FillValue type mismatch")in netCDF 4.1.1 so comment-out for simplicity
+//	rec_var_int_mss_val_dbl:_FillValue = -999.0;
+	rec_var_int_mss_val_dbl:_FillValue = -999;
+	rec_var_int_mss_val_dbl:missing_value = -999.0;
+
+	int rec_var_dbl_mss_val_dbl_pck_lng(time);
+	rec_var_dbl_mss_val_dbl_pck_lng:long_name = "record variable, double packed as long, with double missing values";
+	rec_var_dbl_mss_val_dbl_pck_lng:purpose = "although not usual, packing doubles into longs (rather than shorts) offers considerable space savings";
+//	Using intended _FillValue type breaks ncgen (with "_FillValue type mismatch")in netCDF 4.1.1 so comment-out for simplicity
+//	rec_var_dbl_mss_val_dbl_pck_lng:_FillValue = -999.0;
+	rec_var_dbl_mss_val_dbl_pck_lng:_FillValue = -999;
+	rec_var_dbl_mss_val_dbl_pck_lng:missing_value = -999.0;
+        rec_var_dbl_mss_val_dbl_pck_lng:scale_factor = -9.15541313801785e-05;
+        rec_var_dbl_mss_val_dbl_pck_lng:add_offset = 5.;
+
+	short rec_var_dbl_mss_val_sht_pck_sht(time);
+	rec_var_dbl_mss_val_sht_pck_sht:long_name = "record variable, double packed as short, with short missing values";
+	rec_var_dbl_mss_val_sht_pck_sht:_FillValue = -999s;
+        rec_var_dbl_mss_val_sht_pck_sht:scale_factor = -9.15541313801785e-05;
+	rec_var_dbl_mss_val_sht_pck_sht:add_offset = 5.;
+
+	char one_dmn_rec_var_sng(time);
+	one_dmn_rec_var_sng:long_name = "one dimensional record variable of string";
+        one_dmn_rec_var_sng:NB = "20131222: HDF4 ncgen fails on this variable: /usr/bin/hncgen -b -o ~/in.hdf ~/nco/data/in.cdl produces error message that \"string won't fit in this variable\"";
+
+	float time_lon(time,lon);
+	time_lon:long_name = "Record variable of longitude coordinate";
+
+	char two_dmn_rec_var_sng(time,lev);
+	two_dmn_rec_var_sng:long_name = "two dimensional record variable of string";
+
+	float two_dmn_rec_var(time,lev);
+	two_dmn_rec_var:long_name = "two dimensional record variable";
+	two_dmn_rec_var:units = "watt meter-2";
+
+	float three_dmn_rec_var(time,lat,lon);
+	three_dmn_rec_var:long_name = "three dimensional record variable";
+	three_dmn_rec_var:units = "watt meter-2";
+	three_dmn_rec_var:coordinates = "time lat lon";
+
+	double three_dmn_var_dbl(time,lat,lon);
+	three_dmn_var_dbl:long_name = "three dimensional record variable of type double";
+	three_dmn_var_dbl:units = "watt meter-2";
+	three_dmn_var_dbl:_FillValue = -99.;
+
+	int three_dmn_var_int(time,lat,lon);
+	three_dmn_var_int:long_name = "three dimensional record variable of type int";
+	three_dmn_var_int:units = "watt meter-2";
+	three_dmn_var_int:_FillValue = -99;
+
+	short three_dmn_var_sht(time,lat,lon);
+	three_dmn_var_sht:long_name = "three dimensional record variable";
+	three_dmn_var_sht:units = "watt meter-2";
+	three_dmn_var_sht:_FillValue = -99s;
+
+	int th(time,lat,lon);
+	th:long_name = "three dimensional record variable";
+	th:units = "watt meter-2";
+	th:_FillValue = -99;
+
+	float td(time,dgn);
+	td:long_name = "two dimensional record variable stored in td (time,dgn) order (dgn means degenerate, i.e., of size 1)";
+
+	float tx(time,lon);
+	tx:long_name = "two dimensional record variable stored in tx (time,lon) order";
+
+	float ty(time,lat);
+	ty:long_name = "two dimensional record variable stored in ty (time,lat) order";
+
+	float tz(time,lev);
+	tz:long_name = "two dimensional record variable stored in tz (time,lev) order";
+
+	float txyz(time,lon,lat,lev);
+	txyz:long_name = "four dimensional record variable stored in txyz (time,lon,lat,lev) order";
+
+	float four_dmn_rec_var(time,lat,lev,lon);
+	four_dmn_rec_var:long_name = "four dimensional record variable";
+	four_dmn_rec_var:units = "watt meter-2";
+	four_dmn_rec_var:coordinates = "time lat lev lon";
+
+//	double three_double_dmn(time,lon,lon);
+
+	double time_udunits(time_udunits);
+	time_udunits:units = "hours since 1900-01-01 00:00:0.0";
+	time_udunits:delta_t = "0000-00-00 06:00:0.0";
+	time_udunits:purpose = "The dates specified in this variable are ~1999-12-08";
+
+	float u(time);
+	u:long_name = "Zonal wind speed";
+	u:units = "meter second-1";
+
+	float v(time);
+	v:long_name = "Meridional wind speed";
+	v:units = "meter second-1";
+
+	float var_1D_rct(lat_times_lon);
+	var_1D_rct:long_name = "Variable for 2D rectangular grid stored as 1D arrays";
+
+	float var_1D_rrg(lat_times_lon);
+	var_1D_rrg:long_name = "Variable for 2D irregular grid stored as 1D arrays";
+
+	float var_2D_rct(lat,lon);
+	var_2D_rct:long_name = "Variable for 2D rectangular grid stored as 2D array";
+
+	float var_2D_rrg(lat,lon);
+	var_2D_rrg:long_name = "Variable for 2D irregular grid stored as 2D array";
+
+	float var_nm-dash;
+	var_nm-dash:long_name = "Variable and attribute names include dash characters";
+	var_nm-dash:att_nm-dash = 1.0e36f;
+
+	float vld_rng(time);
+	vld_rng:long_name = "Temperature";
+	vld_rng:purpose = "Array containing _FillValue at some locations, out-of-range values at other locations, and valid data in the remainder";
+	vld_rng:_FillValue = -999.0f;
+	vld_rng:valid_min = 180.f;
+	vld_rng:valid_max = 360.f;
+
+//	float var_nm.dot;
+//	var_nm.dot:long_name = "Variable and attribute names include dot characters";
+//	20070102: Periods in attribute names choke OPeNDAP from FC7 RPM TODO nco911
+//	20091105: Periods in attribute names choke ncgen   from RHEL5   TODO nco911
+//	var_nm.dot:att_nm.dot = 1.0e36f;
+
+	float wnd_spd(time,lat,lon);
+	wnd_spd:long_name = "wind speed";
+	wnd_spd:units = "meter second-1";
+	wnd_spd:_FillValue = -999.0f;
+
+data:
+//	netCDF4-specific atomic types:
+//	None in this file
+//	netCDF3 atomic types:
+	att_var=10.0,10.1,10.20,10.3000,10.40101,10.500001,10.60000001,10.7000001,10.80,10.9900;
+	area=10.,10.;
+	area2=20.,5.;
+	area_asm=1.,2.;
+	bnd_var=1,2,3,4,5,6;
+	byt_arr=0,1,2,3,4,5,6,7;
+	byt_2D=0,1,2,3,4,5,6,7;
+	byt_3D=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23;
+	byt_3D_rec= 	 1, 2, 3, 4, 5, 6, 7, 8,
+			 9,10,11,12,13,14,15,16,
+			17,18,19,20,21,22,23,24,
+			25,26,27,28,29,30,31,32,
+  			33,34,35,36,37,38,39,40,
+			41,42,43,44,45,46,47,48,
+			49,50,51,52,53,54,55,56,
+			57,58,59,60,61,62,63,64,
+			65,66,67,68,69,70,71,72,
+			73,74,75,76,77,78,79,80;
+	byte_var='z';
+	byte_var_neg=-122;
+	char_var="z";
+	// 20131015: This confuses the XML parser
+	//	char_var_multinul="\b\n\0";
+	// char_var_multinul='0','\n','\0';
+	char_var_nul='\0';
+	char_var_space=" ";
+	cnv_CF_crd=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8;
+	cnv_CF_ncl=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
+	cnv_CF_ncl_var_1=11.,22.,23.,24.,25.,26.,27.,28.,29.,30.;
+	cnv_CF_ncl_var_2=21.,32.,33.,34.,35.,36.,37.,38.,39.,40.;
+	date_int=1964,3,12,12,9;
+	dgn=73;
+	dgn_var=73;
+	double_var=10.;
+	double_var2=10.;
+	dps_dry=73;
+	dps_wet=73;
+	dps_ttl=73;
+	e_dbl=2.71828182846;
+	e_flt=2.71828182846;
+// 	20100809: Single quotes around NC_CHAR coordinates required as of 4.1.2-beta1-snapshot2010080820
+// 	20100809: Double quotes cause "String constant too long" error in ncgen
+	fl_dmn='a','b','3';
+	fl_nm="/home/zender/nco/data/in.cdl";
+	float_var=10.;
+	four=4.;
+	g=9.8;
+	gw=10.,10.;
+	gw_T42=-87.863799,-85.096527,-82.312913,-79.525607,-76.736900,-73.947515,-71.157752,-68.367756,-65.577607,-62.787352,-59.997020,-57.206632,-54.416200,-51.625734,-48.835241,-46.044727,-43.254195,-40.463648,-37.673090,-34.882521,-32.091944,-29.301360,-26.510769,-23.720174,-20.929574,-18.138971,-15.348365,-12.557756,-9.767146,-6.976534,-4.185921,-1.395307,1.395307,4.185921,6.976534,9.767146,12.557756,15.348365,18.138971,20.929574,23.720174,26.510769,29.301360,32.091944,34.882521,37.673090, [...]
+	hyam=0.0036,0.0019894,0.0;
+	hyai=0.002255,0.0438226,0.0,0.0;
+	hybm=0.0,0.52,0.992;
+	hybi=0.0,0.457453,0.985,1.0;
+	P0=100000;
+	gds_crd=0,1,2,3,4,5,6,7;
+	gds_var=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8;
+	gds_var_ncd=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8;
+	gds_3dvar=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8,
+	          274.1,274.2,274.3,274.4,274.5,274.6,274.7,274.8,
+	          275.1,275.2,275.3,275.4,275.5,274.5,275.7,275.8,
+	          276.1,276.2,276.3,276.4,276.5,276.5,276.7,276.8,
+	          277.1,277.2,277.3,277.4,277.5,277.5,277.7,277.8,
+	          278.1,278.2,278.3,278.4,278.5,278.6,278.7,278.8,
+	          279.1,279.2,279.3,279.4,279.5,279.9,279.7,279.8,
+	          280.1,280.2,280.3,280.4,280.5,280.9,280.7,280.8,
+	          281.1,281.2,281.3,281.4,281.5,281.9,281.7,281.8,
+	          282.1,282.2,282.3,282.4,282.5,282.9,282.7,282.8;
+	lat_gds=-90, -30,  -30,    0,   0, 30,  30,  90;
+	lon_gds=  0,   0,  180,    0, 180,  0, 180,   0;
+	lat_gds_ncd=-90, -30,  -30,    0,   0, 30,  30,  90;
+	lon_gds_ncd=  0,   0,  180,    0, 180,  0, 180,   0;
+	lat=-90,90;
+	lat_bnd=-90,0,0,90;
+        lat_cal=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
+	lon_cal=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
+	lat_times_lon=0,1,2,3,4,5,6,7;
+	lat_times_lon_nbr=8;
+	lat_1D_rct=-90, -90,  -90,  -90,  90, 90,  90,  90;
+	lon_1D_rct=  0,  90,  180,  270,   0, 90, 180, 270;
+	lat_1D_rrg=-90, -30,  -30,    0,   0, 30,  30,  90;
+	lon_1D_rrg=  0,   0,  180,    0, 180,  0, 180,   0;
+	lat_2D_rct=-90, -90,  -90,  -90,  90, 90,  90,  90;
+	lon_2D_rct=  0,  90,  180,  270,   0, 90, 180, 270;
+	lat_2D_rrg=-90, -30,  -30,    0,   0, 30,  30,  90;
+	lon_2D_rrg=  0,   0,  180,    0, 180,  0, 180,   0;
+	lat_grd=-90,0,90;
+	lat_cpy=-90,90;
+	lat_var=1.,2.;
+	lat_wgt=1.,2.;
+//	lat_T42=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63;
+	lat_T42=-88.240089,-85.092445,-82.311981,-79.525253,-76.736732,-73.947418,-71.157700,-68.367722,-65.577576,-62.787331,-59.997005,-57.206619,-54.416191,-51.625729,-48.835236,-46.044724,-43.254192,-40.463646,-37.673088,-34.882519,-32.091942,-29.301357,-26.510769,-23.720173,-20.929573,-18.138969,-15.348364,-12.557755,-9.767145,-6.976533,-4.185921,-1.395307,1.395307,4.185921,6.976533,9.767145,12.557755,15.348364,18.138969,20.929573,23.720173,26.510769,29.301357,32.091942,34.882519,37.673088 [...]
+	lsmlev=0.05,0.1,0.2,0.5,1.0,3.0;
+	lev=100,500,1000;
+	ilev=50,200,750,1005;
+	lev_bnd=0,300,300,750,750,1013.25;
+	lev_cpy=100,500,1000;
+	lev_var=100.,500.,1000.;
+	lev_wgt=10,2,1;
+	lon=0,90,180,270;
+	Lon=-180,-90,0,90;
+	Lat=-45,45;
+	LatLon=0,1,2,3,4,5,6,7;
+	lond=0,90,180,270;
+	lonf=0,90,180,270;
+	lon_grd=-45,45,135,225,315;
+	lon_wgt=0.347855,0.652145,0.652145,0.347855;
+//	lon_T42=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127;
+	lon_T42=0.000000,2.812500,5.625000,8.437500,11.250000,14.062500,16.875000,19.687500,22.500000,25.312500,28.125000,30.937500,33.750000,36.562500,39.375000,42.187500,45.000000,47.812500,50.625000,53.437500,56.250000,59.062500,61.875000,64.687500,67.500000,70.312500,73.125000,75.937500,78.750000,81.562500,84.375000,87.187500,90.000000,92.812500,95.625000,98.437500,101.250000,104.062500,106.875000,109.687500,112.500000,115.312500,118.125000,120.937500,123.750000,126.562500,129.375000,132.18 [...]
+	ppc_dbl=0.0,0.1,0.12,0.123,0.1234,0.12345,0.123456,0.1234567,0.12345678,0.123456789;
+	ppc_flt=0.0,0.1,0.12,0.123,0.1234,0.12345,0.123456,0.1234567,0.12345678,0.123456789;
+	ppc_big=123456789e-10,123456789e-9,123456789e-8,123456789e-7,123456789e-6,123456789e-5,123456789e-4,123456789e-3,123456789e-2,123456789e-1;
+	ppc_bgr=1234567890e20,1234567890e19,1234567890e18,1234567890e17,1234567890e16,1234567890e15,1234567890e14,1234567890e13,1234567890e12,1234567890e11;
+	ppc_bgr_scl=1234567890e11;
+	ppc_hgh=0.00000000000000000000,0.10000000000000000000,0.12000000000000000000,0.123000000000000000000,0.1234000000000000000,0.12345000000000000000,0.123456000000000000000000,0.12345670000000000000000000,0.123456780000000000000,0.123456789000000000000;
+	ppc_hgr=0.123456789000000000000,0.1234567890100000000000,0.1234567890120000000000,0.12345678901230000000000,0.123456789012340000000,0.12345678901234500000,0.12345678901234560000,0.12345678901234567000,0.12345678901234567800,0.12345678901234567890;
+	ppc_zro_flt=0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0;
+	ppc_zro_dbl=0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0;
+	ppc_zro_int=0,0,0,0,0,0,0,0,0,0;
+	var_msk=0.,1.,0.,0.,1.,1.,0.,2.;
+	ORO=0.,1.,0.,0.,1.,1.,0.,2.;
+	mask=0.,1.,0.,0.,1.,1.,0.,2.;
+//	mask=0.,0.,0.,0.,0.,0.,0.,0.;
+//	mask=1.,1.,1.,1.,1.,1.,1.,1.;
+	fll_val=73,-999,73,-999;
+	fll_val_mss_val=73,-999,73,-999;
+	md5_a="a";
+	md5_abc="abc";
+	msk_prt_mss_prt=0.5,1.0e36,1.5,1.0e36;
+	mss_val=73,1.0e36,73,1.0e36;
+	mss_val_all=1.0e36,1.0e36,1.0e36,1.0e36;
+	mss_val_fst=-999,73,-999,73;
+	mss_val_scl=1.0e36;
+	//	nan_arr=0,nan;
+	nan_arr=0,73;
+//	nan_scl=nan;
+	nan_scl=1;
+	negative_one=-1.;
+	nm_pnd=1;
+	nm_spc=1;
+	no_mss_val=73,1.0e36,73,1.0e36;
+	non_nul_trm_char_one_dmn='a','b';
+	non_nul_trm_char_two_dmn="abcd","efgh","ijkm";
+	one=1.;
+	one_dmn_rec_var=1,2,3,4,5,6,7,8,9,10;
+	one_dmn_rec_wgt=2,1,0,0,0,0,0,0,0,0;
+	one_dmn_rec_var_unsorted=10,4,6,2,8,1,9,7,3,5;
+	one_dmn_rec_var_flt=1,2,3,4,5,6,7,8,9,10;
+	one_dmn_rec_var_flt_mss=_,2,3,4,5,6,7,8,9,_;
+	one_dmn_rec_var_flt_scl=1,2,3,4,5,6,7,8,9,10;
+// First use of underscore to indicate _FillValue in in.cdl is here in one_dmn_rec_var_flt_mss_scl on 20140916
+	one_dmn_rec_var_flt_mss_scl=_,2,3,4,5,6,7,8,9,_;
+	one_dmn_rec_var_dbl=1,2,3,4,5,6,7,8,9,10;
+	one_dmn_rec_var_missing_value=1,2,3,4,5,6,7,8,9,1.0e36;
+	one_dmn_rec_var_mss_val=1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36;
+	one_dmn_rec_var_mss_val_arr=1,2,3,4,5,6,7,8,9,10;
+	one_dmn_rec_var__FillValue=1,2,3,4,5,6,7,8,9,1.0e36;
+	one_dmn_rec_var_unsorted__FillValue=1.0e36,4,6,2,8,1,9,7,3,5;
+	one_dmn_rec_var_mdn=1,1,2,2,2,2,10,10,10,10;
+	one_dmn_rec_var_mdn__FillValue=1,-999,2,2,-999,-999,10,10,10,-999;
+	RDM=1,9,36,84,126,126,84,36,9,1;
+	one_dmn_rec_var_sng="Hello Worl";
+	one_dmn_var=1.,10.;
+	one_dmn_int_val_one=1,1;
+	one_dmn_int_val_two=2,2;
+	pck=1;
+	pck_3=1;
+	pck_5=2;
+	pck_7=1;
+	rec_var_pck_scale_factor_only=1,2,3,4,5,6,7,8,9,10;
+	pck_arr=-32767,0,1,32767;
+	pi=3.1415926535897932384626433832795029;
+	upk=3.;
+	upk_arr=-32767.,0.,1.,32767.;
+	H2O=1.0;
+	H2OH2O=1.0;
+	H2SO4=1.0;
+	H2O_lqd=1.0;
+	H2O_ice=1.0;
+	Q=1.0e36;
+	Q1=1.0e36;
+	AQ01=1.0e36;
+	QQ01=1.0e36;
+	QA01=1.0e36;
+	Q01Q=1.0e36;
+	Q01=1;
+	Q02=2;
+	Q03=3;
+	Q04=4;
+	Q05=5;
+	Q06=6;
+	Q07=7;
+	Q08=8;
+	Q09=9;
+	Q10=10;
+	Q11=11;
+	Q12=12;
+	Q13=13;
+	Q14=14;
+	Q15=15;
+	Q16=16;
+	Q17=17;
+	Q18=18;
+	Q19=19;
+	Q20=20;
+	Q21=21;
+	Q22=22;
+	Q23=23;
+	Q24=24;
+	Q25=25;
+	Q26=26;
+	Q27=27;
+	Q28=28;
+	Q29=29;
+	Q30=30;
+	Q31=31;
+	Q32=32;
+	Q33=33;
+	Q34=34;
+	Q35=35;
+	Q36=36;
+	Q37=37;
+	Q38=38;
+	Q39=39;
+	Q40=40;
+	Q41=41;
+	Q42=42;
+	Q43=43;
+	Q44=44;
+	Q45=45;
+	Q46=46;
+	Q47=47;
+	Q48=48;
+	Q49=49;
+	Q50=50;
+	Q51=51;
+	Q52=52;
+	Q53=53;
+	Q54=54;
+	Q55=55;
+	Q56=56;
+	Q57=57;
+	Q58=58;
+	Q59=59;
+	Q60=60;
+	Q61=61;
+	Q62=62;
+	Q63=63;
+	Q64=64;
+	Q65=65;
+	Q66=66;
+	Q67=67;
+	Q68=68;
+	Q69=69;
+	Q70=70;
+	Q71=71;
+	Q72=72;
+	Q73=73;
+	Q74=74;
+	Q75=75;
+	Q76=76;
+	Q77=77;
+	Q78=78;
+	Q79=79;
+	Q80=80;
+	Q81=81;
+	Q82=82;
+	Q83=83;
+	Q84=84;
+	Q85=85;
+	Q86=86;
+	Q87=87;
+	Q88=88;
+	Q89=89;
+	Q90=90;
+	Q91=91;
+	Q92=92;
+	Q93=93;
+	Q94=94;
+	Q95=95;
+	Q96=96;
+	Q97=97;
+	Q98=98;
+	Q99=99;
+	Q100=100;
+	non_rec_var_flt_pck=1,2,3,4;
+	rec_var_dbl=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
+	rec_var_dbl_mss_val_dbl_pck=-999,32767,21845,10922,0,-10922,-21845,-32767,-999,-999;
+	rec_var_dbl_mss_val_dbl_pck_lng=-999,32767,21845,10922,0,-10922,-21845,-32767,-999,-999;
+	rec_var_dbl_mss_val_sht_pck_sht=-999,32767,21845,10922,0,-10922,-21845,-32767,-999,-999;
+	rec_var_dbl_mss_val_dbl_upk=-999.,2.,3.,4.,5.,6.,7.,8.,-999.,-999.;
+	rec_var_dbl_mss_val_sht_pck=-999,32767,21845,10922,0,-10922,-21845,-32767,-999,-999;
+	rec_var_dbl_mss_val_sht_upk=-999.,2.,3.,4.,5.,6.,7.,8.,-999.,-999.;
+	rec_var_dbl_pck=1,2,3,4,5,6,7,8,9,10;
+	rec_var_flt=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
+	rec_var_flt_mss_val_dbl=1.0e36,2.,3.,4.,5.,6.,7.,8.,1.0e36,1.0e36;
+	rec_var_flt_mss_val_flt=1.0e36,2.,3.,4.,5.,6.,7.,8.,1.0e36,1.0e36;
+	rec_var_flt_mss_val_flt_all=1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36;
+	rec_var_flt_mss_val_flt_all_but_one=1.0e36,1.0e36,1.0e36,1.0e36,5.0,1.0e36,1.0e36,1.0e36,1.0e36,1.0e36;
+	rec_var_flt_mss_val_flt_all_but_two=1.0e36,1.0e36,1.0e36,1.0e36,5.0,1.0e36,1.0e36,1.0e36,1.0e36,10.0;
+	rec_var_flt_mss_val_int=-999.,2.,3.,4.,5.,6.,7.,8.,-999.,-999.;
+	rec_var_flt_pck=1,2,3,4,5,6,7,8,9,10;
+	rec_var_int_mss_val_dbl=-999,2,3,4,5,6,7,8,-999,-999;
+	rec_var_int_mss_val_flt=-999,2,3,4,5,6,7,8,-999,-999;
+	rec_var_int_mss_val_int=-999,2,3,4,5,6,7,8,-999,-999;
+	rlev=1000,500,100;
+	rz=0,5000,17000;
+	scl_dbl_pck=10922;
+	scalar_var=10.;
+	short_var=10;
+	three=3.;
+	three_dmn_var=0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.;
+	three_dmn_var_crd=0.,1.,2.,3.,12.,13.,14.,15.,4.,5.,6.,7.,16.,17.,18.,19.,8.,9.,10.,11.,20.,21.,22.,23.;
+	time=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
+	time_bnds=0.5,1.5,1.5,2.5,2.5,3.5,3.5,4.5,4.5,5.5,5.5,6.5,6.5,7.5,7.5,8.5,8.5,9.5,9.5,10.5;
+	climatology_bounds=0.5,1.5,1.5,2.5,2.5,3.5,3.5,4.5,4.5,5.5,5.5,6.5,6.5,7.5,7.5,8.5,8.5,9.5,9.5,10.5;
+	tm_std=59;
+	tm_grg=59;
+	tm_jln=59;
+	tm_360=59;
+	tm_365=59;
+	tm_366=59;
+	od=20,22,24,26,28,30,32,34,36,38;
+	tpt=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8,273.9,274.0;
+	tpt_flt=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8,273.9,274.0;
+	tpt_dbl=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8,273.9,274.0;
+	two=2.;
+	two_dmn_var=1.5,5.5,9.5,13.5,17.5,21.5;
+	u=1.,0.,1.,0.,1.,0.,1.,0.,1.,0.;
+	v=0.,1.,0.,1.,0.,1.,0.,1.,0.,1.;
+	val_half=0.5;
+	val_half_half=0.5,0.5;
+	val_max_max_sht=17000,17000;
+	val_eminusten=1.1e-10;
+	val_one_int=1;
+	val_one_mss=1.,1.0e36;
+	val_one_mss_int=1,-99;
+	val_one_one_int=1,1;
+	var_nm-dash=1.0;
+//	var_nm.dot=1.0;
+	var_1D_rct=0.,1.,0.,0.,1.,1.,0.,2.;
+	var_1D_rrg=0.,1.,0.,0.,1.,1.,0.,2.;
+	var_2D_rct=0.,1.,0.,0.,1.,1.,0.,2.;
+	var_2D_rrg=0.,1.,0.,0.,1.,1.,0.,2.;
+	weight=10.,10.;
+	wgt_one=1.,1.;
+	wvl=0.5e-6,1.0e-6;
+	z=17000,5000,0;
+	zero=0.;
+// 	        date=640312,640313,640314,640315,640316,640317,640318,640319,640320,640321;
+	date=640224,640225,640226,640227,640228,640301,640302,640303,640304,640305;
+ 	int_var=10;
+ 	long_var=10;
+ 	nbdate=640224;
+	fl_nm_arr="/data/zender/dstccm04/dstccm04_8589_01.nc",
+		"/data/zender/dstccm04/dstccm04_8589_02.nc",
+		"/data/zender/dstccm04/dstccm04_8589_03.nc";
+	fl_nm_rec="/data/zender/dstccm04/dstccm04_8589_01.nc",
+	  "/data/zender/dstccm04/dstccm04_8589_02.nc",
+	  "/data/zender/dstccm04/dstccm04_8589_03.nc",
+	  "/data/zender/dstccm04/dstccm04_8589_04.nc",
+	  "/data/zender/dstccm04/dstccm04_8589_05.nc",
+	  "/data/zender/dstccm04/dstccm04_8589_06.nc",
+	  "/data/zender/dstccm04/dstccm04_8589_07.nc",
+	  "/data/zender/dstccm04/dstccm04_8589_08.nc",
+	  "/data/zender/dstccm04/dstccm04_8589_09.nc",
+	  "/data/zender/dstccm04/dstccm04_8589_10.nc";
+	date_rec="2010-11-01T00:00:00.000000",
+	  "2010-11-01T01:00:00.000000",
+	  "2010-11-01T02:00:00.000000",
+	  "2010-11-01T03:00:00.000000",
+	  "2010-11-01T04:00:00.000000",
+	  "2010-11-01T05:00:00.000000",
+	  "2010-11-01T06:00:00.000000",
+	  "2010-11-01T07:00:00.000000",
+	  "2010-11-01T08:00:00.000000",
+	  "2010-11-01T09:00:00.000000";
+	time_lon=0.0,90.0,180.0,270.0,
+			0.0,90.0,180.0,270.0,
+			0.0,90.0,180.0,270.0,
+			0.0,90.0,180.0,270.0,
+			0.0,90.0,180.0,270.0,
+			0.0,90.0,180.0,270.0,
+			0.0,90.0,180.0,270.0,
+			0.0,90.0,180.0,270.0,
+			0.0,90.0,180.0,270.0,
+			0.0,90.0,180.0,270.0;
+	two_dmn_rec_var_sng="abc",
+				"bcd",
+				"cde",
+				"def",
+				"efg",
+				"fgh",
+				"ghi",
+				"hij",
+				"jkl",
+				"klm";
+	two_dmn_rec_var=1.,2.0,3.,
+			1.,2.1,3.,
+			1.,2.2,3.,
+			1.,2.3,3.,
+			1.,2.4,3.,
+			1.,2.5,3.,
+			1.,2.6,3.,
+			1.,2.7,3.,
+			1.,2.8,3.,
+			1.,2.9,3.;
+	three_dmn_rec_var= 	 1, 2, 3, 4, 5, 6, 7, 8,
+				 9,10,11,12,13,14,15,16,
+				17,18,19,20,21,22,23,24,
+				25,26,27,28,29,30,31,32,
+  				33,34,35,36,37,38,39,40,
+				41,42,43,44,45,46,47,48,
+				49,50,51,52,53,54,55,56,
+				57,58,59,60,61,62,63,64,
+				65,66,67,68,69,70,71,72,
+				73,74,75,76,77,78,79,80;
+	prs_sfc=		 1, 2, 3, 4, 5, 6, 7, 8,
+				 9,10,11,12,13,14,15,16,
+				17,18,19,20,21,22,23,24,
+				25,26,27,28,29,30,31,32,
+  				33,34,35,36,37,38,39,40,
+				41,42,43,44,45,46,47,48,
+				49,50,51,52,53,54,55,56,
+				57,58,59,60,61,62,63,64,
+				65,66,67,68,69,70,71,72,
+				73,74,75,76,77,78,79,80;
+	PS=			101325,101325,101325,101325,101325,101325,101325,101325,
+				101325,101325,101325,101325,101325,101325,101325,101325,
+				101325,101325,101325,101325,101325,101325,101325,101325,
+				101325,101325,101325,101325,101325,101325,101325,101325,
+  				101325,101325,101325,101325,101325,101325,101325,101325,
+				101325,101325,101325,101325,101325,101325,101325,101325,
+				101325,101325,101325,101325,101325,101325,101325,101325,
+				101325,101325,101325,101325,101325,101325,101325,101325,
+				101325,101325,101325,101325,101325,101325,101325,101325,
+				101325,101325,101325,101325,101325,101325,101325,101325;
+	three_dmn_var_dbl= 	 1, 2, 3, 4, 5, 6, 7, 8,
+				 9,10,11,12,13,14,15,16,
+				17,18,19,20,21,22,23,24,
+				-99,-99,-99,-99,-99,-99,-99,-99,
+				33,34,35,36,37,38,39,40,
+				41,42,43,44,45,46,47,48,
+				49,50,51,52,53,54,55,56,
+				-99,58,59,60,61,62,63,64,
+				65,66,67,68,69,70,71,72,
+				-99,74,75,76,77,78,79,-99;
+	three_dmn_var_int= 	 1, 2, 3, 4, 5, 6, 7, 8,
+				 9,10,11,12,13,14,15,16,
+				-99,-99,-99,-99,-99,-99,-99,-99,
+				25,26,27,28,29,30,31,32,
+				33,34,35,36,37,38,39,40,
+				41,-99,43,44,45,46,47,48,
+				49,50,51,52,53,54,55,56,
+				-99,58,59,60,-99,62,63,64,
+				65,-99,67,68,69,70,71,72,
+				-99,74,75,-99,77,78,79,80;
+	three_dmn_var_sht= 	 1, 2, 3, 4, 5, 6, 7, 8,
+				 -99,10,11,12,13,14,15,16,
+				17,18,19,20,21,22,23,24,
+				25,26,27,28,29,30,31,32,
+				-99,34,35,-99,37,38,39,40,
+				41,42,43,44,-99,46,47,48,
+				49,50,51,52,53,54,55,56,
+				57,58,59,-99,61,62,63,64,
+				65,66,67,68,69,70,71,72,
+				-99,-99,-99,-99,-99,-99,-99,-99;
+	th=			1, 2, 3, 4, 5, 6, 7, 8,
+				9,10,11,12,13,14,15,16,
+			  	17,18,19,20,21,22,23,24,
+			  	-99,-99,-99,-99,-99,-99,-99,-99,
+			  	33,34,35,36,37,38,39,40,
+			  	41,42,43,44,45,46,47,48,
+			  	49,50,51,52,53,54,55,56,
+			  	-99,58,59,60,61,62,63,64,
+			  	65,66,67,68,69,70,71,72,
+			 	-99,74,75,76,77,78,79,-99;
+	four_dmn_rec_var= 	  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
+				 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+				 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+				 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+				 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+				 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+				 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+				 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+				 97, 98, 99,100,101,102,103,104,105,106,107,108,
+				109,110,111,112,113,114,115,116,117,118,119,120,
+				121,122,123,124,125,126,127,128,129,130,131,132,
+				133,134,135,136,137,138,139,140,141,142,143,144,
+				145,146,147,148,149,150,151,152,153,154,155,156,
+				157,158,159,160,161,162,163,164,165,166,167,168,
+				169,170,171,172,173,174,175,176,177,178,179,180,
+				181,182,183,184,185,186,187,188,189,190,191,192,
+				193,194,195,196,197,198,199,200,201,202,203,204,
+				205,206,207,208,209,210,211,212,213,214,215,216,
+				217,218,219,220,221,222,223,224,225,226,227,228,
+				229,230,231,232,233,234,235,236,237,238,239,240;
+	td=		1,2,3,4,5,6,7,8,9,10;
+	tx=		1,2,3,4,5,6,7,8,9,10,
+			11,12,13,14,15,16,17,18,19,20,
+			21,22,23,24,25,26,27,28,29,30,
+			31,32,33,34,35,36,37,38,39,40;
+	ty=		1,2,3,4,5,6,7,8,9,10,
+			11,12,13,14,15,16,17,18,19,20;
+	tz=		1,2,3,4,5,6,7,8,9,10,
+			11,12,13,14,15,16,17,18,19,20,
+			21,22,23,24,25,26,27,28,29,30;
+	txyz=		 	  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
+				 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+				 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+				 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+				 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+				 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+				 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+				 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+				 97, 98, 99,100,101,102,103,104,105,106,107,108,
+				109,110,111,112,113,114,115,116,117,118,119,120,
+				121,122,123,124,125,126,127,128,129,130,131,132,
+				133,134,135,136,137,138,139,140,141,142,143,144,
+				145,146,147,148,149,150,151,152,153,154,155,156,
+				157,158,159,160,161,162,163,164,165,166,167,168,
+				169,170,171,172,173,174,175,176,177,178,179,180,
+				181,182,183,184,185,186,187,188,189,190,191,192,
+				193,194,195,196,197,198,199,200,201,202,203,204,
+				205,206,207,208,209,210,211,212,213,214,215,216,
+				217,218,219,220,221,222,223,224,225,226,227,228,
+				229,230,231,232,233,234,235,236,237,238,239,240;
+
+//	three_double_dmn= 	 1, 2, 3, 4, 5, 6, 7, 8,
+//				 9,10,11,12,13,14,15,16,
+//				17,18,19,20,21,22,23,24,
+//				-99,-99,-99,-99,-99,-99,-99,-99,
+//				33,34,35,36,37,38,39,40,
+//				41,42,43,44,45,46,47,48,
+//				49,50,51,52,53,54,55,56,
+//				-99,58,59,60,61,62,63,64,
+//				65,66,67,68,69,70,71,72,
+//				-99,74,75,76,77,78,79,-99,
+//				1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5,
+//				 9.5,10.5,11.5,12.5,13.5,14.5,15.5,16.5,
+//				17.5,18.5,19.5,20.5,21.5,22.5,23.5,24.5,
+//				-99.5,-99.5,-99.5,-99.5,-99.5,-99.5,-99.5,-99.5,
+//				33.5,34.5,35.5,36.5,37.5,38.5,39.5,40.5,
+//				41.5,42.5,43.5,44.5,45.5,46.5,47.5,48.5,
+//				49.5,50.5,51.5,52.5,53.5,54.5,55.5,56.5,
+//				-99.5,58.5,59.5,60.5,61.5,62.5,63.5,64.5,
+//				65.5,66.5,67.5,68.5,69.5,70.5,71.5,72.5,
+//				-99.5,74.5,75.5,76.5,77.5,78.5,79.5,-99.5;
+
+	time_udunits = 876012, 876018, 876024;
+
+	vld_rng=		273.,-999.,180.,179.,273.,360.,361.,1.0e36,-1.0e36,273.;
+
+	wnd_spd=		-999,0.5,1.5,0.5,1.5,0.5,1.5,0.5,
+				0.5,-999,0.5,0.5,0.5,0.5,0.5,0.5,
+				0.5,1.5,-999,1.5,0.5,1.5,0.5,1.5,
+				0.5,0.5,0.5,-999,0.5,0.5,0.5,0.5,
+  				1.5,1.5,1.5,1.5,-999,1.5,1.5,1.5,
+				0.5,0.5,0.5,0.5,0.5,-999,0.5,0.5,
+				2.5,2.5,2.5,2.5,2.5,2.5,-999,2.5,
+				0.5,0.5,0.5,0.5,0.5,0.5,0.5,-999,
+				0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,
+				0.5,0.5,2.5,0.5,0.5,2.5,0.5,0.5;
+} // end netcdf
diff --git a/ncgen/ncgen.1 b/ncgen/ncgen.1
index 5015d07..e29dbcb 100644
--- a/ncgen/ncgen.1
+++ b/ncgen/ncgen.1
@@ -490,7 +490,7 @@ except that type suffixes must be appended to shorts and floats to
 distinguish them from longs and doubles.
 .LP
 A \fIbyte\fP constant is represented by
- an integer constant with a `b' (or
+an integer constant with a `b' (or
 `B') appended.  In the old netCDF-2 API, byte constants could also be
 represented using single characters or standard C character escape
 sequences such as `a' or `\n'.  This is still supported for backward
@@ -520,8 +520,11 @@ begins with `0', it is interpreted as octal, except that if it begins with
 .LP
 \fIint\fP integer constants are intended for representing 32-bit signed
 quantities.  The form of an \fIint\fP constant is an ordinary integer
-constant, although it is acceptable to append an optional `l' or
-`L' (again, deprecated).
+constant, although it is acceptable to optionally append a single `l' or
+`L' (again, deprecated). Be careful, though, the L suffix is interpreted
+as a 32 bit integer, and never as a 64 bit integer. This can be confusing
+since the C long type can ambigously be either 32 bit or 64 bit.
+.LP
 If an \fIint\fP constant begins with `0', it is interpreted as
 octal, except that if it begins with `0x', it is interpreted as a hexadecimal
 constant (but see opaque constants below).
@@ -578,8 +581,9 @@ For example the following are all acceptable \fIdouble\fP constants:
 .LP
 Unsigned integer constants can be created by appending
 the character 'U' or 'u' between the constant and any trailing
-size specifier.  Thus one could say
-10U, 100us, 100000ul, or 1000000ull, for example.
+size specifier, or immediately at the end of the size specifier.
+Thus one could say
+10U, 100su, 100000ul, or 1000000llu, for example.
 .LP
 Single character constants may be enclosed in single quotes.
 If a sequence of one or more characters is enclosed
diff --git a/ncgen/ncgen.l b/ncgen/ncgen.l
index 31a4dc0..689c1ec 100644
--- a/ncgen/ncgen.l
+++ b/ncgen/ncgen.l
@@ -73,13 +73,17 @@ static unsigned int MAX_UINT = NC_MAX_UINT;
 #define NC_MAX_UINT MAX_UINT
 #endif
 
-#define TAG "BbSsLl"
+#define TAGCHARS "BbSsLlUu"
 
 #define tstdecimal(ch) ((ch) >= '0' && (ch) <= '9')
 
 /*Mnemonics*/
 #define ISIDENT 1
 
+/* Define a fake constant indicating that
+   no tag was specified */
+#define NC_NOTAG (-1)
+
 char errstr[100];		/* for short error messages */
 
 int lineno;              /* line number for error messages */
@@ -106,9 +110,10 @@ unsigned char ubyte_val;       /* last byte value read */
 static Symbol* makepath(char* text);
 static int lexdebug(int);
 static unsigned long long parseULL(char* text, int*);
-static nc_type downconvert(unsigned long long uint64, int, int, int);
-static int tagmatch(nc_type nct, int tag, int hasU);
+static nc_type downconvert(unsigned long long uint64, int*, int, int);
+static int tagmatch(nc_type nct, int tag);
 static int nct2lexeme(nc_type nct);
+static int collecttag(char* text, char** stagp);
 
 static struct Specialtoken {
     char* name;
@@ -196,8 +201,8 @@ OPAQUESTRING	(0[xX][0-9A-Fa-f][0-9A-Fa-f]*)
 
 PATH    ([/]|([/]{ID})([/]{ID})*)
 
-XUNUMBER     {OPAQUESTRING}[SsLl]
-NUMBER       [+-]?[0-9][0-9]*[Uu]?[BbSsLl]?
+XUNUMBER     {OPAQUESTRING}([Ss]|[Ll]|[Ll][Ll])?
+NUMBER       [+-]?[0-9][0-9]*[Uu]?([BbSs]|[Ll]|[Ll][Ll])?
 DBLNUMBER    [+-]?[0-9]*\.[0-9]*{exp}?[LlDd]?|[+-]?[0-9]*{exp}[LlDd]?
 FLTNUMBER    [+-]?[0-9]*\.[0-9]*{exp}?[Ff]|[+-]?[0-9]*{exp}[Ff]
 
@@ -246,7 +251,7 @@ yytext[MAXTRST-1] = '\0';
 	        if((len % 2) == 1) bbAppend(lextext,'0');
 		bbNull(lextext);
 		/* convert all chars to lower case */
-		for(p=bbContents(lextext);*p;p++) *p = tolower(*p);
+		for(p=bbContents(lextext);(int)*p;p++) *p = tolower(*p);
 		return lexdebug(OPAQUESTRING);
 		}
 
@@ -364,33 +369,37 @@ NIL|nil|Nil {
 		}
 
 {NUMBER}    {
-/*
-We need to try to see what size of integer ((u)int).
-Technically, the user should specify, but...
-If out of any integer range, then complain
-*/
+		/*
+		  We need to try to see what size of integer ((u)int).
+		  Technically, the user should specify, but...
+		  If out of any integer range, then complain
+		*/
 		    int slen = strlen(ncgtext);
-		    int tag = ncgtext[slen-1];
-		    int hasU = 0;
+		    char* stag = NULL;
+		    int tag = NC_NAT;
 		    int signchar = 0;
 		    int isneg = 0;
 		    int c = ncgtext[0];
 		    int fail = 0;
 		    nc_type nct = 0;
 		    char* pos = NULL;
+		    int hasU = 0;
 
+		    /* capture the tag string */
+		    tag = collecttag(ncgtext,&stag);
+		    if(tag == NC_NAT) {
+			sprintf(errstr,"Illegal integer suffix: %s",stag);
+			yyerror(errstr);
+			goto done;
+		    }
+		    /* drop the tag from the input text */
+		    ncgtext[slen - strlen(stag)] = '\0';
+		    hasU = isuinttype(tag);
 		    if(!tstdecimal(c)) {
 			pos = ncgtext+1;
 			isneg = (c == '-');
 		    } else
 		        pos = ncgtext;
-		    if(tag != '\0' && strchr(TAG,tag) != NULL) {
-			if(slen > 2) {
-			    c = ncgtext[slen-2];
-			    hasU = (c == 'U' || c == 'u') ? 1 : 0;
-			}
-		    } else
-			tag = 0;
 		    if(isneg && hasU) {
 			sprintf(errstr,"Unsigned integer cannot be signed: %s",ncgtext);
 			yyerror(errstr);
@@ -403,7 +412,7 @@ If out of any integer range, then complain
 			goto done;
 		    }
 		    /* Down convert to smallest possible range */
-		    nct = downconvert(uint64_val,isneg,tag,hasU);
+		    nct = downconvert(uint64_val,&tag,isneg,hasU);
 		    switch (k_flag) {
 		    case NC_FORMAT_64BIT_DATA:
 		    case NC_FORMAT_NETCDF4:
@@ -417,10 +426,9 @@ If out of any integer range, then complain
 				goto done;
 			    }
 		    }
-		    if(!tagmatch(nct,tag,hasU))  {
-			sprintf(errstr,"Integer out of range for tag: %s",ncgtext);
-			yyerror(errstr);
-			goto done;
+
+		    if(!tagmatch(nct,tag))  {
+			semwarn(lineno,"Warning: Integer out of range for tag: %s; tag treated as changed.",ncgtext);
 		    }
 		    return lexdebug(nct2lexeme(nct));
 done: return 0;
@@ -430,10 +438,20 @@ done: return 0;
 		int c;
 		int token = 0;
 		int slen = strlen(yytext);
-		int tag = yytext[slen-1];
+		char* stag = NULL;
+	        int tag = NC_NAT;
 		char* hex = yytext+2; /* point to first true hex digit */
 		int xlen = (slen - 3);  /* true hex length */
+
 		yytext[slen-1] = '\0';
+	        /* capture the tag string */
+		tag = collecttag(yytext,&stag);
+		if(tag == NC_NAT) {
+		    sprintf(errstr,"Illegal integer suffix: %s",stag);
+		    yyerror(errstr);
+		    goto done;
+		}
+		yytext[slen - strlen(stag)] = '\0';
 	        if(xlen > 16) { /* truncate hi order digits */
 		    hex += (xlen - 16);
 		}
@@ -444,11 +462,14 @@ done: return 0;
 		    uint64_val = ((uint64_val << 4) | hexdigit);
 		}
 		switch (tag) {
-		case 'S': case 's':
+		case NC_USHORT:
 		    uint16_val = (unsigned short)uint64_val;
 		    token = USHORT_CONST;
 		    break;
-		case 'L': case 'l':
+		case NC_UINT:
+		    token = UINT_CONST;
+		    break;
+		case NC_UINT64:
 		    token = UINT64_CONST;
 		    break;
 		default: /* should never happen */
@@ -624,7 +645,7 @@ makepath(char* text0)
 }
 
 /*
-Parse a simple string of digitis into an unsigned long long
+Parse a simple string of digits into an unsigned long long
 Return the value.
 */
 static unsigned long long
@@ -654,122 +675,114 @@ parseULL(char* text, int* failp)
 /**
 Given the raw bits, the sign char, the tag, and hasU
 fill in the appropriate *_val field
-and return the type
+and return the type.
+Note that we cannot return unsigned types if running pure netcdf classic.
+The rule is to pick the smallest enclosing type.
+
+The rule used here is that the tag (the suffix, if any)
+always takes precedence and the value is modified to conform
+if possible, otherwise out-of-range is signalled.
+For historical reasons (ncgen3), values that fit as unsigned
+are acceptable for the signed tag and conversion is attempted;
+e.g. 65535s; is legal and is return as a negative short.
 */
 static nc_type
-downconvert(unsigned long long uint64, int isneg, int tag, int hasU)
+downconvert(unsigned long long uint64, int* tagp, int isneg, int hasU)
 {
     nc_type nct = NC_NAT;
-    int bit64 = (uint64 >> 63);
-    int allones = (uint64 == 0xffffffffffffffffUL);
+    int tag = *tagp;
+    int bit63set = (uint64 >> 63);
     long long int64 = *((long long*)&uint64);
 
-    if(isneg && hasU)
-	return NC_NAT;
-    /* Special cases: all (u)int64 values */
-    if(allones && (hasU || !isneg)) /* bare max uint64 value */
-	return NC_UINT64;
-    if((int64 < NC_MIN_INT) || (int64 > NC_MAX_INT)) {
-	if(isneg && !hasU) {
-	    int64_val = - int64;
-	    return NC_INT64;
-	}
-	if(!isneg && hasU) {
-	    uint64_val = uint64;
-	    return NC_UINT64;
-	}
-	/* Bare big integer, assume int64 unless sign bit set */
-	if(!isneg && !hasU && bit64) {
-	    uint64_val = uint64;
-	    return NC_UINT64;
-	} else if(!bit64) {
-	    int64_val = int64;
-	    return NC_INT64;
-	}
-        /*assert(!isneg)*/
+    if(isneg && hasU) {
+	return (*tagp = NC_NAT);
+    }
+    /* To simplify the code, we look for special case of NC_UINT64
+       constants that will not fit into an NC_INT64 constant.
+     */
+    if(tag == NC_UINT64 && bit63set) {
         uint64_val = uint64;
-	return NC_UINT64;
+	return tag;
     }
-
-    if(isneg) int64 = -int64;
-
-    /* special case:
-       If there is no tag and the size is ok,
-       then always return NC_INT or NC_UINT.
-    */
-    if(!tag) {
-	if(!hasU) {
-	    if((int64 >= NC_MIN_INT) && (int64 <= NC_MAX_INT)) {
-		int32_val = (int)int64;
-	        return NC_INT;
-	    }
-	}
-	if(uint64 <= NC_MAX_UINT) {
-	    uint32_val = (unsigned int)uint64;
-	    return NC_INT;
+    /* At this point we need deal only with int64 value */
+    /* Apply the isneg */
+    if(isneg)
+	int64 = - int64;
+
+    if(tag == NC_NOTAG) {
+        /* If we have no other info, then assume NC_(U)INT(64) */
+	if(int64 >= NC_MIN_INT && int64 <= NC_MAX_INT) {
+	    nct = (tag = NC_INT);
+	    int32_val = (signed int)int64;
+	} else if(int64 >= 0 && int64 <= NC_MAX_UINT) {
+	        nct = (tag = NC_UINT);
+	        uint32_val = (unsigned int)int64;
+	} else if(int64 < 0) {
+		nct = (tag = NC_INT64);
+	        int64_val = (signed long long)int64;
+	} else {
+	        nct = (tag = NC_UINT64);
+	        uint64_val = (unsigned long long)int64;
 	}
+        goto done;
     }
-    /* assert (tag != 0) */
-
-    /* Pick smallest enclosing type;
-       for historical reasons (ncgen3), technically out of range
-       values are allowed and conversion is attempted;
-	e.g. 65535s; is legal and is return as an unsigned short.
-    */
-    if(hasU) {
-        switch (tag) {
-        case 'B': case 'b':
-	    if((int64 >= 0) && (int64 <= NC_MAX_UBYTE)) {
+    if(isuinttype(tag) && int64 < 0)
+	goto outofrange;
+    switch (tag) {
+    case NC_UBYTE:
+	    if(int64 <= NC_MAX_UBYTE) {
 	        nct = NC_UBYTE;
 	        ubyte_val = (unsigned char)int64;
-	    }; break;
-        case 'S': case 's':
-	    if((int64 >= 0) && (int64 <= NC_MAX_USHORT)) {
+	    } else
+		goto outofrange;
+	    break;
+    case NC_USHORT:
+	    if(int64 <= NC_MAX_USHORT) {
 	        nct = NC_USHORT;
 	        uint16_val = (unsigned short)int64;
-	    } break;
-        case 'L': case 'l':
-            if((int64 >= 0) && (int64 <= NC_MAX_UINT64)) {
+	    } else
+	       goto outofrange;
+	    break;
+    case NC_UINT:
+	    if(int64 <= NC_MAX_UINT) {
+	        nct = NC_UINT;
+	        uint32_val = (unsigned int)int64;
+	    } else
+		goto outofrange;
+	    break;
+    case NC_UINT64:
+            if(int64 <= NC_MAX_UINT64) {
 	        nct = NC_UINT64;
 	        uint64_val = uint64;
-	    } break;
-	default:
-	    return NC_NAT;
-	}
-    } else { /* !hasU */
-        switch (tag) {
-        case 'B': case 'b':
-            if((int64 >= NC_MIN_BYTE) && (int64 <= NC_MAX_BYTE)) {
-	        nct = NC_BYTE;
-	        byte_val = (signed char)int64;
-	    } else {/* force to unsigned value */
-		uint64_val = uint64 & 0xff;
-		nct = NC_UBYTE;
-	    }
+	    } else
+		goto outofrange;
 	    break;
-        case 'S': case 's':
-	    if((int64 >= NC_MIN_SHORT) && (int64 <= NC_MAX_SHORT)) {
-	        nct = NC_SHORT;
-	        int16_val = (signed short)int64;
-	    } else {/* force to unsigned value */
-		uint64_val = uint64 & 0xffff;
-		nct = NC_USHORT;
-	    }
+    case NC_INT64:
+	    nct = NC_INT64;
+	    int64_val = int64;
 	    break;
-        case 'L': case 'l':
-            if((uint64 <= NC_MAX_INT64)) {
-	        nct = NC_INT64;
-	        int64_val = int64;
-	    } else {/* force to unsigned value */
-		uint64_val = uint64;
-		nct = NC_UINT64;
-	    }
+    case NC_BYTE:
+	    nct = NC_BYTE;
+	    byte_val = (signed char)int64;
 	    break;
-	default:
-	    return NC_NAT;
-	}
+    case NC_SHORT:
+	    nct = NC_SHORT;
+	    int16_val = (signed short)int64;
+	    break;
+    case NC_INT:
+	    nct = NC_INT;
+	    int32_val = (signed int)int64;
+	    break;
+    default:
+	    goto outofrange;
     }
+
+done:
+    *tagp = tag;
     return nct;
+outofrange:
+    yyerror("Value out of range");
+    return NC_NAT;
 }
 
 static int
@@ -789,23 +802,62 @@ nct2lexeme(nc_type nct)
     return 0;
 }
 
+static int
+tagmatch(nc_type nct, int tag)
+{
+    if(tag == NC_NAT || tag ==  NC_NOTAG)
+	return 1;
+    return nct == tag;
+}
 
+/* capture the tag string */
 static int
-tagmatch(nc_type nct, int tag, int hasU)
+collecttag(char* text, char** stagp)
 {
-    if(hasU) switch(nct) {
-        case NC_UBYTE: return (tag == 0 || tag == 'B' || tag == 'b');
-        case NC_USHORT: return (tag == 0 || tag == 'S' || tag == 's');
-        case NC_UINT: return (tag == 0);
-        case NC_UINT64: return (tag == 0 || tag == 'L' || tag == 'l');
-	default: return 0;
-    } else switch(nct) {
-	case NC_BYTE: return (tag == 0 || tag == 'B' || tag == 'b');
-	case NC_SHORT: return (tag == 0 || tag == 'S' || tag == 's');
-	case NC_INT: return (tag == 0);
-	case NC_INT64: return (tag == 0 || tag == 'L' || tag == 'l');
-	default: return 0;
+    char* stag0;
+#define MAXTAGLEN 3
+    char stag[MAXTAGLEN+1];
+    int slen = strlen(text);
+    int staglen;
+    int tag = NC_NAT;
+    int hasU = 0;
+
+    for(stag0 = text+(slen-1);stag0 > 0;stag0--) {
+	if(strchr(TAGCHARS,*stag0) == NULL) {stag0++; break;}
     }
-    return 0;
+    if(stagp) *stagp = stag0;
+    staglen = strlen(stag0);
+    if(staglen == 0)
+	return NC_NOTAG;
+    if(staglen > MAXTAGLEN)
+	return tag;
+    strncpy(stag,stag0,sizeof(stag));
+    stag[MAXTAGLEN] = '\0';
+    if(stag[0] == 'U' || stag[0] == 'u') {
+	hasU = 1;
+    memmove(stag,stag+1,MAXTAGLEN);
+	staglen--;
+    } else if(stag[staglen-1] == 'U' || stag[staglen-1] == 'u') {
+	hasU = 1;
+	staglen--;
+	stag[staglen] = '\0';
+    }
+    if(strlen(stag) == 0 && hasU) {
+	tag = NC_UINT64;
+    } else if(strlen(stag) == 1) {
+	switch (stag[0]) {
+	case 'B': case 'b': tag = (hasU ? NC_UBYTE : NC_BYTE); break;
+	case 'S': case 's': tag = (hasU ? NC_USHORT : NC_SHORT); break;
+	case 'L': case 'l': tag = (hasU ? NC_UINT : NC_INT); break;
+	default: break;
+	}
+    } else if(strcasecmp(stag,"ll") == 0) {
+	tag = (hasU ? NC_UINT64 : NC_INT64);
+    }
+    if(tag == NC_NAT) {
+	if(strlen(stag) > 0)
+	    return tag;
+	tag = NC_NAT;
+    }
+    return tag;
 }
-
diff --git a/ncgen/ncgen.y b/ncgen/ncgen.y
index 2dd12f7..7a6b1b4 100644
--- a/ncgen/ncgen.y
+++ b/ncgen/ncgen.y
@@ -159,8 +159,8 @@ NCConstant       constant;
         INT64_CONST   /* long long constant */
         UBYTE_CONST  /* unsigned byte constant */
         USHORT_CONST /* unsigned short constant */
-        UINT_CONST   /* unsigned long long constant */
-        UINT64_CONST   /* unsigned int constant */
+        UINT_CONST   /* unsigned int  constant */
+        UINT64_CONST   /* unsigned long long  constant */
         FLOAT_CONST /* float constant */
         DOUBLE_CONST/* double constant */
         DIMENSIONS  /* keyword starting dimensions section, if any */
@@ -438,37 +438,13 @@ dimdeclist:     dimdecl
                 ;
 
 dimdecl:
-	  dimd '=' UINT_CONST
+	  dimd '=' UINT64_CONST
               {
-		$1->dim.declsize = (size_t)uint32_val;
+		$1->dim.declsize = (size_t)uint64_val;
 #ifdef GENDEBUG1
-fprintf(stderr,"dimension: %s = %lu\n",$1->name,(unsigned long)$1->dim.declsize);
+fprintf(stderr,"dimension: %s = %llu\n",$1->name,(unsigned long long)$1->dim.declsize);
 #endif
 	      }
-	| dimd '=' INT_CONST
-              {
-		if(int32_val <= 0) {
-		    derror("dimension size must be positive");
-		    YYABORT;
-		}
-		$1->dim.declsize = (size_t)int32_val;
-#ifdef GENDEBUG1
-fprintf(stderr,"dimension: %s = %lu\n",$1->name,(unsigned long)$1->dim.declsize);
-#endif
-	      }
-        | dimd '=' DOUBLE_CONST
-                   { /* for rare case where 2^31 < dimsize < 2^32 */
-                       if (double_val <= 0)
-                         yyerror("dimension length must be positive");
-                       if (double_val > MAXFLOATDIM)
-                         yyerror("dimension too large");
-                       if (double_val - (size_t) double_val > 0)
-                         yyerror("dimension length must be an integer");
-                       $1->dim.declsize = (size_t)double_val;
-#ifdef GENDEBUG1
-fprintf(stderr,"dimension: %s = %lu\n",$1->name,(unsigned long)$1->dim.declsize);
-#endif
-                   }
         | dimd '=' NC_UNLIMITED_K
                    {
 		        $1->dim.declsize = NC_UNLIMITED;
@@ -903,7 +879,7 @@ ncgwrap(void)                    /* returns 1 on EOF if no more input */
 }
 
 /* get lexical input routine generated by lex  */
-#include "ncgenyy.c"
+#include "ncgenl.c"
 
 /* Really should init our data within this file */
 void
diff --git a/ncgen/ncgenyy.c b/ncgen/ncgenl.c
similarity index 62%
rename from ncgen/ncgenyy.c
rename to ncgen/ncgenl.c
index ee8c86f..3b8187a 100644
--- a/ncgen/ncgenyy.c
+++ b/ncgen/ncgenl.c
@@ -1,5 +1,5 @@
 
-#line 3 "ncgenyy.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;
@@ -387,7 +388,7 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[382] =
+static yyconst flex_int16_t yy_accept[384] =
     {   0,
         0,    0,   45,   45,    0,    0,   49,   47,    1,   43,
        47,   47,   47,   47,   37,   31,   35,   35,   34,   34,
@@ -396,41 +397,41 @@ static yyconst flex_int16_t yy_accept[382] =
        34,   34,   47,   47,   47,   45,   48,   33,   48,    1,
         0,    3,    0,    0,    0,   37,   35,    0,    0,   37,
        37,    0,   38,   44,    2,   31,    0,    0,    0,    0,
-       35,   35,   35,    0,   34,    0,    0,    0,    0,   34,
+       35,   35,   35,   35,    0,   34,    0,    0,    0,    0,
        34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
        34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
 
        34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
        34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
-       34,    0,    0,   45,    0,   46,   33,   39,    0,    0,
-        0,    0,   37,    0,    0,   37,    2,   31,    0,    0,
-        0,    0,    0,    0,    0,    4,    0,    0,   34,   34,
-       34,   34,   34,   34,   30,   27,   34,   34,   34,   34,
-       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
-       34,   34,   34,   34,   34,   14,   34,   27,   34,   34,
+       34,   34,    0,    0,   45,    0,   46,   33,   39,    0,
+        0,    0,    0,   37,    0,    0,   37,    2,   31,    0,
+        0,    0,    0,    0,    0,    0,    4,    0,    0,   34,
+       34,   34,   34,   34,   34,   30,   27,   34,   34,   34,
        34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
-        0,   42,    0,    0,   37,    0,   31,    0,    0,    0,
-
-        0,    0,    0,    0,    4,   36,    0,   34,   34,   28,
-       34,   34,   29,   34,   34,   34,   34,   34,   34,   34,
-       34,   34,   34,   10,    9,   34,   34,   34,   34,    6,
-       34,   34,   34,   34,   14,   34,   34,   34,    8,   34,
-       34,   34,   34,   15,   34,   34,   34,   34,    0,    0,
-       28,    0,   31,    0,    0,    0,    0,    0,    0,    0,
+       34,   34,   34,   34,   34,   34,   14,   34,   27,   34,
        34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
-       34,   34,   34,   34,   34,   23,   34,   34,   34,   16,
-       34,   34,   34,   34,   12,   34,   34,   11,   34,   34,
-       15,   34,   34,   34,   40,   41,    0,    0,    0,    0,
-
-       34,   34,   34,   25,   34,   34,   34,   34,   34,   34,
-       34,   34,   34,   34,   34,   34,   18,   24,   34,    7,
-        5,   20,   17,   34,   34,   13,   34,    0,    0,   34,
-       34,   34,   34,   34,   34,   34,   34,   34,   32,   34,
-       34,   34,   34,   34,   34,   34,   34,    0,   34,   26,
-       34,   34,   34,   34,   34,   34,    5,   34,   34,   34,
-       34,   26,   26,   19,   34,   34,   34,   34,   34,   34,
-       34,   34,   34,   34,   34,   34,   22,   34,   21,   34,
-        0
+       34,    0,   42,    0,    0,   37,    0,   31,    0,    0,
+
+        0,    0,    0,    0,    0,    4,   36,   36,    0,   34,
+       34,   28,   34,   34,   29,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   10,    9,   34,   34,   34,
+       34,    6,   34,   34,   34,   34,   14,   34,   34,   34,
+        8,   34,   34,   34,   34,   15,   34,   34,   34,   34,
+        0,    0,   28,    0,   31,    0,    0,    0,    0,    0,
+        0,    0,   34,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   23,   34,   34,
+       34,   16,   34,   34,   34,   34,   12,   34,   34,   11,
+       34,   34,   15,   34,   34,   34,   40,   41,    0,    0,
+
+        0,    0,   34,   34,   34,   25,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   18,   24,
+       34,    7,    5,   20,   17,   34,   34,   13,   34,    0,
+        0,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       32,   34,   34,   34,   34,   34,   34,   34,   34,    0,
+       34,   26,   34,   34,   34,   34,   34,   34,    5,   34,
+       34,   34,   34,   26,   26,   19,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   22,   34,
+       21,   34,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -476,100 +477,102 @@ static yyconst flex_int32_t yy_meta[68] =
        11,   11,   14,    1,   11,   11,   11
     } ;
 
-static yyconst flex_int16_t yy_base[400] =
+static yyconst flex_int16_t yy_base[402] =
     {   0,
-        0,    0,  336,  331,  274,  273,  331, 2153,   66, 2153,
-       63,  289,   60,   61,   93,   83,  140,  285,   50,   60,
+        0,    0,  345,  343,  285,  283,  344, 2153,   66, 2153,
+       63,  301,   60,   61,   93,   83,  140,  300,   50,   60,
       191,   64,   95,  154,  102,  198,  198,  180,  195,  228,
-      269,  188,  213,  221,  232,  252,  237,  245,  267,  263,
-      297,  275,  256,  252,  245,  300,  295,    0, 2153,   78,
-       86, 2153,  303,  277,  342,    0,  245,  356,  225,    0,
-     2153,  367, 2153, 2153,    0,  340,  374,  210,  208,  207,
-      230, 2153,  141,    0,  329,  393,  188,  186,  185,  370,
-       74,  400,  373,  396,  381,  386,  417,  404,  427,  420,
-      430,  434,  437,  460,  452,  473,  476,  483,  486,  497,
-
-      494,  506,  509,  516,  532,  528,  539,  549,  542,  546,
-      552,  582,  572,  565,  586,  589,  605,  608,  626,  620,
-      639,  180,  179,  232,  227, 2153,    0, 2153,  230,  683,
-      228,  665,  694,  189,  712,  732,    0,  650,  491,  748,
-      168,  164,  163,  131,  129,  146,  125,  124,  700,  704,
-      722,  734,  747,  740,  743,  752,  755,  764,  787,  790,
-      777,  796,  803,  799,  808,  833,  838,  822,  841,  845,
-      852,  856,  863,  875,  878,  908,  889,  893,  915,  896,
-      882,  912,  926,  932,  929,  945,  948,  968,  952,  982,
-      123, 2153, 1008,    0, 2153,   48,  989, 1023,  122,  121,
-
-      114,  108,  101,   88,  293, 2153,   82,  993, 1006, 1012,
-     1015, 1027, 1019, 1030, 1024, 1037, 1050, 1061, 1067, 1070,
-     1074, 1085, 1082, 1091, 1104, 1107, 1123, 1115, 1126, 1130,
-     1140, 1145, 1137, 1148, 1162, 1183, 1179, 1171, 1186, 1196,
-     1193, 1209, 1226, 1239, 1233, 1229, 1246, 1249,  138,  137,
-     2153,   90, 1243, 1313,   77,   75,   71,   68,   64,   58,
-     1259, 1293, 1289, 1263, 1303, 1296, 1300, 1306, 1312, 1315,
-     1345, 1336, 1349, 1352, 1361, 2153, 1366, 1369, 1386, 1383,
-     1399, 1402, 1409, 1417, 1392, 1422, 1425, 1406, 1439, 1432,
-     1443, 1447, 1458, 1462, 2153, 2153,   55,   36,   35,   33,
-
-     1473, 1455, 1477, 1480, 1492, 1498, 1495, 1503, 1510, 1533,
-     1516, 1528, 1541, 1546, 1549, 1571, 1558, 2153, 1564, 1567,
-     1580, 2153, 1583, 1597, 1602, 1588, 1606,   36,   25, 1613,
-     1621, 1632, 1651, 1636, 1647, 1643, 1654, 1662, 1658, 1667,
-     1692, 1688, 1684, 1700, 1704, 1697, 1708,   24, 1723, 1734,
-     1753, 1742, 1746, 1749, 1758, 1765, 1768, 1784, 1799, 1802,
-     1789,   36, 1806, 1809, 1814, 1819, 1832, 1839, 1844, 1850,
-     1858, 1855, 1870, 1862, 1875, 1894, 2153, 1900, 2153, 1905,
-     2153, 1972, 1986, 2000, 2014, 2023, 2032, 2041, 2054, 2068,
-     2081, 2095, 2105, 2111, 2119, 2121, 2127, 2133, 2139
-
+      284,  188,  213,  221,  232,  252,  237,  245,  267,  263,
+      297,  275,  267,  263,  258,  313,  308,    0, 2153,   78,
+       86, 2153,  313,  302,  342,    0,  271,  356,  255,    0,
+     2153,  367, 2153, 2153,    0,  340,  374,  242,  220,  218,
+      240, 2153,   53,  141,    0,  329,  393,  210,  208,  207,
+      370,   75,  400,  373,  396,  381,  386,  417,  404,  427,
+      420,  430,  434,  437,  460,  452,  473,  476,  483,  486,
+
+      497,  494,  506,  509,  516,  532,  528,  539,  549,  542,
+      546,  552,  582,  572,  565,  586,  589,  605,  608,  626,
+      620,  639,  203,  188,  242,  237, 2153,    0, 2153,  237,
+      683,  236,  665,  694,  195,  712,  732,    0,  650,  491,
+      748,  175,  173,  171,  170,  168,  146,  164,  163,  700,
+      704,  722,  734,  747,  740,  743,  752,  755,  764,  787,
+      790,  777,  796,  803,  799,  808,  833,  838,  822,  841,
+      845,  852,  856,  863,  875,  878,  908,  889,  893,  915,
+      896,  882,  912,  926,  932,  929,  945,  948,  968,  952,
+      982,  131, 2153, 1008,    0, 2153,   48,  989, 1023,  129,
+
+      125,  124,  123,  122,  121,  293,   92, 2153,  114,  993,
+     1006, 1012, 1015, 1027, 1019, 1030, 1024, 1037, 1050, 1061,
+     1067, 1070, 1074, 1085, 1082, 1091, 1104, 1107, 1123, 1115,
+     1126, 1130, 1140, 1145, 1137, 1148, 1162, 1183, 1179, 1171,
+     1186, 1196, 1193, 1209, 1226, 1239, 1233, 1229, 1246, 1249,
+      165,  158, 2153,  100, 1243, 1313,   82,   81,   80,   77,
+       75,   71, 1259, 1293, 1289, 1263, 1303, 1296, 1300, 1306,
+     1312, 1315, 1345, 1336, 1349, 1352, 1361, 2153, 1366, 1369,
+     1386, 1383, 1399, 1402, 1409, 1417, 1392, 1422, 1425, 1406,
+     1439, 1432, 1443, 1447, 1458, 1462, 2153, 2153,   84,   64,
+
+       36,   35, 1473, 1455, 1477, 1480, 1492, 1498, 1495, 1503,
+     1510, 1533, 1516, 1528, 1541, 1546, 1549, 1571, 1558, 2153,
+     1564, 1567, 1580, 2153, 1583, 1597, 1602, 1588, 1606,   39,
+       30, 1613, 1621, 1632, 1651, 1636, 1647, 1643, 1654, 1662,
+     1658, 1667, 1692, 1688, 1684, 1700, 1704, 1697, 1708,   28,
+     1723, 1734, 1753, 1742, 1746, 1749, 1758, 1765, 1768, 1784,
+     1799, 1802, 1789,   36, 1806, 1809, 1814, 1819, 1832, 1839,
+     1844, 1850, 1858, 1855, 1870, 1862, 1875, 1894, 2153, 1900,
+     2153, 1905, 2153, 1972, 1986, 2000, 2014, 2023, 2032, 2041,
+     2054, 2068, 2081, 2095, 2105, 2111, 2119, 2121, 2127, 2133,
+
+     2139
     } ;
 
-static yyconst flex_int16_t yy_def[400] =
+static yyconst flex_int16_t yy_def[402] =
     {   0,
-      381,    1,  382,  382,  383,  383,  381,  381,  381,  381,
-      384,  385,  381,  386,  381,  387,  381,   17,  388,  388,
-      388,  388,  388,  388,  388,  381,  388,  388,  388,  388,
-       21,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  381,  381,  381,  389,  389,  390,  381,  381,
-      384,  381,  384,  381,  391,   15,   17,  381,  381,   15,
-      381,  381,  381,  381,  392,  393,  381,  381,  381,  381,
-       17,  381,  381,  394,  388,  381,  381,  381,  381,  388,
-       21,   21,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  381,  381,  389,  389,  381,  390,  381,  381,  381,
-      395,  381,  381,  381,  381,  381,  392,  393,  396,  381,
-      381,  381,  381,  381,  381,  397,  381,  381,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      381,  381,  381,  398,  381,  381,  399,  381,  381,  381,
-
-      381,  381,  381,  381,  397,  381,  381,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  381,  381,
-      381,  381,  399,  381,  381,  381,  381,  381,  381,  381,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  381,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  381,  381,  381,  381,  381,  381,
-
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  381,  388,  388,
-      388,  381,  388,  388,  388,  388,  388,  381,  381,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  381,  388,  388,
-      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  381,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  388,  388,  388,  388,  388,  381,  388,  381,  388,
-        0,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381
+      383,    1,  384,  384,  385,  385,  383,  383,  383,  383,
+      386,  387,  383,  388,  383,  389,  383,   17,  390,  390,
+      390,  390,  390,  390,  390,  383,  390,  390,  390,  390,
+       21,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  383,  383,  383,  391,  391,  392,  383,  383,
+      386,  383,  386,  383,  393,   15,   17,  383,  383,   15,
+      383,  383,  383,  383,  394,  395,  383,  383,  383,  383,
+       17,  383,  383,  383,  396,  390,  383,  383,  383,  383,
+      390,   21,   21,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
 
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  383,  383,  391,  391,  383,  392,  383,  383,
+      383,  397,  383,  383,  383,  383,  383,  394,  395,  398,
+      383,  383,  383,  383,  383,  383,  399,  383,  383,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  383,  383,  383,  400,  383,  383,  401,  383,  383,
+
+      383,  383,  383,  383,  383,  399,  383,  383,  383,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      383,  383,  383,  383,  401,  383,  383,  383,  383,  383,
+      383,  383,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  383,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  383,  383,  383,  383,
+
+      383,  383,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  383,
+      390,  390,  390,  383,  390,  390,  390,  390,  390,  383,
+      383,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  383,
+      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  383,  390,  390,  390,  390,  390,  390,
+      390,  390,  390,  390,  390,  390,  390,  390,  383,  390,
+      383,  390,    0,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
+
+      383
     } ;
 
 static yyconst flex_int16_t yy_nxt[2221] =
@@ -582,242 +585,242 @@ static yyconst flex_int16_t yy_nxt[2221] =
        19,   36,   37,   19,   19,   38,   39,   40,   41,   42,
        19,   19,    8,    8,   43,   44,   45,   50,   52,   50,
        56,   56,   57,   57,   57,   57,   57,   57,   57,   50,
-      251,   50,   75,   75,  362,   58,   58,   76,  253,   59,
-       64,   52,  251,  348,   65,  252,  197,   76,  329,  253,
-
-       53,   76,  328,   58,   58,   60,   60,   60,   60,   60,
-       60,   60,   80,   83,   77,   78,   79,   61,   62,   63,
-       67,  138,   61,   53,   77,   78,   79,  300,   77,   78,
-       79,  197,   76,   89,  299,   61,   62,   63,  298,   76,
-      253,  297,   61,  296,  295,   75,   84,   68,   69,   70,
-       56,   66,   71,   71,   71,   71,   71,   71,   71,   77,
-       78,   79,   72,   72,  260,   58,   77,   78,   79,   72,
-       72,  138,   72,   72,   73,  206,   74,  259,  206,   85,
-       72,   72,   86,   58,  258,  197,   90,  207,   75,   72,
-       72,   76,  204,   87,   66,  206,   72,   72,   73,   81,
-
-       81,   88,  206,   82,   82,   82,   82,   82,   82,   82,
-       90,   90,   90,   90,   90,   90,   90,   76,   77,   78,
-       79,   91,   92,   93,   94,   76,  203,  202,   76,   95,
-       96,  138,   76,  196,  192,   76,  192,  104,  381,  125,
-       97,   98,  191,   90,   77,   78,   79,   99,  148,  147,
-       76,   75,   77,   78,   79,   77,   78,   79,   76,   77,
-       78,   79,   77,   78,   79,   76,  381,  100,  105,   76,
-      145,  144,  106,   66,   76,  101,  134,   77,   78,   79,
-      102,  381,   76,  128,  107,   77,   78,   79,  112,   76,
-      111,  108,   77,   78,   79,  109,   77,   78,   79,  110,
-
-       76,   77,   78,   79,   76,  381,  126,  125,  123,   77,
-       78,   79,   76,  113,  121,  122,   77,   78,   79,   90,
-      103,  381,  206,  115,  114,  206,   55,   77,   78,   79,
-      381,   77,   78,   79,   76,   49,   49,  116,   47,   77,
-       78,   79,  206,   47,  117,  381,  118,  381,  119,  206,
-      381,  139,  381,  120,  130,  130,  130,  130,  130,  130,
-      381,   77,   78,   79,  132,  132,   76,  381,  133,  133,
-      133,  133,  133,  133,  133,  135,  135,  140,  131,  136,
-      136,  136,  136,  136,  136,  136,   66,   66,   66,   66,
-       66,   66,   66,   77,   78,   79,   75,   75,   75,   75,
-
-       75,  381,  381,  381,  141,  142,  143,   76,   75,   75,
-       76,  381,   75,  381,  154,  155,  381,  381,   76,  381,
-      381,  381,  381,   76,  150,  152,  151,  381,  149,  150,
-       75,  381,  381,   76,   77,   78,   79,   77,   78,   79,
-      153,   76,  150,  381,  151,   77,   78,   79,  156,  150,
-       77,   78,   79,  155,   76,   75,  157,   76,  381,  381,
-       77,   78,   79,  381,   76,  381,  381,   76,   77,   78,
-       79,   76,  381,  381,   76,  381,  158,  159,  381,  381,
-      381,   77,   78,   79,   77,   78,   79,  381,  160,   76,
-      381,   77,   78,   79,   77,   78,   79,   76,   77,   78,
-
-       79,   77,   78,   79,  164,  381,  381,  161,  381,  162,
-       76,  381,  163,   76,  381,  381,   77,   78,   79,  165,
-       76,  381,  168,   76,   77,   78,   79,  381,  198,  381,
-      166,   76,  381,  167,   76,  381,  169,   77,   78,   79,
-       77,   78,   79,   76,  171,  381,   76,   77,   78,   79,
-       77,   78,   79,   76,  170,  199,  200,  201,   77,   78,
-       79,   77,   78,   79,  172,   76,  381,  173,  174,   76,
-       77,   78,   79,   77,   78,   79,   76,  381,  381,   76,
-       77,   78,   79,   76,  175,  176,   76,  381,  381,   76,
-      177,  180,   77,   78,   79,  155,   77,   78,   79,  179,
-
-      178,  381,   76,   77,   78,   79,   77,   78,   79,   76,
-       77,   78,   79,   77,   78,   79,   77,   78,   79,   76,
-      183,  181,  381,   76,  182,  381,   76,  381,  381,   77,
-       78,   79,  381,  381,  381,  381,   77,   78,   79,  184,
-      381,  381,   76,  381,  381,   76,   77,   78,   79,  185,
-       77,   78,   79,   77,   78,   79,  186,   76,  381,  381,
-      187,  139,  381,   76,  381,  381,  189,  381,  381,   77,
-       78,   79,   77,   78,   79,  188,   76,  133,  133,  133,
-      133,  133,  133,  133,   77,   78,   79,  140,  381,  192,
-       77,   78,   79,  381,  190,  193,  193,  193,  193,  193,
-
-      193,  381,  381,   77,   78,   79,  133,  133,  133,  133,
-      133,  133,  133,  381,  141,  142,  143,  381,  195,  381,
-       63,  381,  381,  195,  136,  136,  136,  136,  136,  136,
-      136,  381,  381,  381,  381,  381,  195,   76,   63,  381,
-      208,   76,  381,  195,  136,  136,  136,  136,  136,  136,
-      136,  138,  138,  138,  138,  138,   61,  381,   63,   76,
-      381,   61,  381,  212,   77,   78,   79,  138,   77,   78,
-       79,   76,  381,  209,   61,  381,   63,   76,  381,  381,
-       76,   61,  381,  214,   76,  138,   77,   78,   79,   76,
-      381,  210,   76,  381,  211,  381,  213,  381,   77,   78,
-
-       79,   76,  381,  381,   77,   78,   79,   77,   78,   79,
-      138,   77,   78,   79,   76,  381,   77,   78,   79,   77,
-       78,   79,  215,  381,   76,  221,  218,   76,   77,   78,
-       79,  216,  217,   76,  381,  381,   76,  381,  381,  219,
-       76,   77,   78,   79,  381,   76,  381,  381,  381,  381,
-      381,   77,   78,   79,   77,   78,   79,  381,  220,   76,
-       77,   78,   79,   77,   78,   79,  222,   77,   78,   79,
-       76,  381,   77,   78,   79,   76,  381,  225,   76,  381,
-      381,  224,   76,  381,  227,  223,   77,   78,   79,   76,
-      381,  381,  381,   76,  226,  228,  229,   77,   78,   79,
-
-       76,  381,   77,   78,   79,   77,   78,   79,  381,   77,
-       78,   79,   76,  230,  231,   76,   77,   78,   79,   76,
-       77,   78,   79,  381,  381,  233,   76,   77,   78,   79,
-       76,  239,  381,   76,  235,  381,  232,  213,  236,   77,
-       78,   79,   77,   78,   79,   76,   77,   78,   79,   76,
-      238,  234,   76,   77,   78,   79,  237,   77,   78,   79,
-       77,   78,   79,   76,  381,  381,   76,  240,  381,   76,
-      381,  381,   77,   78,   79,  242,   77,   78,   79,   77,
-       78,   79,   76,  381,  241,   76,  243,  381,  381,   76,
-       77,   78,   79,   77,   78,   79,   77,   78,   79,  245,
-
-      139,  381,  244,  381,  247,   76,  381,  381,  381,   77,
-       78,   79,   77,   78,   79,  246,   77,   78,   79,   76,
-      249,  249,  249,  249,  249,  249,  254,  381,  381,  248,
-       76,  381,   77,   78,   79,  197,  197,  197,  197,  197,
-      197,  197,  261,   76,  381,  381,   77,   78,   79,   76,
-      381,  264,   76,  255,  256,  257,   76,   77,   78,   79,
-      265,   76,  381,  262,   76,  381,  263,   76,  381,  381,
-       77,   78,   79,  381,   76,  266,   77,   78,   79,   77,
-       78,   79,  381,   77,   78,   79,  267,   76,   77,   78,
-       79,   77,   78,   79,   77,   78,   79,  268,   76,  381,
-
-      381,   77,   78,   79,   76,  381,  381,   76,  381,  381,
-      269,   76,  381,  381,   77,   78,   79,  381,  381,   76,
-      271,  272,   76,  381,  270,   77,   78,   79,   76,  273,
-      381,   77,   78,   79,   77,   78,   79,  274,   77,   78,
-       79,   76,  276,  381,   76,  381,   77,   78,   79,   77,
-       78,   79,   76,  280,  381,   77,   78,   79,  381,  275,
-       76,  381,  381,   76,  381,  381,  277,   76,   77,   78,
-       79,   77,   78,   79,   76,  278,  381,   76,  381,   77,
-       78,   79,   76,  381,  381,   76,  381,   77,   78,   79,
-       77,   78,   79,  281,   77,   78,   79,  239,  279,   76,
-
-      381,   77,   78,   79,   77,   78,   79,  282,   76,   77,
-       78,   79,   77,   78,   79,  381,   76,  381,  381,  381,
-       76,  283,  381,   76,  381,  381,   77,   78,   79,  284,
-       76,  381,  381,   76,  286,   77,   78,   79,  381,  381,
-      381,  381,  381,   77,   78,   79,   76,   77,   78,   79,
-       77,   78,   79,  285,  139,  381,  289,   77,   78,   79,
-       77,   78,   79,   76,  381,  287,   76,  381,  381,  288,
-       76,  381,  381,   77,   78,   79,   76,  381,  291,  292,
-      254,  381,  290,   76,  381,  381,   76,  381,  294,  304,
-       77,   78,   79,   77,   78,   79,   76,   77,   78,   79,
-
-       76,  293,  301,   77,   78,   79,  381,  255,  256,  257,
-       77,   78,   79,   77,   78,   79,  253,  253,  253,  253,
-      253,  302,  381,   77,   78,   79,   76,   77,   78,   79,
-       76,  305,  253,   76,  381,  381,  303,   76,  381,  307,
-       76,  381,  381,   76,  306,  308,  381,  309,  381,   76,
-      253,  381,   76,   77,   78,   79,  310,   77,   78,   79,
-       77,   78,   79,  381,   77,   78,   79,   77,   78,   79,
-       77,   78,   79,   76,  381,  253,   77,   78,   79,   77,
-       78,   79,   76,  381,  311,  312,   76,  381,  381,   76,
-      381,  314,  381,  313,  381,  381,  381,  381,   76,  381,
-
-       77,   78,   79,   76,  381,  318,   76,  381,  381,   77,
-       78,   79,  317,   77,   78,   79,   77,   78,   79,  315,
-       76,  381,  316,   76,  381,   77,   78,   79,  304,   76,
-       77,   78,   79,   77,   78,   79,   76,  381,  381,   76,
-      381,  381,  319,   76,  322,  381,   76,   77,   78,   79,
-       77,   78,   79,  304,   76,  323,   77,   78,   79,   76,
-      320,  381,   76,   77,   78,   79,   77,   78,   79,   76,
-       77,   78,   79,   77,   78,   79,   76,  324,  381,  321,
-       76,   77,   78,   79,   76,  381,   77,   78,   79,   77,
-       78,   79,   76,  381,  325,   76,   77,   78,   79,   76,
-
-      381,  330,  327,   77,   78,   79,  331,   77,   78,   79,
-       76,   77,   78,   79,   76,  326,  381,   76,  381,   77,
-       78,   79,   77,   78,   79,  333,   77,   78,   79,   76,
-      334,  381,   76,  381,  332,   76,  381,   77,   78,   79,
-       76,   77,   78,   79,   77,   78,   79,   76,  381,  337,
-      381,  381,  335,   76,  336,  381,   77,   78,   79,   77,
-       78,   79,   77,   78,   79,   76,  381,   77,   78,   79,
-       76,  381,  381,  339,   77,   78,   79,  339,   76,  338,
-       77,   78,   79,   76,  381,  381,   76,  381,  381,  381,
-      340,  341,   77,   78,   79,   76,  381,   77,   78,   79,
-
-      342,   76,  381,  381,   76,   77,   78,   79,   76,  381,
-       77,   78,   79,   77,   78,   79,  381,   76,  343,  235,
-       76,  381,   77,   78,   79,   76,  381,  381,   77,   78,
-       79,   77,   78,   79,   76,   77,   78,   79,  344,   76,
-      345,  381,  381,   76,   77,   78,   79,   77,   78,   79,
-       76,  381,   77,   78,   79,  347,  381,  381,   76,  346,
-      381,   77,   78,   79,  349,  210,   77,   78,   79,   76,
-       77,   78,   79,   76,  381,  381,  351,   77,   78,   79,
-       76,  381,  381,  352,   76,   77,   78,   79,   76,  381,
-      353,   76,  350,  381,  354,   76,   77,   78,   79,   76,
-
-       77,   78,   79,  355,   76,  356,  381,   77,   78,   79,
-      339,   77,   78,   79,  381,   77,   78,   79,   77,   78,
-       79,   76,   77,   78,   79,   76,   77,   78,   79,   76,
-      357,   77,   78,   79,   76,  339,  358,   76,  381,  381,
-      360,   76,  381,  381,  381,   76,  381,  381,   77,   78,
-       79,  361,   77,   78,   79,  359,   77,   78,   79,  291,
-       76,   77,   78,   79,   77,   78,   79,  363,   77,   78,
-       79,   76,   77,   78,   79,  366,  381,  364,  210,   76,
-      381,  381,  381,   76,  381,  381,   76,   77,   78,   79,
-       76,  381,  367,  381,  381,   76,  381,  381,   77,   78,
-
-       79,  381,   76,  365,  381,   76,   77,   78,   79,  381,
-       77,   78,   79,   77,   78,   79,  368,   77,   78,   79,
-      369,   76,   77,   78,   79,  381,   76,  381,  381,   77,
-       78,   79,   77,   78,   79,  370,   76,  381,  381,   76,
-      381,  381,  357,   76,  364,  371,   76,  381,   77,   78,
-       79,   76,  381,   77,   78,   79,   76,  372,  381,  375,
-      381,  381,  373,   77,   78,   79,   77,   78,   79,   76,
-       77,   78,   79,   77,   78,   79,   76,  377,   77,   78,
-       79,   76,  339,   77,   78,   79,  381,   76,  374,  339,
-      381,  381,   76,  381,  381,   76,   77,   78,   79,   76,
-
-      381,  381,  381,   77,   78,   79,  376,   76,   77,   78,
-       79,  339,   76,  379,   77,   78,   79,  381,  339,   77,
-       78,   79,   77,   78,   79,  381,   77,   78,   79,  378,
-      381,   76,  381,  381,   77,   78,   79,   76,  381,   77,
-       78,   79,   76,  380,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  339,  381,  381,  381,   77,   78,
-       79,  381,  381,  381,   77,   78,   79,  381,  381,   77,
-       78,   79,   46,   46,   46,   46,   46,   46,   46,   46,
+      253,   50,   72,   76,   76,   58,   58,   77,  364,   59,
+       64,   52,  253,  255,   65,  254,  350,   77,  198,  331,
+
+       53,   77,   72,   58,   58,   60,   60,   60,   60,   60,
+       60,   60,   81,   84,   78,   79,   80,   61,   62,   63,
+       67,  208,   61,   53,   78,   79,   80,  255,   78,   79,
+       80,  330,   77,   90,  139,   61,   62,   63,  302,   77,
+      198,  208,   61,  301,  300,  255,   85,   68,   69,   70,
+       56,  299,   71,   71,   71,   71,   71,   71,   71,   78,
+       79,   80,   72,   72,  298,   58,   78,   79,   80,   73,
+       73,  297,   72,   72,   74,  207,   75,   76,  208,   86,
+       72,   72,   87,   58,   66,  262,  139,  261,  260,   73,
+       73,   77,  198,   88,   91,  207,   72,   72,   74,   82,
+
+       82,   89,  208,   83,   83,   83,   83,   83,   83,   83,
+       91,   91,   91,   91,   91,   91,   91,   77,   78,   79,
+       80,   92,   93,   94,   95,   77,  209,   76,   77,   96,
+       97,  205,   77,   66,  204,   77,  203,  105,  139,  197,
+       98,   99,  193,  193,   78,   79,   80,  100,  383,  126,
+       77,  192,   78,   79,   80,   78,   79,   80,   77,   78,
+       79,   80,   78,   79,   80,   77,   91,  101,  106,   77,
+      149,  148,  107,   76,   77,  102,  383,   78,   79,   80,
+      103,  146,   77,  145,  108,   78,   79,   80,  113,   77,
+      112,  109,   78,   79,   80,  110,   78,   79,   80,  111,
+
+       77,   78,   79,   80,   77,   66,  135,  383,  129,   78,
+       79,   80,   77,  114,  122,  383,   78,   79,   80,  127,
+      126,  124,  207,  116,  115,  208,  123,   78,   79,   80,
+       91,   78,   79,   80,   77,  104,  383,  117,   55,   78,
+       79,   80,  207,  383,  118,   49,  119,   49,  120,  208,
+       47,  140,   47,  121,  131,  131,  131,  131,  131,  131,
+      383,   78,   79,   80,  133,  133,   77,  383,  134,  134,
+      134,  134,  134,  134,  134,  136,  136,  141,  132,  137,
+      137,  137,  137,  137,  137,  137,   66,   66,   66,   66,
+       66,   66,   66,   78,   79,   80,   76,   76,   76,   76,
+
+       76,  383,  383,  383,  142,  143,  144,   77,   76,   76,
+       77,  383,   76,  383,  155,  156,  383,  383,   77,  383,
+      383,  383,  383,   77,  151,  153,  152,  383,  150,  151,
+       76,  383,  383,   77,   78,   79,   80,   78,   79,   80,
+      154,   77,  151,  383,  152,   78,   79,   80,  157,  151,
+       78,   79,   80,  156,   77,   76,  158,   77,  383,  383,
+       78,   79,   80,  383,   77,  383,  383,   77,   78,   79,
+       80,   77,  383,  383,   77,  383,  159,  160,  383,  383,
+      383,   78,   79,   80,   78,   79,   80,  383,  161,   77,
+      383,   78,   79,   80,   78,   79,   80,   77,   78,   79,
+
+       80,   78,   79,   80,  165,  383,  383,  162,  383,  163,
+       77,  383,  164,   77,  383,  383,   78,   79,   80,  166,
+       77,  383,  169,   77,   78,   79,   80,  383,  199,  383,
+      167,   77,  383,  168,   77,  383,  170,   78,   79,   80,
+       78,   79,   80,   77,  172,  383,   77,   78,   79,   80,
+       78,   79,   80,   77,  171,  200,  201,  202,   78,   79,
+       80,   78,   79,   80,  173,   77,  383,  174,  175,   77,
+       78,   79,   80,   78,   79,   80,   77,  383,  383,   77,
+       78,   79,   80,   77,  176,  177,   77,  383,  383,   77,
+      178,  181,   78,   79,   80,  156,   78,   79,   80,  180,
+
+      179,  383,   77,   78,   79,   80,   78,   79,   80,   77,
+       78,   79,   80,   78,   79,   80,   78,   79,   80,   77,
+      184,  182,  383,   77,  183,  383,   77,  383,  383,   78,
+       79,   80,  383,  383,  383,  383,   78,   79,   80,  185,
+      383,  383,   77,  383,  383,   77,   78,   79,   80,  186,
+       78,   79,   80,   78,   79,   80,  187,   77,  383,  383,
+      188,  140,  383,   77,  383,  383,  190,  383,  383,   78,
+       79,   80,   78,   79,   80,  189,   77,  134,  134,  134,
+      134,  134,  134,  134,   78,   79,   80,  141,  383,  193,
+       78,   79,   80,  383,  191,  194,  194,  194,  194,  194,
+
+      194,  383,  383,   78,   79,   80,  134,  134,  134,  134,
+      134,  134,  134,  383,  142,  143,  144,  383,  196,  383,
+       63,  383,  383,  196,  137,  137,  137,  137,  137,  137,
+      137,  383,  383,  383,  383,  383,  196,   77,   63,  383,
+      210,   77,  383,  196,  137,  137,  137,  137,  137,  137,
+      137,  139,  139,  139,  139,  139,   61,  383,   63,   77,
+      383,   61,  383,  214,   78,   79,   80,  139,   78,   79,
+       80,   77,  383,  211,   61,  383,   63,   77,  383,  383,
+       77,   61,  383,  216,   77,  139,   78,   79,   80,   77,
+      383,  212,   77,  383,  213,  383,  215,  383,   78,   79,
+
+       80,   77,  383,  383,   78,   79,   80,   78,   79,   80,
+      139,   78,   79,   80,   77,  383,   78,   79,   80,   78,
+       79,   80,  217,  383,   77,  223,  220,   77,   78,   79,
+       80,  218,  219,   77,  383,  383,   77,  383,  383,  221,
+       77,   78,   79,   80,  383,   77,  383,  383,  383,  383,
+      383,   78,   79,   80,   78,   79,   80,  383,  222,   77,
+       78,   79,   80,   78,   79,   80,  224,   78,   79,   80,
+       77,  383,   78,   79,   80,   77,  383,  227,   77,  383,
+      383,  226,   77,  383,  229,  225,   78,   79,   80,   77,
+      383,  383,  383,   77,  228,  230,  231,   78,   79,   80,
+
+       77,  383,   78,   79,   80,   78,   79,   80,  383,   78,
+       79,   80,   77,  232,  233,   77,   78,   79,   80,   77,
+       78,   79,   80,  383,  383,  235,   77,   78,   79,   80,
+       77,  241,  383,   77,  237,  383,  234,  215,  238,   78,
+       79,   80,   78,   79,   80,   77,   78,   79,   80,   77,
+      240,  236,   77,   78,   79,   80,  239,   78,   79,   80,
+       78,   79,   80,   77,  383,  383,   77,  242,  383,   77,
+      383,  383,   78,   79,   80,  244,   78,   79,   80,   78,
+       79,   80,   77,  383,  243,   77,  245,  383,  383,   77,
+       78,   79,   80,   78,   79,   80,   78,   79,   80,  247,
+
+      140,  383,  246,  383,  249,   77,  383,  383,  383,   78,
+       79,   80,   78,   79,   80,  248,   78,   79,   80,   77,
+      251,  251,  251,  251,  251,  251,  256,  383,  383,  250,
+       77,  383,   78,   79,   80,  198,  198,  198,  198,  198,
+      198,  198,  263,   77,  383,  383,   78,   79,   80,   77,
+      383,  266,   77,  257,  258,  259,   77,   78,   79,   80,
+      267,   77,  383,  264,   77,  383,  265,   77,  383,  383,
+       78,   79,   80,  383,   77,  268,   78,   79,   80,   78,
+       79,   80,  383,   78,   79,   80,  269,   77,   78,   79,
+       80,   78,   79,   80,   78,   79,   80,  270,   77,  383,
+
+      383,   78,   79,   80,   77,  383,  383,   77,  383,  383,
+      271,   77,  383,  383,   78,   79,   80,  383,  383,   77,
+      273,  274,   77,  383,  272,   78,   79,   80,   77,  275,
+      383,   78,   79,   80,   78,   79,   80,  276,   78,   79,
+       80,   77,  278,  383,   77,  383,   78,   79,   80,   78,
+       79,   80,   77,  282,  383,   78,   79,   80,  383,  277,
+       77,  383,  383,   77,  383,  383,  279,   77,   78,   79,
+       80,   78,   79,   80,   77,  280,  383,   77,  383,   78,
+       79,   80,   77,  383,  383,   77,  383,   78,   79,   80,
+       78,   79,   80,  283,   78,   79,   80,  241,  281,   77,
+
+      383,   78,   79,   80,   78,   79,   80,  284,   77,   78,
+       79,   80,   78,   79,   80,  383,   77,  383,  383,  383,
+       77,  285,  383,   77,  383,  383,   78,   79,   80,  286,
+       77,  383,  383,   77,  288,   78,   79,   80,  383,  383,
+      383,  383,  383,   78,   79,   80,   77,   78,   79,   80,
+       78,   79,   80,  287,  140,  383,  291,   78,   79,   80,
+       78,   79,   80,   77,  383,  289,   77,  383,  383,  290,
+       77,  383,  383,   78,   79,   80,   77,  383,  293,  294,
+      256,  383,  292,   77,  383,  383,   77,  383,  296,  306,
+       78,   79,   80,   78,   79,   80,   77,   78,   79,   80,
+
+       77,  295,  303,   78,   79,   80,  383,  257,  258,  259,
+       78,   79,   80,   78,   79,   80,  255,  255,  255,  255,
+      255,  304,  383,   78,   79,   80,   77,   78,   79,   80,
+       77,  307,  255,   77,  383,  383,  305,   77,  383,  309,
+       77,  383,  383,   77,  308,  310,  383,  311,  383,   77,
+      255,  383,   77,   78,   79,   80,  312,   78,   79,   80,
+       78,   79,   80,  383,   78,   79,   80,   78,   79,   80,
+       78,   79,   80,   77,  383,  255,   78,   79,   80,   78,
+       79,   80,   77,  383,  313,  314,   77,  383,  383,   77,
+      383,  316,  383,  315,  383,  383,  383,  383,   77,  383,
+
+       78,   79,   80,   77,  383,  320,   77,  383,  383,   78,
+       79,   80,  319,   78,   79,   80,   78,   79,   80,  317,
+       77,  383,  318,   77,  383,   78,   79,   80,  306,   77,
+       78,   79,   80,   78,   79,   80,   77,  383,  383,   77,
+      383,  383,  321,   77,  324,  383,   77,   78,   79,   80,
+       78,   79,   80,  306,   77,  325,   78,   79,   80,   77,
+      322,  383,   77,   78,   79,   80,   78,   79,   80,   77,
+       78,   79,   80,   78,   79,   80,   77,  326,  383,  323,
+       77,   78,   79,   80,   77,  383,   78,   79,   80,   78,
+       79,   80,   77,  383,  327,   77,   78,   79,   80,   77,
+
+      383,  332,  329,   78,   79,   80,  333,   78,   79,   80,
+       77,   78,   79,   80,   77,  328,  383,   77,  383,   78,
+       79,   80,   78,   79,   80,  335,   78,   79,   80,   77,
+      336,  383,   77,  383,  334,   77,  383,   78,   79,   80,
+       77,   78,   79,   80,   78,   79,   80,   77,  383,  339,
+      383,  383,  337,   77,  338,  383,   78,   79,   80,   78,
+       79,   80,   78,   79,   80,   77,  383,   78,   79,   80,
+       77,  383,  383,  341,   78,   79,   80,  341,   77,  340,
+       78,   79,   80,   77,  383,  383,   77,  383,  383,  383,
+      342,  343,   78,   79,   80,   77,  383,   78,   79,   80,
+
+      344,   77,  383,  383,   77,   78,   79,   80,   77,  383,
+       78,   79,   80,   78,   79,   80,  383,   77,  345,  237,
+       77,  383,   78,   79,   80,   77,  383,  383,   78,   79,
+       80,   78,   79,   80,   77,   78,   79,   80,  346,   77,
+      347,  383,  383,   77,   78,   79,   80,   78,   79,   80,
+       77,  383,   78,   79,   80,  349,  383,  383,   77,  348,
+      383,   78,   79,   80,  351,  212,   78,   79,   80,   77,
+       78,   79,   80,   77,  383,  383,  353,   78,   79,   80,
+       77,  383,  383,  354,   77,   78,   79,   80,   77,  383,
+      355,   77,  352,  383,  356,   77,   78,   79,   80,   77,
+
+       78,   79,   80,  357,   77,  358,  383,   78,   79,   80,
+      341,   78,   79,   80,  383,   78,   79,   80,   78,   79,
+       80,   77,   78,   79,   80,   77,   78,   79,   80,   77,
+      359,   78,   79,   80,   77,  341,  360,   77,  383,  383,
+      362,   77,  383,  383,  383,   77,  383,  383,   78,   79,
+       80,  363,   78,   79,   80,  361,   78,   79,   80,  293,
+       77,   78,   79,   80,   78,   79,   80,  365,   78,   79,
+       80,   77,   78,   79,   80,  368,  383,  366,  212,   77,
+      383,  383,  383,   77,  383,  383,   77,   78,   79,   80,
+       77,  383,  369,  383,  383,   77,  383,  383,   78,   79,
+
+       80,  383,   77,  367,  383,   77,   78,   79,   80,  383,
+       78,   79,   80,   78,   79,   80,  370,   78,   79,   80,
+      371,   77,   78,   79,   80,  383,   77,  383,  383,   78,
+       79,   80,   78,   79,   80,  372,   77,  383,  383,   77,
+      383,  383,  359,   77,  366,  373,   77,  383,   78,   79,
+       80,   77,  383,   78,   79,   80,   77,  374,  383,  377,
+      383,  383,  375,   78,   79,   80,   78,   79,   80,   77,
+       78,   79,   80,   78,   79,   80,   77,  379,   78,   79,
+       80,   77,  341,   78,   79,   80,  383,   77,  376,  341,
+      383,  383,   77,  383,  383,   77,   78,   79,   80,   77,
+
+      383,  383,  383,   78,   79,   80,  378,   77,   78,   79,
+       80,  341,   77,  381,   78,   79,   80,  383,  341,   78,
+       79,   80,   78,   79,   80,  383,   78,   79,   80,  380,
+      383,   77,  383,  383,   78,   79,   80,   77,  383,   78,
+       79,   80,   77,  382,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  341,  383,  383,  383,   78,   79,
+       80,  383,  383,  383,   78,   79,   80,  383,  383,   78,
+       79,   80,   46,   46,   46,   46,   46,   46,   46,   46,
        46,   46,   46,   46,   46,   46,   48,   48,   48,   48,
        48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
 
        51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
        51,   51,   51,   51,   54,   54,   54,   54,   54,   54,
-       54,   54,   54,   54,   54,   54,   54,   54,   57,  381,
-       57,  381,   57,  381,   57,   66,  381,  381,   66,  381,
-       66,   66,   66,   66,   66,   75,   75,  381,   75,   75,
-       75,   75,   75,   75,  124,  124,  124,  124,  124,  124,
-      124,  124,  124,  124,  124,  124,  124,  124,  127,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-      127,  129,  381,  129,  129,  129,  129,  129,  129,  129,
-      129,  129,  129,  129,  129,  137,  381,  137,  137,  137,
-
-      137,  137,  137,  137,  137,  137,  137,  137,  137,  138,
-      138,  138,  138,  138,  138,  138,  138,  138,  146,  146,
-      146,  194,  381,  381,  381,  381,  194,  194,  194,  197,
-      197,  197,  197,  197,  205,  205,  205,  381,  381,  205,
-      250,  250,  250,  253,  253,  253,  253,  253,  253,  253,
-      253,  253,    7,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381
+       54,   54,   54,   54,   54,   54,   54,   54,   57,  383,
+       57,  383,   57,  383,   57,   66,  383,  383,   66,  383,
+       66,   66,   66,   66,   66,   76,   76,  383,   76,   76,
+       76,   76,   76,   76,  125,  125,  125,  125,  125,  125,
+      125,  125,  125,  125,  125,  125,  125,  125,  128,  128,
+      128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+      128,  130,  383,  130,  130,  130,  130,  130,  130,  130,
+      130,  130,  130,  130,  130,  138,  383,  138,  138,  138,
+
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  147,  147,
+      147,  195,  383,  383,  383,  383,  195,  195,  195,  198,
+      198,  198,  198,  198,  206,  206,  206,  383,  383,  206,
+      252,  252,  252,  255,  255,  255,  255,  255,  255,  255,
+      255,  255,    7,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
+
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383
     } ;
 
 static yyconst flex_int16_t yy_chk[2221] =
@@ -830,242 +833,242 @@ static yyconst flex_int16_t yy_chk[2221] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    9,   11,    9,
        13,   14,   13,   13,   13,   13,   13,   13,   13,   50,
-      362,   50,   81,   81,  348,   13,   14,   19,  329,   14,
-       16,   51,  196,  328,   16,  196,  300,   20,  299,  298,
+      364,   50,   73,   82,   82,   13,   14,   19,  350,   14,
+       16,   51,  197,  331,   16,  197,  330,   20,  302,  301,
 
-       11,   22,  297,   13,   14,   15,   15,   15,   15,   15,
+       11,   22,   73,   13,   14,   15,   15,   15,   15,   15,
        15,   15,   20,   22,   19,   19,   19,   15,   15,   15,
-       16,  260,   15,   51,   20,   20,   20,  259,   22,   22,
-       22,  258,   23,   25,  257,   15,   15,   15,  256,   25,
-      255,  252,   15,  250,  249,  207,   23,   16,   16,   16,
-       17,  204,   17,   17,   17,   17,   17,   17,   17,   23,
-       23,   23,   17,   73,  203,   17,   25,   25,   25,   17,
-       73,  202,   17,   73,   17,  146,   17,  201,  146,   24,
-       17,   73,   24,   17,  200,  199,  191,  148,  147,   17,
-       73,   24,  145,   24,  144,  146,   17,   73,   17,   21,
-
-       21,   24,  146,   21,   21,   21,   21,   21,   21,   21,
+       16,  207,   15,   51,   20,   20,   20,  300,   22,   22,
+       22,  299,   23,   25,  262,   15,   15,   15,  261,   25,
+      260,  207,   15,  259,  258,  257,   23,   16,   16,   16,
+       17,  254,   17,   17,   17,   17,   17,   17,   17,   23,
+       23,   23,   17,   74,  252,   17,   25,   25,   25,   17,
+       74,  251,   17,   74,   17,  147,   17,  209,  147,   24,
+       17,   74,   24,   17,  205,  204,  203,  202,  201,   17,
+       74,   24,  200,   24,  192,  147,   17,   74,   17,   21,
+
+       21,   24,  147,   21,   21,   21,   21,   21,   21,   21,
        26,   26,   26,   26,   26,   26,   26,   28,   24,   24,
-       24,   27,   27,   27,   27,   32,  143,  142,   21,   27,
-       27,  141,   29,  134,  131,   27,  129,   32,  125,  124,
-       28,   29,  123,  122,   28,   28,   28,   29,   79,   78,
-       33,   77,   32,   32,   32,   21,   21,   21,   34,   29,
-       29,   29,   27,   27,   27,   30,   71,   30,   33,   35,
-       70,   69,   34,   68,   37,   30,   59,   33,   33,   33,
-       30,   57,   38,   54,   35,   34,   34,   34,   38,   36,
+       24,   27,   27,   27,   27,   32,  149,  148,   21,   27,
+       27,  146,   29,  145,  144,   27,  143,   32,  142,  135,
+       28,   29,  132,  130,   28,   28,   28,   29,  126,  125,
+       33,  124,   32,   32,   32,   21,   21,   21,   34,   29,
+       29,   29,   27,   27,   27,   30,  123,   30,   33,   35,
+       80,   79,   34,   78,   37,   30,   71,   33,   33,   33,
+       30,   70,   38,   69,   35,   34,   34,   34,   38,   36,
        37,   36,   30,   30,   30,   36,   35,   35,   35,   36,
 
-       40,   37,   37,   37,   39,   53,   47,   46,   45,   38,
-       38,   38,   42,   39,   42,   44,   36,   36,   36,   43,
-       31,   18,  205,   40,   39,  205,   12,   40,   40,   40,
-        7,   39,   39,   39,   41,    6,    5,   41,    4,   42,
-       42,   42,  205,    3,   41,    0,   41,    0,   41,  205,
-        0,   66,    0,   41,   55,   55,   55,   55,   55,   55,
-        0,   41,   41,   41,   58,   58,   75,    0,   58,   58,
+       40,   37,   37,   37,   39,   68,   59,   57,   54,   38,
+       38,   38,   42,   39,   42,   53,   36,   36,   36,   47,
+       46,   45,  206,   40,   39,  206,   44,   40,   40,   40,
+       43,   39,   39,   39,   41,   31,   18,   41,   12,   42,
+       42,   42,  206,    7,   41,    6,   41,    5,   41,  206,
+        4,   66,    3,   41,   55,   55,   55,   55,   55,   55,
+        0,   41,   41,   41,   58,   58,   76,    0,   58,   58,
        58,   58,   58,   58,   58,   62,   62,   66,   55,   62,
        62,   62,   62,   62,   62,   62,   67,   67,   67,   67,
-       67,   67,   67,   75,   75,   75,   76,   76,   76,   76,
-
-       76,    0,    0,    0,   66,   66,   66,   80,   82,   82,
-       83,    0,   76,    0,   85,   86,    0,    0,   85,    0,
-        0,    0,    0,   86,   82,   83,   82,    0,   80,   82,
-       76,    0,    0,   84,   80,   80,   80,   83,   83,   83,
-       84,   88,   82,    0,   82,   85,   85,   85,   87,   82,
-       86,   86,   86,   88,   87,   76,   89,   90,    0,    0,
-       84,   84,   84,    0,   89,    0,    0,   91,   88,   88,
-       88,   92,    0,    0,   93,    0,   91,   92,    0,    0,
-        0,   87,   87,   87,   90,   90,   90,    0,   93,   95,
-        0,   89,   89,   89,   91,   91,   91,   94,   92,   92,
-
-       92,   93,   93,   93,   95,    0,    0,   94,    0,   94,
-       96,    0,   94,   97,    0,    0,   95,   95,   95,   96,
-       98,    0,   98,   99,   94,   94,   94,    0,  139,    0,
-       96,  101,    0,   97,  100,    0,   99,   96,   96,   96,
-       97,   97,   97,  102,  101,    0,  103,   98,   98,   98,
-       99,   99,   99,  104,  100,  139,  139,  139,  101,  101,
-      101,  100,  100,  100,  102,  106,    0,  103,  104,  105,
-      102,  102,  102,  103,  103,  103,  107,    0,    0,  109,
-      104,  104,  104,  110,  105,  106,  108,    0,    0,  111,
-      107,  111,  106,  106,  106,  110,  105,  105,  105,  109,
-
-      108,    0,  114,  107,  107,  107,  109,  109,  109,  113,
-      110,  110,  110,  108,  108,  108,  111,  111,  111,  112,
-      114,  112,    0,  115,  113,    0,  116,    0,    0,  114,
-      114,  114,    0,    0,    0,    0,  113,  113,  113,  115,
-        0,    0,  117,    0,    0,  118,  112,  112,  112,  116,
-      115,  115,  115,  116,  116,  116,  117,  120,    0,    0,
-      118,  138,    0,  119,    0,    0,  120,    0,    0,  117,
-      117,  117,  118,  118,  118,  119,  121,  132,  132,  132,
-      132,  132,  132,  132,  120,  120,  120,  138,    0,  130,
-      119,  119,  119,    0,  121,  130,  130,  130,  130,  130,
-
-      130,    0,    0,  121,  121,  121,  133,  133,  133,  133,
-      133,  133,  133,    0,  138,  138,  138,    0,  133,    0,
-      133,    0,    0,  133,  135,  135,  135,  135,  135,  135,
-      135,    0,    0,    0,    0,    0,  133,  149,  133,    0,
-      149,  150,    0,  133,  136,  136,  136,  136,  136,  136,
-      136,  140,  140,  140,  140,  140,  136,    0,  136,  151,
-        0,  136,    0,  154,  149,  149,  149,  140,  150,  150,
-      150,  152,    0,  152,  136,    0,  136,  154,    0,    0,
-      155,  136,    0,  157,  153,  140,  151,  151,  151,  156,
-        0,  153,  157,    0,  153,    0,  156,    0,  152,  152,
-
-      152,  158,    0,    0,  154,  154,  154,  155,  155,  155,
-      140,  153,  153,  153,  161,    0,  156,  156,  156,  157,
-      157,  157,  158,    0,  159,  164,  161,  160,  158,  158,
-      158,  159,  160,  162,    0,    0,  164,    0,    0,  162,
-      163,  161,  161,  161,    0,  165,    0,    0,    0,    0,
-        0,  159,  159,  159,  160,  160,  160,    0,  163,  168,
-      162,  162,  162,  164,  164,  164,  165,  163,  163,  163,
-      166,    0,  165,  165,  165,  167,    0,  168,  169,    0,
-        0,  167,  170,    0,  170,  166,  168,  168,  168,  171,
-        0,    0,    0,  172,  169,  171,  172,  166,  166,  166,
-
-      173,    0,  167,  167,  167,  169,  169,  169,    0,  170,
-      170,  170,  174,  173,  174,  175,  171,  171,  171,  181,
-      172,  172,  172,    0,    0,  176,  177,  173,  173,  173,
-      178,  181,    0,  180,  177,    0,  175,  178,  179,  174,
-      174,  174,  175,  175,  175,  176,  181,  181,  181,  182,
-      180,  176,  179,  177,  177,  177,  179,  178,  178,  178,
-      180,  180,  180,  183,    0,    0,  185,  182,    0,  184,
-        0,    0,  176,  176,  176,  184,  182,  182,  182,  179,
-      179,  179,  186,    0,  183,  187,  185,    0,    0,  189,
-      183,  183,  183,  185,  185,  185,  184,  184,  184,  187,
-
-      197,    0,  186,    0,  189,  188,    0,    0,    0,  186,
-      186,  186,  187,  187,  187,  188,  189,  189,  189,  190,
-      193,  193,  193,  193,  193,  193,  197,    0,    0,  190,
-      208,    0,  188,  188,  188,  198,  198,  198,  198,  198,
-      198,  198,  208,  209,    0,    0,  190,  190,  190,  210,
-        0,  212,  211,  197,  197,  197,  213,  208,  208,  208,
-      214,  215,    0,  209,  212,    0,  211,  214,    0,    0,
-      209,  209,  209,    0,  216,  215,  210,  210,  210,  211,
-      211,  211,    0,  213,  213,  213,  216,  217,  215,  215,
-      215,  212,  212,  212,  214,  214,  214,  217,  218,    0,
-
-        0,  216,  216,  216,  219,    0,    0,  220,    0,    0,
-      218,  221,    0,    0,  217,  217,  217,    0,    0,  223,
-      220,  221,  222,    0,  219,  218,  218,  218,  224,  222,
-        0,  219,  219,  219,  220,  220,  220,  223,  221,  221,
-      221,  225,  227,    0,  226,    0,  223,  223,  223,  222,
-      222,  222,  228,  233,    0,  224,  224,  224,    0,  226,
-      227,    0,    0,  229,    0,    0,  228,  230,  225,  225,
-      225,  226,  226,  226,  233,  229,    0,  231,    0,  228,
-      228,  228,  232,    0,    0,  234,    0,  227,  227,  227,
-      229,  229,  229,  234,  230,  230,  230,  231,  232,  235,
-
-        0,  233,  233,  233,  231,  231,  231,  236,  238,  232,
-      232,  232,  234,  234,  234,    0,  237,    0,    0,    0,
-      236,  237,    0,  239,    0,    0,  235,  235,  235,  238,
-      241,    0,    0,  240,  241,  238,  238,  238,    0,    0,
-        0,    0,    0,  237,  237,  237,  242,  236,  236,  236,
-      239,  239,  239,  240,  253,    0,  244,  241,  241,  241,
-      240,  240,  240,  243,    0,  242,  246,    0,    0,  243,
-      245,    0,    0,  242,  242,  242,  244,    0,  245,  246,
-      253,    0,  244,  247,    0,    0,  248,    0,  248,  264,
-      243,  243,  243,  246,  246,  246,  261,  245,  245,  245,
-
-      264,  247,  261,  244,  244,  244,    0,  253,  253,  253,
-      247,  247,  247,  248,  248,  248,  254,  254,  254,  254,
-      254,  262,    0,  261,  261,  261,  263,  264,  264,  264,
-      262,  265,  254,  266,    0,    0,  263,  267,    0,  267,
-      265,    0,    0,  268,  266,  268,    0,  269,    0,  269,
-      254,    0,  270,  263,  263,  263,  270,  262,  262,  262,
-      266,  266,  266,    0,  267,  267,  267,  265,  265,  265,
-      268,  268,  268,  272,    0,  254,  269,  269,  269,  270,
-      270,  270,  271,    0,  271,  272,  273,    0,    0,  274,
-        0,  274,    0,  273,    0,    0,    0,    0,  275,    0,
-
-      272,  272,  272,  277,    0,  279,  278,    0,    0,  271,
-      271,  271,  278,  273,  273,  273,  274,  274,  274,  275,
-      280,    0,  277,  279,    0,  275,  275,  275,  282,  285,
-      277,  277,  277,  278,  278,  278,  281,    0,    0,  282,
-        0,    0,  281,  288,  287,    0,  283,  280,  280,  280,
-      279,  279,  279,  283,  284,  289,  285,  285,  285,  286,
-      284,    0,  287,  281,  281,  281,  282,  282,  282,  290,
-      288,  288,  288,  283,  283,  283,  289,  290,    0,  286,
-      291,  284,  284,  284,  292,    0,  286,  286,  286,  287,
-      287,  287,  302,    0,  292,  293,  290,  290,  290,  294,
-
-        0,  301,  294,  289,  289,  289,  302,  291,  291,  291,
-      301,  292,  292,  292,  303,  293,    0,  304,    0,  302,
-      302,  302,  293,  293,  293,  305,  294,  294,  294,  305,
-      306,    0,  307,    0,  303,  306,    0,  301,  301,  301,
-      308,  303,  303,  303,  304,  304,  304,  309,    0,  309,
-        0,    0,  307,  311,  308,    0,  305,  305,  305,  307,
-      307,  307,  306,  306,  306,  312,    0,  308,  308,  308,
-      310,    0,    0,  311,  309,  309,  309,  312,  313,  310,
-      311,  311,  311,  314,    0,    0,  315,    0,    0,    0,
-      313,  314,  312,  312,  312,  317,    0,  310,  310,  310,
-
-      315,  319,    0,    0,  320,  313,  313,  313,  316,    0,
-      314,  314,  314,  315,  315,  315,    0,  321,  316,  319,
-      323,    0,  317,  317,  317,  326,    0,    0,  319,  319,
-      319,  320,  320,  320,  324,  316,  316,  316,  321,  325,
-      324,    0,    0,  327,  321,  321,  321,  323,  323,  323,
-      330,    0,  326,  326,  326,  327,    0,    0,  331,  325,
-        0,  324,  324,  324,  330,  331,  325,  325,  325,  332,
-      327,  327,  327,  334,    0,    0,  333,  330,  330,  330,
-      336,    0,    0,  334,  335,  331,  331,  331,  333,    0,
-      335,  337,  332,    0,  336,  339,  332,  332,  332,  338,
-
-      334,  334,  334,  337,  340,  338,    0,  336,  336,  336,
-      340,  335,  335,  335,    0,  333,  333,  333,  337,  337,
-      337,  343,  339,  339,  339,  342,  338,  338,  338,  341,
-      342,  340,  340,  340,  346,  341,  343,  344,    0,    0,
-      346,  345,    0,    0,    0,  347,    0,    0,  343,  343,
-      343,  347,  342,  342,  342,  344,  341,  341,  341,  345,
-      349,  346,  346,  346,  344,  344,  344,  349,  345,  345,
-      345,  350,  347,  347,  347,  353,    0,  351,  350,  352,
-        0,    0,    0,  353,    0,    0,  354,  349,  349,  349,
-      351,    0,  354,    0,    0,  355,    0,    0,  350,  350,
-
-      350,    0,  356,  352,    0,  357,  352,  352,  352,    0,
-      353,  353,  353,  354,  354,  354,  355,  351,  351,  351,
-      356,  358,  355,  355,  355,    0,  361,    0,    0,  356,
-      356,  356,  357,  357,  357,  358,  359,    0,    0,  360,
-        0,    0,  359,  363,  360,  361,  364,    0,  358,  358,
-      358,  365,    0,  361,  361,  361,  366,  365,    0,  369,
-        0,    0,  366,  359,  359,  359,  360,  360,  360,  367,
-      363,  363,  363,  364,  364,  364,  368,  371,  365,  365,
-      365,  369,  368,  366,  366,  366,    0,  370,  367,  375,
-        0,    0,  372,    0,    0,  371,  367,  367,  367,  374,
-
-        0,    0,    0,  368,  368,  368,  370,  373,  369,  369,
-      369,  372,  375,  376,  370,  370,  370,    0,  374,  372,
-      372,  372,  371,  371,  371,    0,  374,  374,  374,  373,
-        0,  376,    0,    0,  373,  373,  373,  378,    0,  375,
-      375,  375,  380,  378,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,  380,    0,    0,    0,  376,  376,
-      376,    0,    0,    0,  378,  378,  378,    0,    0,  380,
-      380,  380,  382,  382,  382,  382,  382,  382,  382,  382,
-      382,  382,  382,  382,  382,  382,  383,  383,  383,  383,
+       67,   67,   67,   76,   76,   76,   77,   77,   77,   77,
+
+       77,    0,    0,    0,   66,   66,   66,   81,   83,   83,
+       84,    0,   77,    0,   86,   87,    0,    0,   86,    0,
+        0,    0,    0,   87,   83,   84,   83,    0,   81,   83,
+       77,    0,    0,   85,   81,   81,   81,   84,   84,   84,
+       85,   89,   83,    0,   83,   86,   86,   86,   88,   83,
+       87,   87,   87,   89,   88,   77,   90,   91,    0,    0,
+       85,   85,   85,    0,   90,    0,    0,   92,   89,   89,
+       89,   93,    0,    0,   94,    0,   92,   93,    0,    0,
+        0,   88,   88,   88,   91,   91,   91,    0,   94,   96,
+        0,   90,   90,   90,   92,   92,   92,   95,   93,   93,
+
+       93,   94,   94,   94,   96,    0,    0,   95,    0,   95,
+       97,    0,   95,   98,    0,    0,   96,   96,   96,   97,
+       99,    0,   99,  100,   95,   95,   95,    0,  140,    0,
+       97,  102,    0,   98,  101,    0,  100,   97,   97,   97,
+       98,   98,   98,  103,  102,    0,  104,   99,   99,   99,
+      100,  100,  100,  105,  101,  140,  140,  140,  102,  102,
+      102,  101,  101,  101,  103,  107,    0,  104,  105,  106,
+      103,  103,  103,  104,  104,  104,  108,    0,    0,  110,
+      105,  105,  105,  111,  106,  107,  109,    0,    0,  112,
+      108,  112,  107,  107,  107,  111,  106,  106,  106,  110,
+
+      109,    0,  115,  108,  108,  108,  110,  110,  110,  114,
+      111,  111,  111,  109,  109,  109,  112,  112,  112,  113,
+      115,  113,    0,  116,  114,    0,  117,    0,    0,  115,
+      115,  115,    0,    0,    0,    0,  114,  114,  114,  116,
+        0,    0,  118,    0,    0,  119,  113,  113,  113,  117,
+      116,  116,  116,  117,  117,  117,  118,  121,    0,    0,
+      119,  139,    0,  120,    0,    0,  121,    0,    0,  118,
+      118,  118,  119,  119,  119,  120,  122,  133,  133,  133,
+      133,  133,  133,  133,  121,  121,  121,  139,    0,  131,
+      120,  120,  120,    0,  122,  131,  131,  131,  131,  131,
+
+      131,    0,    0,  122,  122,  122,  134,  134,  134,  134,
+      134,  134,  134,    0,  139,  139,  139,    0,  134,    0,
+      134,    0,    0,  134,  136,  136,  136,  136,  136,  136,
+      136,    0,    0,    0,    0,    0,  134,  150,  134,    0,
+      150,  151,    0,  134,  137,  137,  137,  137,  137,  137,
+      137,  141,  141,  141,  141,  141,  137,    0,  137,  152,
+        0,  137,    0,  155,  150,  150,  150,  141,  151,  151,
+      151,  153,    0,  153,  137,    0,  137,  155,    0,    0,
+      156,  137,    0,  158,  154,  141,  152,  152,  152,  157,
+        0,  154,  158,    0,  154,    0,  157,    0,  153,  153,
+
+      153,  159,    0,    0,  155,  155,  155,  156,  156,  156,
+      141,  154,  154,  154,  162,    0,  157,  157,  157,  158,
+      158,  158,  159,    0,  160,  165,  162,  161,  159,  159,
+      159,  160,  161,  163,    0,    0,  165,    0,    0,  163,
+      164,  162,  162,  162,    0,  166,    0,    0,    0,    0,
+        0,  160,  160,  160,  161,  161,  161,    0,  164,  169,
+      163,  163,  163,  165,  165,  165,  166,  164,  164,  164,
+      167,    0,  166,  166,  166,  168,    0,  169,  170,    0,
+        0,  168,  171,    0,  171,  167,  169,  169,  169,  172,
+        0,    0,    0,  173,  170,  172,  173,  167,  167,  167,
+
+      174,    0,  168,  168,  168,  170,  170,  170,    0,  171,
+      171,  171,  175,  174,  175,  176,  172,  172,  172,  182,
+      173,  173,  173,    0,    0,  177,  178,  174,  174,  174,
+      179,  182,    0,  181,  178,    0,  176,  179,  180,  175,
+      175,  175,  176,  176,  176,  177,  182,  182,  182,  183,
+      181,  177,  180,  178,  178,  178,  180,  179,  179,  179,
+      181,  181,  181,  184,    0,    0,  186,  183,    0,  185,
+        0,    0,  177,  177,  177,  185,  183,  183,  183,  180,
+      180,  180,  187,    0,  184,  188,  186,    0,    0,  190,
+      184,  184,  184,  186,  186,  186,  185,  185,  185,  188,
+
+      198,    0,  187,    0,  190,  189,    0,    0,    0,  187,
+      187,  187,  188,  188,  188,  189,  190,  190,  190,  191,
+      194,  194,  194,  194,  194,  194,  198,    0,    0,  191,
+      210,    0,  189,  189,  189,  199,  199,  199,  199,  199,
+      199,  199,  210,  211,    0,    0,  191,  191,  191,  212,
+        0,  214,  213,  198,  198,  198,  215,  210,  210,  210,
+      216,  217,    0,  211,  214,    0,  213,  216,    0,    0,
+      211,  211,  211,    0,  218,  217,  212,  212,  212,  213,
+      213,  213,    0,  215,  215,  215,  218,  219,  217,  217,
+      217,  214,  214,  214,  216,  216,  216,  219,  220,    0,
+
+        0,  218,  218,  218,  221,    0,    0,  222,    0,    0,
+      220,  223,    0,    0,  219,  219,  219,    0,    0,  225,
+      222,  223,  224,    0,  221,  220,  220,  220,  226,  224,
+        0,  221,  221,  221,  222,  222,  222,  225,  223,  223,
+      223,  227,  229,    0,  228,    0,  225,  225,  225,  224,
+      224,  224,  230,  235,    0,  226,  226,  226,    0,  228,
+      229,    0,    0,  231,    0,    0,  230,  232,  227,  227,
+      227,  228,  228,  228,  235,  231,    0,  233,    0,  230,
+      230,  230,  234,    0,    0,  236,    0,  229,  229,  229,
+      231,  231,  231,  236,  232,  232,  232,  233,  234,  237,
+
+        0,  235,  235,  235,  233,  233,  233,  238,  240,  234,
+      234,  234,  236,  236,  236,    0,  239,    0,    0,    0,
+      238,  239,    0,  241,    0,    0,  237,  237,  237,  240,
+      243,    0,    0,  242,  243,  240,  240,  240,    0,    0,
+        0,    0,    0,  239,  239,  239,  244,  238,  238,  238,
+      241,  241,  241,  242,  255,    0,  246,  243,  243,  243,
+      242,  242,  242,  245,    0,  244,  248,    0,    0,  245,
+      247,    0,    0,  244,  244,  244,  246,    0,  247,  248,
+      255,    0,  246,  249,    0,    0,  250,    0,  250,  266,
+      245,  245,  245,  248,  248,  248,  263,  247,  247,  247,
+
+      266,  249,  263,  246,  246,  246,    0,  255,  255,  255,
+      249,  249,  249,  250,  250,  250,  256,  256,  256,  256,
+      256,  264,    0,  263,  263,  263,  265,  266,  266,  266,
+      264,  267,  256,  268,    0,    0,  265,  269,    0,  269,
+      267,    0,    0,  270,  268,  270,    0,  271,    0,  271,
+      256,    0,  272,  265,  265,  265,  272,  264,  264,  264,
+      268,  268,  268,    0,  269,  269,  269,  267,  267,  267,
+      270,  270,  270,  274,    0,  256,  271,  271,  271,  272,
+      272,  272,  273,    0,  273,  274,  275,    0,    0,  276,
+        0,  276,    0,  275,    0,    0,    0,    0,  277,    0,
+
+      274,  274,  274,  279,    0,  281,  280,    0,    0,  273,
+      273,  273,  280,  275,  275,  275,  276,  276,  276,  277,
+      282,    0,  279,  281,    0,  277,  277,  277,  284,  287,
+      279,  279,  279,  280,  280,  280,  283,    0,    0,  284,
+        0,    0,  283,  290,  289,    0,  285,  282,  282,  282,
+      281,  281,  281,  285,  286,  291,  287,  287,  287,  288,
+      286,    0,  289,  283,  283,  283,  284,  284,  284,  292,
+      290,  290,  290,  285,  285,  285,  291,  292,    0,  288,
+      293,  286,  286,  286,  294,    0,  288,  288,  288,  289,
+      289,  289,  304,    0,  294,  295,  292,  292,  292,  296,
+
+        0,  303,  296,  291,  291,  291,  304,  293,  293,  293,
+      303,  294,  294,  294,  305,  295,    0,  306,    0,  304,
+      304,  304,  295,  295,  295,  307,  296,  296,  296,  307,
+      308,    0,  309,    0,  305,  308,    0,  303,  303,  303,
+      310,  305,  305,  305,  306,  306,  306,  311,    0,  311,
+        0,    0,  309,  313,  310,    0,  307,  307,  307,  309,
+      309,  309,  308,  308,  308,  314,    0,  310,  310,  310,
+      312,    0,    0,  313,  311,  311,  311,  314,  315,  312,
+      313,  313,  313,  316,    0,    0,  317,    0,    0,    0,
+      315,  316,  314,  314,  314,  319,    0,  312,  312,  312,
+
+      317,  321,    0,    0,  322,  315,  315,  315,  318,    0,
+      316,  316,  316,  317,  317,  317,    0,  323,  318,  321,
+      325,    0,  319,  319,  319,  328,    0,    0,  321,  321,
+      321,  322,  322,  322,  326,  318,  318,  318,  323,  327,
+      326,    0,    0,  329,  323,  323,  323,  325,  325,  325,
+      332,    0,  328,  328,  328,  329,    0,    0,  333,  327,
+        0,  326,  326,  326,  332,  333,  327,  327,  327,  334,
+      329,  329,  329,  336,    0,    0,  335,  332,  332,  332,
+      338,    0,    0,  336,  337,  333,  333,  333,  335,    0,
+      337,  339,  334,    0,  338,  341,  334,  334,  334,  340,
+
+      336,  336,  336,  339,  342,  340,    0,  338,  338,  338,
+      342,  337,  337,  337,    0,  335,  335,  335,  339,  339,
+      339,  345,  341,  341,  341,  344,  340,  340,  340,  343,
+      344,  342,  342,  342,  348,  343,  345,  346,    0,    0,
+      348,  347,    0,    0,    0,  349,    0,    0,  345,  345,
+      345,  349,  344,  344,  344,  346,  343,  343,  343,  347,
+      351,  348,  348,  348,  346,  346,  346,  351,  347,  347,
+      347,  352,  349,  349,  349,  355,    0,  353,  352,  354,
+        0,    0,    0,  355,    0,    0,  356,  351,  351,  351,
+      353,    0,  356,    0,    0,  357,    0,    0,  352,  352,
+
+      352,    0,  358,  354,    0,  359,  354,  354,  354,    0,
+      355,  355,  355,  356,  356,  356,  357,  353,  353,  353,
+      358,  360,  357,  357,  357,    0,  363,    0,    0,  358,
+      358,  358,  359,  359,  359,  360,  361,    0,    0,  362,
+        0,    0,  361,  365,  362,  363,  366,    0,  360,  360,
+      360,  367,    0,  363,  363,  363,  368,  367,    0,  371,
+        0,    0,  368,  361,  361,  361,  362,  362,  362,  369,
+      365,  365,  365,  366,  366,  366,  370,  373,  367,  367,
+      367,  371,  370,  368,  368,  368,    0,  372,  369,  377,
+        0,    0,  374,    0,    0,  373,  369,  369,  369,  376,
+
+        0,    0,    0,  370,  370,  370,  372,  375,  371,  371,
+      371,  374,  377,  378,  372,  372,  372,    0,  376,  374,
+      374,  374,  373,  373,  373,    0,  376,  376,  376,  375,
+        0,  378,    0,    0,  375,  375,  375,  380,    0,  377,
+      377,  377,  382,  380,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  382,    0,    0,    0,  378,  378,
+      378,    0,    0,    0,  380,  380,  380,    0,    0,  382,
+      382,  382,  384,  384,  384,  384,  384,  384,  384,  384,
+      384,  384,  384,  384,  384,  384,  385,  385,  385,  385,
+      385,  385,  385,  385,  385,  385,  385,  385,  385,  385,
+
+      386,  386,  386,  386,  386,  386,  386,  386,  386,  386,
+      386,  386,  386,  386,  387,  387,  387,  387,  387,  387,
+      387,  387,  387,  387,  387,  387,  387,  387,  388,    0,
+      388,    0,  388,    0,  388,  389,    0,    0,  389,    0,
+      389,  389,  389,  389,  389,  390,  390,    0,  390,  390,
+      390,  390,  390,  390,  391,  391,  391,  391,  391,  391,
+      391,  391,  391,  391,  391,  391,  391,  391,  392,  392,
+      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
+      392,  393,    0,  393,  393,  393,  393,  393,  393,  393,
+      393,  393,  393,  393,  393,  394,    0,  394,  394,  394,
+
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  395,
+      395,  395,  395,  395,  395,  395,  395,  395,  396,  396,
+      396,  397,    0,    0,    0,    0,  397,  397,  397,  398,
+      398,  398,  398,  398,  399,  399,  399,    0,    0,  399,
+      400,  400,  400,  401,  401,  401,  401,  401,  401,  401,
+      401,  401,  383,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
       383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
 
-      384,  384,  384,  384,  384,  384,  384,  384,  384,  384,
-      384,  384,  384,  384,  385,  385,  385,  385,  385,  385,
-      385,  385,  385,  385,  385,  385,  385,  385,  386,    0,
-      386,    0,  386,    0,  386,  387,    0,    0,  387,    0,
-      387,  387,  387,  387,  387,  388,  388,    0,  388,  388,
-      388,  388,  388,  388,  389,  389,  389,  389,  389,  389,
-      389,  389,  389,  389,  389,  389,  389,  389,  390,  390,
-      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
-      390,  391,    0,  391,  391,  391,  391,  391,  391,  391,
-      391,  391,  391,  391,  391,  392,    0,  392,  392,  392,
-
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  393,
-      393,  393,  393,  393,  393,  393,  393,  393,  394,  394,
-      394,  395,    0,    0,    0,    0,  395,  395,  395,  396,
-      396,  396,  396,  396,  397,  397,  397,    0,    0,  397,
-      398,  398,  398,  399,  399,  399,  399,  399,  399,  399,
-      399,  399,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381,
-      381,  381,  381,  381,  381,  381,  381,  381,  381,  381
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,
+      383,  383,  383,  383,  383,  383,  383,  383,  383,  383
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -1158,13 +1161,17 @@ static unsigned int MAX_UINT = NC_MAX_UINT;
 #define NC_MAX_UINT MAX_UINT
 #endif
 
-#define TAG "BbSsLl"
+#define TAGCHARS "BbSsLlUu"
 
 #define tstdecimal(ch) ((ch) >= '0' && (ch) <= '9')
 
 /*Mnemonics*/
 #define ISIDENT 1
 
+/* Define a fake constant indicating that
+   no tag was specified */
+#define NC_NOTAG (-1)
+
 char errstr[100];		/* for short error messages */
 
 int lineno;              /* line number for error messages */
@@ -1191,9 +1198,10 @@ unsigned char ubyte_val;       /* last byte value read */
 static Symbol* makepath(char* text);
 static int lexdebug(int);
 static unsigned long long parseULL(char* text, int*);
-static nc_type downconvert(unsigned long long uint64, int, int, int);
-static int tagmatch(nc_type nct, int tag, int hasU);
+static nc_type downconvert(unsigned long long uint64, int*, int, int);
+static int tagmatch(nc_type nct, int tag);
 static int nct2lexeme(nc_type nct);
+static int collecttag(char* text, char** stagp);
 
 static struct Specialtoken {
     char* name;
@@ -1254,7 +1262,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 1258 "ncgenyy.c"
+#line 1266 "lex.ncg.c"
 
 #define INITIAL 0
 #define ST_C_COMMENT 1
@@ -1295,7 +1303,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 );
 
@@ -1345,7 +1353,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( ncgtext, ncgleng, 1, ncgout )) {} } while (0)
+#define ECHO fwrite( ncgtext, ncgleng, 1, ncgout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -1356,7 +1364,7 @@ static int input (void );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		unsigned n; \
+		yy_size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( ncgin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -1438,9 +1446,9 @@ YY_DECL
 	register char *yy_cp, *yy_bp;
 	register int yy_act;
     
-#line 208 "ncgen.l"
+#line 213 "ncgen.l"
 
-#line 1444 "ncgenyy.c"
+#line 1452 "lex.ncg.c"
 
 	if ( !(yy_init) )
 		{
@@ -1493,22 +1501,18 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 382 )
+				if ( yy_current_state >= 384 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 2153 );
+		while ( yy_current_state != 383 );
+		yy_cp = (yy_last_accepting_cpos);
+		yy_current_state = (yy_last_accepting_state);
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
-		if ( yy_act == 0 )
-			{ /* have to back up */
-			yy_cp = (yy_last_accepting_cpos);
-			yy_current_state = (yy_last_accepting_state);
-			yy_act = yy_accept[yy_current_state];
-			}
 
 		YY_DO_BEFORE_ACTION;
 
@@ -1525,14 +1529,14 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 209 "ncgen.l"
+#line 214 "ncgen.l"
 { /* whitespace */
 		  break;
 		}
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 213 "ncgen.l"
+#line 218 "ncgen.l"
 { /* comment */
                           break;
                         }
@@ -1540,7 +1544,7 @@ YY_RULE_SETUP
 case 3:
 /* rule 3 can match eol */
 YY_RULE_SETUP
-#line 217 "ncgen.l"
+#line 222 "ncgen.l"
 {int len;
 			 /* In netcdf4, this will be used in a variety
                             of places, so only remove escapes */
@@ -1567,7 +1571,7 @@ ncgtext[MAXTRST-1] = '\0';
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 241 "ncgen.l"
+#line 246 "ncgen.l"
 { /* drop leading 0x; pad to even number of chars */
 		char* p = ncgtext+2;
 		int len = ncgleng - 2;
@@ -1576,119 +1580,119 @@ YY_RULE_SETUP
 	        if((len % 2) == 1) bbAppend(lextext,'0');
 		bbNull(lextext);
 		/* convert all chars to lower case */
-		for(p=bbContents(lextext);*p;p++) *p = tolower(*p);
+		for(p=bbContents(lextext);(int)*p;p++) *p = tolower(*p);
 		return lexdebug(OPAQUESTRING);
 		}
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 253 "ncgen.l"
+#line 258 "ncgen.l"
 {return lexdebug(COMPOUND);}
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 254 "ncgen.l"
+#line 259 "ncgen.l"
 {return lexdebug(ENUM);}
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 255 "ncgen.l"
+#line 260 "ncgen.l"
 {return lexdebug(OPAQUE);}
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 257 "ncgen.l"
+#line 262 "ncgen.l"
 {return lexdebug(FLOAT_K);}
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 258 "ncgen.l"
+#line 263 "ncgen.l"
 {return lexdebug(CHAR_K);}
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 259 "ncgen.l"
+#line 264 "ncgen.l"
 {return lexdebug(BYTE_K);}
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 260 "ncgen.l"
+#line 265 "ncgen.l"
 {return lexdebug(UBYTE_K);}
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 261 "ncgen.l"
+#line 266 "ncgen.l"
 {return lexdebug(SHORT_K);}
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 262 "ncgen.l"
+#line 267 "ncgen.l"
 {return lexdebug(USHORT_K);}
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 263 "ncgen.l"
+#line 268 "ncgen.l"
 {return lexdebug(INT_K);}
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 264 "ncgen.l"
+#line 269 "ncgen.l"
 {return lexdebug(UINT_K);}
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 265 "ncgen.l"
+#line 270 "ncgen.l"
 {return lexdebug(INT64_K);}
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 266 "ncgen.l"
+#line 271 "ncgen.l"
 {return lexdebug(UINT64_K);}
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 267 "ncgen.l"
+#line 272 "ncgen.l"
 {return lexdebug(DOUBLE_K);}
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 268 "ncgen.l"
+#line 273 "ncgen.l"
 {int32_val = -1;
 			 return lexdebug(NC_UNLIMITED_K);}
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 271 "ncgen.l"
+#line 276 "ncgen.l"
 {return lexdebug(TYPES);}
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 272 "ncgen.l"
+#line 277 "ncgen.l"
 {return lexdebug(DIMENSIONS);}
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 273 "ncgen.l"
+#line 278 "ncgen.l"
 {return lexdebug(VARIABLES);}
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 274 "ncgen.l"
+#line 279 "ncgen.l"
 {return lexdebug(DATA);}
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 275 "ncgen.l"
+#line 280 "ncgen.l"
 {return lexdebug(GROUP);}
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 277 "ncgen.l"
+#line 282 "ncgen.l"
 {BEGIN(TEXT);return lexdebug(NETCDF);}
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 279 "ncgen.l"
+#line 284 "ncgen.l"
 { /* missing value (pre-2.4 backward compatibility) */
                 if (ncgtext[0] == '-') {
 		    double_val = NEGNC_INFINITE;
@@ -1701,7 +1705,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 288 "ncgen.l"
+#line 293 "ncgen.l"
 { /* missing value (pre-2.4 backward compatibility) */
 		double_val = NAN;
 		specialconstants = 1;
@@ -1710,7 +1714,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 294 "ncgen.l"
+#line 299 "ncgen.l"
 {/* missing value (pre-2.4 backward compatibility)*/
                 if (ncgtext[0] == '-') {
 		    float_val = NEGNC_INFINITEF;
@@ -1723,7 +1727,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 303 "ncgen.l"
+#line 308 "ncgen.l"
 { /* missing value (pre-2.4 backward compatibility) */
 		float_val = NANF;
 		specialconstants = 1;
@@ -1732,7 +1736,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 309 "ncgen.l"
+#line 314 "ncgen.l"
 {
 #ifdef USE_NETCDF4
 		if(l_flag == L_C || l_flag == L_BINARY)
@@ -1745,7 +1749,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 319 "ncgen.l"
+#line 324 "ncgen.l"
 {
 		bbClear(lextext);
 		bbAppendn(lextext,(char*)ncgtext,ncgleng+1); /* include null */
@@ -1756,7 +1760,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 328 "ncgen.l"
+#line 333 "ncgen.l"
 {struct Specialtoken* st;
 		bbClear(lextext);
 		bbAppendn(lextext,(char*)ncgtext,ncgleng+1); /* include null */
@@ -1770,7 +1774,7 @@ YY_RULE_SETUP
 case 33:
 /* rule 33 can match eol */
 YY_RULE_SETUP
-#line 338 "ncgen.l"
+#line 343 "ncgen.l"
 {
 		    int c;
 		    char* p; char* q;
@@ -1789,7 +1793,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 354 "ncgen.l"
+#line 359 "ncgen.l"
 { char* id; int len;
 		    bbClear(lextext);
 		    bbAppendn(lextext,(char*)ncgtext,ncgleng+1); /* include null */
@@ -1804,35 +1808,39 @@ YY_RULE_SETUP
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 366 "ncgen.l"
+#line 371 "ncgen.l"
 {
-/*
-We need to try to see what size of integer ((u)int).
-Technically, the user should specify, but...
-If out of any integer range, then complain
-*/
+		/*
+		  We need to try to see what size of integer ((u)int).
+		  Technically, the user should specify, but...
+		  If out of any integer range, then complain
+		*/
 		    int slen = strlen(ncgtext);
-		    int tag = ncgtext[slen-1];
-		    int hasU = 0;
+		    char* stag = NULL;
+		    int tag = NC_NAT;
 		    int signchar = 0;
 		    int isneg = 0;
 		    int c = ncgtext[0];
 		    int fail = 0;
 		    nc_type nct = 0;
 		    char* pos = NULL;
+		    int hasU = 0;
 
+		    /* capture the tag string */
+		    tag = collecttag(ncgtext,&stag);
+		    if(tag == NC_NAT) {
+			sprintf(errstr,"Illegal integer suffix: %s",stag);
+			yyerror(errstr);
+			goto done;
+		    }
+		    /* drop the tag from the input text */
+		    ncgtext[slen - strlen(stag)] = '\0';
+		    hasU = isuinttype(tag);
 		    if(!tstdecimal(c)) {
 			pos = ncgtext+1;
 			isneg = (c == '-');
 		    } else
 		        pos = ncgtext;
-		    if(tag != '\0' && strchr(TAG,tag) != NULL) {
-			if(slen > 2) {
-			    c = ncgtext[slen-2];
-			    hasU = (c == 'U' || c == 'u') ? 1 : 0;
-			}
-		    } else
-			tag = 0;
 		    if(isneg && hasU) {
 			sprintf(errstr,"Unsigned integer cannot be signed: %s",ncgtext);
 			yyerror(errstr);
@@ -1845,7 +1853,7 @@ If out of any integer range, then complain
 			goto done;
 		    }
 		    /* Down convert to smallest possible range */
-		    nct = downconvert(uint64_val,isneg,tag,hasU);
+		    nct = downconvert(uint64_val,&tag,isneg,hasU);
 		    switch (k_flag) {
 		    case NC_FORMAT_64BIT_DATA:
 		    case NC_FORMAT_NETCDF4:
@@ -1859,10 +1867,9 @@ If out of any integer range, then complain
 				goto done;
 			    }
 		    }
-		    if(!tagmatch(nct,tag,hasU))  {
-			sprintf(errstr,"Integer out of range for tag: %s",ncgtext);
-			yyerror(errstr);
-			goto done;
+
+		    if(!tagmatch(nct,tag))  {
+			semwarn(lineno,"Warning: Integer out of range for tag: %s; tag treated as changed.",ncgtext);
 		    }
 		    return lexdebug(nct2lexeme(nct));
 done: return 0;
@@ -1870,15 +1877,25 @@ done: return 0;
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 429 "ncgen.l"
+#line 437 "ncgen.l"
 {
 		int c;
 		int token = 0;
 		int slen = strlen(ncgtext);
-		int tag = ncgtext[slen-1];
+		char* stag = NULL;
+	        int tag = NC_NAT;
 		char* hex = ncgtext+2; /* point to first true hex digit */
 		int xlen = (slen - 3);  /* true hex length */
+
 		ncgtext[slen-1] = '\0';
+	        /* capture the tag string */
+		tag = collecttag(ncgtext,&stag);
+		if(tag == NC_NAT) {
+		    sprintf(errstr,"Illegal integer suffix: %s",stag);
+		    yyerror(errstr);
+		    goto done;
+		}
+		ncgtext[slen - strlen(stag)] = '\0';
 	        if(xlen > 16) { /* truncate hi order digits */
 		    hex += (xlen - 16);
 		}
@@ -1889,11 +1906,14 @@ YY_RULE_SETUP
 		    uint64_val = ((uint64_val << 4) | hexdigit);
 		}
 		switch (tag) {
-		case 'S': case 's':
+		case NC_USHORT:
 		    uint16_val = (unsigned short)uint64_val;
 		    token = USHORT_CONST;
 		    break;
-		case 'L': case 'l':
+		case NC_UINT:
+		    token = UINT_CONST;
+		    break;
+		case NC_UINT64:
 		    token = UINT64_CONST;
 		    break;
 		default: /* should never happen */
@@ -1908,7 +1928,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 463 "ncgen.l"
+#line 484 "ncgen.l"
 {
 		if (sscanf((char*)ncgtext, "%le", &double_val) != 1) {
 		    sprintf(errstr,"bad long or double constant: %s",(char*)ncgtext);
@@ -1919,7 +1939,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 470 "ncgen.l"
+#line 491 "ncgen.l"
 {
 		if (sscanf((char*)ncgtext, "%e", &float_val) != 1) {
 		    sprintf(errstr,"bad float constant: %s",(char*)ncgtext);
@@ -1931,7 +1951,7 @@ YY_RULE_SETUP
 case 39:
 /* rule 39 can match eol */
 YY_RULE_SETUP
-#line 477 "ncgen.l"
+#line 498 "ncgen.l"
 {
 	        (void) sscanf((char*)&ncgtext[1],"%c",&byte_val);
 		return lexdebug(BYTE_CONST);
@@ -1939,7 +1959,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 481 "ncgen.l"
+#line 502 "ncgen.l"
 {
 		int oct = unescapeoct(&ncgtext[2]);
 		if(oct < 0) {
@@ -1952,7 +1972,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 490 "ncgen.l"
+#line 511 "ncgen.l"
 {
 		int hex = unescapehex(&ncgtext[3]);
 		if(byte_val < 0) {
@@ -1965,7 +1985,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 499 "ncgen.l"
+#line 520 "ncgen.l"
 {
 	       switch ((char)ncgtext[2]) {
 	          case 'a': byte_val = '\007'; break; /* not everyone under-
@@ -1987,7 +2007,7 @@ YY_RULE_SETUP
 case 43:
 /* rule 43 can match eol */
 YY_RULE_SETUP
-#line 517 "ncgen.l"
+#line 538 "ncgen.l"
 {
 		lineno++ ;
                 break;
@@ -1995,7 +2015,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 522 "ncgen.l"
+#line 543 "ncgen.l"
 {/*initial*/
 	    BEGIN(ST_C_COMMENT);
 	    break;
@@ -2004,21 +2024,21 @@ YY_RULE_SETUP
 case 45:
 /* rule 45 can match eol */
 YY_RULE_SETUP
-#line 527 "ncgen.l"
+#line 548 "ncgen.l"
 {/* continuation */
 				     break;
 				}
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 531 "ncgen.l"
+#line 552 "ncgen.l"
 {/* final */
 			    BEGIN(INITIAL);
 			    break;
 			}
 	YY_BREAK
 case YY_STATE_EOF(ST_C_COMMENT):
-#line 536 "ncgen.l"
+#line 557 "ncgen.l"
 {/* final, error */
 			    fprintf(stderr,"unterminated /**/ comment");
 			    BEGIN(INITIAL);
@@ -2027,17 +2047,17 @@ case YY_STATE_EOF(ST_C_COMMENT):
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 542 "ncgen.l"
+#line 563 "ncgen.l"
 {/* Note: this next rule will not work for UTF8 characters */
 		return lexdebug(ncgtext[0]) ;
 		}
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 545 "ncgen.l"
+#line 566 "ncgen.l"
 ECHO;
 	YY_BREAK
-#line 2041 "ncgenyy.c"
+#line 2061 "lex.ncg.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(TEXT):
 	yyterminate();
@@ -2105,7 +2125,8 @@ case YY_STATE_EOF(TEXT):
 
 			else
 				{
-				yy_cp = (yy_c_buf_p);
+				yy_cp = (yy_last_accepting_cpos);
+				yy_current_state = (yy_last_accepting_state);
 				goto yy_find_action;
 				}
 			}
@@ -2224,7 +2245,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 )
@@ -2238,7 +2259,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;
@@ -2269,7 +2290,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);
 		}
@@ -2330,7 +2351,7 @@ static int yy_get_next_buffer (void)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 382 )
+			if ( yy_current_state >= 384 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -2358,11 +2379,11 @@ static int yy_get_next_buffer (void)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 382 )
+		if ( yy_current_state >= 384 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 381);
+	yy_is_jam = (yy_current_state == 383);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
@@ -2379,7 +2400,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 =
@@ -2428,7 +2449,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(  ) )
@@ -2452,7 +2473,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;
@@ -2704,7 +2725,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)) {
 
@@ -2801,12 +2822,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;
@@ -2888,7 +2908,7 @@ FILE *ncgget_out  (void)
 /** Get the length of the current token.
  * 
  */
-int ncgget_leng  (void)
+yy_size_t ncgget_leng  (void)
 {
         return ncgleng;
 }
@@ -3036,7 +3056,7 @@ void ncgfree (void * ptr )
 
 #define YYTABLES_NAME "yytables"
 
-#line 545 "ncgen.l"
+#line 566 "ncgen.l"
 
 
 static int
@@ -3120,7 +3140,7 @@ makepath(char* text0)
 }
 
 /*
-Parse a simple string of digitis into an unsigned long long
+Parse a simple string of digits into an unsigned long long
 Return the value.
 */
 static unsigned long long
@@ -3150,122 +3170,114 @@ parseULL(char* text, int* failp)
 /**
 Given the raw bits, the sign char, the tag, and hasU
 fill in the appropriate *_val field
-and return the type
+and return the type.
+Note that we cannot return unsigned types if running pure netcdf classic.
+The rule is to pick the smallest enclosing type.
+
+The rule used here is that the tag (the suffix, if any)
+always takes precedence and the value is modified to conform
+if possible, otherwise out-of-range is signalled.
+For historical reasons (ncgen3), values that fit as unsigned
+are acceptable for the signed tag and conversion is attempted;
+e.g. 65535s; is legal and is return as a negative short.
 */
 static nc_type
-downconvert(unsigned long long uint64, int isneg, int tag, int hasU)
+downconvert(unsigned long long uint64, int* tagp, int isneg, int hasU)
 {
     nc_type nct = NC_NAT;
-    int bit64 = (uint64 >> 63);
-    int allones = (uint64 == 0xffffffffffffffffUL);
+    int tag = *tagp;
+    int bit63set = (uint64 >> 63);
     long long int64 = *((long long*)&uint64);
 
-    if(isneg && hasU)
-	return NC_NAT;
-    /* Special cases: all (u)int64 values */
-    if(allones && (hasU || !isneg)) /* bare max uint64 value */
-	return NC_UINT64;
-    if((int64 < NC_MIN_INT) || (int64 > NC_MAX_INT)) {
-	if(isneg && !hasU) {
-	    int64_val = - int64;
-	    return NC_INT64;
-	}
-	if(!isneg && hasU) {
-	    uint64_val = uint64;
-	    return NC_UINT64;
-	}
-	/* Bare big integer, assume int64 unless sign bit set */
-	if(!isneg && !hasU && bit64) {
-	    uint64_val = uint64;
-	    return NC_UINT64;
-	} else if(!bit64) {
-	    int64_val = int64;
-	    return NC_INT64;
-	}
-        /*assert(!isneg)*/
+    if(isneg && hasU) {
+	return (*tagp = NC_NAT);
+    }
+    /* To simplify the code, we look for special case of NC_UINT64
+       constants that will not fit into an NC_INT64 constant.
+     */
+    if(tag == NC_UINT64 && bit63set) {
         uint64_val = uint64;
-	return NC_UINT64;
+	return tag;
     }
-
-    if(isneg) int64 = -int64;
-
-    /* special case:
-       If there is no tag and the size is ok,
-       then always return NC_INT or NC_UINT.
-    */
-    if(!tag) {
-	if(!hasU) {
-	    if((int64 >= NC_MIN_INT) && (int64 <= NC_MAX_INT)) {
-		int32_val = (int)int64;
-	        return NC_INT;
-	    }
-	}
-	if(uint64 <= NC_MAX_UINT) {
-	    uint32_val = (unsigned int)uint64;
-	    return NC_INT;
+    /* At this point we need deal only with int64 value */
+    /* Apply the isneg */
+    if(isneg)
+	int64 = - int64;
+
+    if(tag == NC_NOTAG) {
+        /* If we have no other info, then assume NC_(U)INT(64) */
+	if(int64 >= NC_MIN_INT && int64 <= NC_MAX_INT) {
+	    nct = (tag = NC_INT);
+	    int32_val = (signed int)int64;
+	} else if(int64 >= 0 && int64 <= NC_MAX_UINT) {
+	        nct = (tag = NC_UINT);
+	        uint32_val = (unsigned int)int64;
+	} else if(int64 < 0) {
+		nct = (tag = NC_INT64);
+	        int64_val = (signed long long)int64;
+	} else {
+	        nct = (tag = NC_UINT64);
+	        uint64_val = (unsigned long long)int64;
 	}
+        goto done;
     }
-    /* assert (tag != 0) */
-
-    /* Pick smallest enclosing type;
-       for historical reasons (ncgen3), technically out of range
-       values are allowed and conversion is attempted;
-	e.g. 65535s; is legal and is return as an unsigned short.
-    */
-    if(hasU) {
-        switch (tag) {
-        case 'B': case 'b':
-	    if((int64 >= 0) && (int64 <= NC_MAX_UBYTE)) {
+    if(isuinttype(tag) && int64 < 0)
+	goto outofrange;
+    switch (tag) {
+    case NC_UBYTE:
+	    if(int64 <= NC_MAX_UBYTE) {
 	        nct = NC_UBYTE;
 	        ubyte_val = (unsigned char)int64;
-	    }; break;
-        case 'S': case 's':
-	    if((int64 >= 0) && (int64 <= NC_MAX_USHORT)) {
+	    } else
+		goto outofrange;
+	    break;
+    case NC_USHORT:
+	    if(int64 <= NC_MAX_USHORT) {
 	        nct = NC_USHORT;
 	        uint16_val = (unsigned short)int64;
-	    } break;
-        case 'L': case 'l':
-            if((int64 >= 0) && (int64 <= NC_MAX_UINT64)) {
+	    } else
+	       goto outofrange;
+	    break;
+    case NC_UINT:
+	    if(int64 <= NC_MAX_UINT) {
+	        nct = NC_UINT;
+	        uint32_val = (unsigned int)int64;
+	    } else
+		goto outofrange;
+	    break;
+    case NC_UINT64:
+            if(int64 <= NC_MAX_UINT64) {
 	        nct = NC_UINT64;
 	        uint64_val = uint64;
-	    } break;
-	default:
-	    return NC_NAT;
-	}
-    } else { /* !hasU */
-        switch (tag) {
-        case 'B': case 'b':
-            if((int64 >= NC_MIN_BYTE) && (int64 <= NC_MAX_BYTE)) {
-	        nct = NC_BYTE;
-	        byte_val = (signed char)int64;
-	    } else {/* force to unsigned value */
-		uint64_val = uint64 & 0xff;
-		nct = NC_UBYTE;
-	    }
+	    } else
+		goto outofrange;
 	    break;
-        case 'S': case 's':
-	    if((int64 >= NC_MIN_SHORT) && (int64 <= NC_MAX_SHORT)) {
-	        nct = NC_SHORT;
-	        int16_val = (signed short)int64;
-	    } else {/* force to unsigned value */
-		uint64_val = uint64 & 0xffff;
-		nct = NC_USHORT;
-	    }
+    case NC_INT64:
+	    nct = NC_INT64;
+	    int64_val = int64;
 	    break;
-        case 'L': case 'l':
-            if((uint64 <= NC_MAX_INT64)) {
-	        nct = NC_INT64;
-	        int64_val = int64;
-	    } else {/* force to unsigned value */
-		uint64_val = uint64;
-		nct = NC_UINT64;
-	    }
+    case NC_BYTE:
+	    nct = NC_BYTE;
+	    byte_val = (signed char)int64;
 	    break;
-	default:
-	    return NC_NAT;
-	}
+    case NC_SHORT:
+	    nct = NC_SHORT;
+	    int16_val = (signed short)int64;
+	    break;
+    case NC_INT:
+	    nct = NC_INT;
+	    int32_val = (signed int)int64;
+	    break;
+    default:
+	    goto outofrange;
     }
+
+done:
+    *tagp = tag;
     return nct;
+outofrange:
+    yyerror("Value out of range");
+    return NC_NAT;
 }
 
 static int
@@ -3285,24 +3297,63 @@ nct2lexeme(nc_type nct)
     return 0;
 }
 
+static int
+tagmatch(nc_type nct, int tag)
+{
+    if(tag == NC_NAT || tag ==  NC_NOTAG)
+	return 1;
+    return nct == tag;
+}
 
+/* capture the tag string */
 static int
-tagmatch(nc_type nct, int tag, int hasU)
+collecttag(char* text, char** stagp)
 {
-    if(hasU) switch(nct) {
-        case NC_UBYTE: return (tag == 0 || tag == 'B' || tag == 'b');
-        case NC_USHORT: return (tag == 0 || tag == 'S' || tag == 's');
-        case NC_UINT: return (tag == 0);
-        case NC_UINT64: return (tag == 0 || tag == 'L' || tag == 'l');
-	default: return 0;
-    } else switch(nct) {
-	case NC_BYTE: return (tag == 0 || tag == 'B' || tag == 'b');
-	case NC_SHORT: return (tag == 0 || tag == 'S' || tag == 's');
-	case NC_INT: return (tag == 0);
-	case NC_INT64: return (tag == 0 || tag == 'L' || tag == 'l');
-	default: return 0;
+    char* stag0;
+#define MAXTAGLEN 3
+    char stag[MAXTAGLEN+1];
+    int slen = strlen(text);
+    int staglen;
+    int tag = NC_NAT;
+    int hasU = 0;
+
+    for(stag0 = text+(slen-1);stag0 > 0;stag0--) {
+	if(strchr(TAGCHARS,*stag0) == NULL) {stag0++; break;}
     }
-    return 0;
+    if(stagp) *stagp = stag0;
+    staglen = strlen(stag0);
+    if(staglen == 0)
+	return NC_NOTAG;
+    if(staglen > MAXTAGLEN)
+	return tag;
+    strncpy(stag,stag0,sizeof(stag));
+    stag[MAXTAGLEN] = '\0';
+    if(stag[0] == 'U' || stag[0] == 'u') {
+	hasU = 1;
+    memmove(stag,stag+1,MAXTAGLEN);
+	staglen--;
+    } else if(stag[staglen-1] == 'U' || stag[staglen-1] == 'u') {
+	hasU = 1;
+	staglen--;
+	stag[staglen] = '\0';
+    }
+    if(strlen(stag) == 0 && hasU) {
+	tag = NC_UINT64;
+    } else if(strlen(stag) == 1) {
+	switch (stag[0]) {
+	case 'B': case 'b': tag = (hasU ? NC_UBYTE : NC_BYTE); break;
+	case 'S': case 's': tag = (hasU ? NC_USHORT : NC_SHORT); break;
+	case 'L': case 'l': tag = (hasU ? NC_UINT : NC_INT); break;
+	default: break;
+	}
+    } else if(strcasecmp(stag,"ll") == 0) {
+	tag = (hasU ? NC_UINT64 : NC_INT64);
+    }
+    if(tag == NC_NAT) {
+	if(strlen(stag) > 0)
+	    return tag;
+	tag = NC_NAT;
+    }
+    return tag;
 }
 
-
diff --git a/ncgen/ncgentab.c b/ncgen/ncgeny.c
similarity index 82%
rename from ncgen/ncgentab.c
rename to ncgen/ncgeny.c
index 96915dd..e43896e 100644
--- a/ncgen/ncgentab.c
+++ b/ncgen/ncgeny.c
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
-/* Bison implementation for Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   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
    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
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    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 <http://www.gnu.org/licenses/>.  */
+   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
@@ -26,7 +29,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -44,7 +47,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "2.3"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -52,28 +55,129 @@
 /* Pure parsers.  */
 #define YYPURE 0
 
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
 /* Using locations.  */
 #define YYLSP_NEEDED 0
 
 /* 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
+#define yyparse ncgparse
+#define yylex   ncglex
+#define yyerror ncgerror
+#define yylval  ncglval
+#define yychar  ncgchar
+#define yydebug ncgdebug
+#define yynerrs ncgnerrs
 
 
-/* Copy the first part of user declarations.  */
+/* 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,
+     DATASETID = 305
+   };
+#endif
+/* Tokens.  */
+#define NC_UNLIMITED_K 258
+#define CHAR_K 259
+#define BYTE_K 260
+#define SHORT_K 261
+#define INT_K 262
+#define FLOAT_K 263
+#define DOUBLE_K 264
+#define UBYTE_K 265
+#define USHORT_K 266
+#define UINT_K 267
+#define INT64_K 268
+#define UINT64_K 269
+#define IDENT 270
+#define TERMSTRING 271
+#define CHAR_CONST 272
+#define BYTE_CONST 273
+#define SHORT_CONST 274
+#define INT_CONST 275
+#define INT64_CONST 276
+#define UBYTE_CONST 277
+#define USHORT_CONST 278
+#define UINT_CONST 279
+#define UINT64_CONST 280
+#define FLOAT_CONST 281
+#define DOUBLE_CONST 282
+#define DIMENSIONS 283
+#define VARIABLES 284
+#define NETCDF 285
+#define DATA 286
+#define TYPES 287
+#define COMPOUND 288
+#define ENUM 289
+#define OPAQUE 290
+#define OPAQUESTRING 291
+#define GROUP 292
+#define PATH 293
+#define FILLMARKER 294
+#define NIL 295
+#define _FILLVALUE 296
+#define _FORMAT 297
+#define _STORAGE 298
+#define _CHUNKSIZES 299
+#define _DEFLATELEVEL 300
+#define _SHUFFLE 301
+#define _ENDIANNESS 302
+#define _NOFILL 303
+#define _FLETCHER32 304
+#define DATASETID 305
 
-/* Line 268 of yacc.c  */
+
+
+
+/* Copy the first part of user declarations.  */
 #line 11 "ncgen.y"
 
 /*
@@ -193,9 +297,6 @@ extern int lex_init(void);
 
 
 
-/* Line 268 of yacc.c  */
-#line 198 "ncgentab.c"
-
 /* Enabling traces.  */
 #ifndef YYDEBUG
 # define YYDEBUG 1
@@ -214,96 +315,32 @@ extern int lex_init(void);
 # define YYTOKEN_TABLE 0
 #endif
 
-
-/* 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,
-     DATASETID = 305
-   };
-#endif
-
-
-
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-{
-
-/* Line 293 of yacc.c  */
 #line 131 "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 293 of yacc.c  */
-#line 295 "ncgentab.c"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 193 of yacc.c.  */
+#line 331 "ncgen.tab.c"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 
+
 /* Copy the second part of user declarations.  */
 
 
-/* Line 343 of yacc.c  */
-#line 307 "ncgentab.c"
+/* Line 216 of yacc.c.  */
+#line 344 "ncgen.tab.c"
 
 #ifdef short
 # undef short
@@ -378,14 +415,14 @@ typedef short int yytype_int16;
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static int
-YYID (int yyi)
+YYID (int i)
 #else
 static int
-YYID (yyi)
-    int yyi;
+YYID (i)
+    int i;
 #endif
 {
-  return yyi;
+  return i;
 }
 #endif
 
@@ -406,11 +443,11 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
 #     endif
 #    endif
 #   endif
@@ -433,24 +470,24 @@ YYID (yyi)
 #  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)))
 #   include <stdlib.h> /* 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 && (defined __STDC__ || defined __C99__FUNC__ \
+#   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 && (defined __STDC__ || defined __C99__FUNC__ \
+#   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
@@ -466,9 +503,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 /* 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)
@@ -479,27 +516,6 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
       + YYSTACK_GAP_MAXIMUM)
 
-# define YYCOPY_NEEDED 1
-
-/* 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 (YYID (0))
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
 /* Copy COUNT objects from FROM to TO.  The source and destination do
    not overlap.  */
 # ifndef YYCOPY
@@ -517,7 +533,24 @@ union yyalloc
       while (YYID (0))
 #  endif
 # endif
-#endif /* !YYCOPY_NEEDED */
+
+/* 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)					\
+    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
 
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  5
@@ -687,7 +720,7 @@ static const char *const yytname[] =
   "_DEFLATELEVEL", "_SHUFFLE", "_ENDIANNESS", "_NOFILL", "_FLETCHER32",
   "DATASETID", "'{'", "'}'", "';'", "','", "'='", "'('", "')'", "'*'",
   "':'", "$accept", "ncdesc", "datasetid", "rootgroup", "groupbody",
-  "subgrouplist", "namedgroup", "$@1", "$@2", "typesection", "typedecls",
+  "subgrouplist", "namedgroup", "@1", "@2", "typesection", "typedecls",
   "typename", "type_or_attr_decl", "typedecl", "optsemicolon", "enumdecl",
   "enumidlist", "enumid", "opaquedecl", "vlendecl", "compounddecl",
   "fields", "field", "primtype", "dimsection", "dimdecls",
@@ -758,8 +791,8 @@ static const yytype_uint8 yyr2[] =
        1
 };
 
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
-   Performed when YYTABLE doesn't specify something else to do.  Zero
+/* 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[] =
 {
@@ -850,7 +883,8 @@ static const yytype_int16 yypgoto[] =
 
 /* 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 YYTABLE_NINF, syntax error.  */
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -105
 static const yytype_int16 yytable[] =
 {
@@ -893,12 +927,6 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,     0,     0,     0,    20
 };
 
-#define yypact_value_is_default(yystate) \
-  ((yystate) == (-124))
-
-#define yytable_value_is_error(yytable_value) \
-  YYID (0)
-
 static const yytype_int16 yycheck[] =
 {
       37,    21,    85,    24,    38,   101,   102,    39,   131,    15,
@@ -984,18 +1012,9 @@ static const yytype_uint8 yystos[] =
 
 /* 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.  However,
-   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
-   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
-   discussed.  */
+   Once GCC version 2 has supplanted version 1, this can go.  */
 
 #define YYFAIL		goto yyerrlab
-#if defined YYFAIL
-  /* This is here to suppress warnings from the GCC cpp's
-     -Wunused-macros.  Normally we don't worry about that warning, but
-     some users do, and we want to make it easy for users to remove
-     YYFAIL uses, which will produce warnings from Bison 2.5.  */
-#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
@@ -1005,6 +1024,7 @@ do								\
     {								\
       yychar = (Token);						\
       yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
       YYPOPSTACK (1);						\
       goto yybackup;						\
     }								\
@@ -1046,10 +1066,19 @@ while (YYID (0))
 #endif
 
 
-/* This macro is provided for backward compatibility. */
+/* 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
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# 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
 
 
@@ -1153,20 +1182,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
 #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 (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
+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");
 }
 
@@ -1200,11 +1226,11 @@ yy_reduce_print (yyvsp, yyrule)
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      fprintf (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
 		       &(yyvsp[(yyi + 1) - (yynrhs)])
 		       		       );
-      YYFPRINTF (stderr, "\n");
+      fprintf (stderr, "\n");
     }
 }
 
@@ -1241,6 +1267,7 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
+

 
 #if YYERROR_VERBOSE
 
@@ -1343,142 +1370,115 @@ 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 (0, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
-  YYSIZE_T yysize1;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = 0;
-  /* 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:
-     - Assume YYFAIL is not used.  It's too flawed to consider.  See
-       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
-       for details.  YYERROR is fine as it does not invoke this
-       function.
-     - 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];
-                yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-                if (! (yysize <= yysize1
-                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                  return 2;
-                yysize = yysize1;
-              }
-        }
-    }
+  int yyn = yypact[yystate];
 
-  switch (yycount)
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
     {
-# 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_
-    }
+      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;
+	  }
 
-  yysize1 = yysize + yystrlen (yyformat);
-  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-    return 2;
-  yysize = yysize1;
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
 
-  if (*yymsg_alloc < yysize)
-    {
-      *yymsg_alloc = 2 * yysize;
-      if (! (yysize <= *yymsg_alloc
-             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
-        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
-    }
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
 
-  /* 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;
+      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;
+    }
 }
 #endif /* YYERROR_VERBOSE */
+

 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -1510,9 +1510,10 @@ yydestruct (yymsg, yytype, yyvaluep)
 	break;
     }
 }
-
+

 
 /* Prevent warnings from -Wmissing-prototypes.  */
+
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
 int yyparse (void *YYPARSE_PARAM);
@@ -1528,16 +1529,18 @@ int yyparse ();
 #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.  |
 `----------*/
@@ -1564,37 +1567,14 @@ yyparse ()
 #endif
 #endif
 {
-    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 thru 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;
-
+  
+  int yystate;
   int yyn;
   int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
 #if YYERROR_VERBOSE
   /* Buffer for error messages, and its allocated size.  */
   char yymsgbuf[128];
@@ -1602,28 +1582,51 @@ yyparse ()
   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;
 
-  yytoken = 0;
-  yyss = yyssa;
-  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;
 
@@ -1653,6 +1656,7 @@ yyparse ()
 	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
@@ -1660,6 +1664,7 @@ yyparse ()
 	yyoverflow (YY_("memory exhausted"),
 		    &yyss1, yysize * sizeof (*yyssp),
 		    &yyvs1, yysize * sizeof (*yyvsp),
+
 		    &yystacksize);
 
 	yyss = yyss1;
@@ -1682,8 +1687,9 @@ yyparse ()
 	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
 	if (! yyptr)
 	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss_alloc, yyss);
-	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
 #  undef YYSTACK_RELOCATE
 	if (yyss1 != yyssa)
 	  YYSTACK_FREE (yyss1);
@@ -1694,6 +1700,7 @@ yyparse ()
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
+
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
 		  (unsigned long int) yystacksize));
 
@@ -1703,9 +1710,6 @@ yyparse ()
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
   goto yybackup;
 
 /*-----------.
@@ -1714,16 +1718,16 @@ yyparse ()
 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: "));
@@ -1749,22 +1753,26 @@ yybackup:
   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;
   *++yyvsp = yylval;
@@ -1804,22 +1812,16 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-
-/* Line 1806 of yacc.c  */
 #line 211 "ncgen.y"
-    {if (error_count > 0) YYABORT;}
+    {if (error_count > 0) YYABORT;;}
     break;
 
   case 3:
-
-/* Line 1806 of yacc.c  */
 #line 214 "ncgen.y"
-    {createrootgroup(datasetname);}
+    {createrootgroup(datasetname);;}
     break;
 
   case 8:
-
-/* Line 1806 of yacc.c  */
 #line 233 "ncgen.y"
     {
 		Symbol* id = (yyvsp[(2) - (3)].sym);
@@ -1827,33 +1829,25 @@ yyreduce:
 		if(creategroup(id) == NULL)
                     yyerror("duplicate group declaration within parent group for %s",
                                 id->name);
-            }
+            ;}
     break;
 
   case 9:
-
-/* Line 1806 of yacc.c  */
 #line 242 "ncgen.y"
-    {listpop(groupstack);}
+    {listpop(groupstack);;}
     break;
 
   case 12:
-
-/* Line 1806 of yacc.c  */
 #line 248 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 13:
-
-/* Line 1806 of yacc.c  */
 #line 250 "ncgen.y"
-    {markcdf4("Type specification");}
+    {markcdf4("Type specification");;}
     break;
 
   case 16:
-
-/* Line 1806 of yacc.c  */
 #line 256 "ncgen.y"
     { /* Use when defining a type */
               (yyvsp[(1) - (1)].sym)->objectclass = NC_TYPE;
@@ -1861,26 +1855,20 @@ yyreduce:
                     yyerror("duplicate type declaration for %s",
                             (yyvsp[(1) - (1)].sym)->name);
               listpush(typdefs,(void*)(yyvsp[(1) - (1)].sym));
-	    }
+	    ;}
     break;
 
   case 17:
-
-/* Line 1806 of yacc.c  */
 #line 265 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 18:
-
-/* Line 1806 of yacc.c  */
 #line 265 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 25:
-
-/* Line 1806 of yacc.c  */
 #line 279 "ncgen.y"
     {
 		int i;
@@ -1907,19 +1895,15 @@ yyreduce:
 		   eid->typ.basetype = (yyvsp[(3) - (6)].sym)->typ.basetype;
                 }
                 listsetlength(stack,stackbase);/* remove stack nodes*/
-              }
+              ;}
     break;
 
   case 26:
-
-/* Line 1806 of yacc.c  */
 #line 308 "ncgen.y"
-    {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[(1) - (1)].sym));}
+    {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[(1) - (1)].sym));;}
     break;
 
   case 27:
-
-/* Line 1806 of yacc.c  */
 #line 310 "ncgen.y"
     {
 		    int i;
@@ -1934,24 +1918,20 @@ yyreduce:
         	                 elem->name);
 		    }
 		    listpush(stack,(void*)(yyvsp[(3) - (3)].sym));
-		}
+		;}
     break;
 
   case 28:
-
-/* Line 1806 of yacc.c  */
 #line 327 "ncgen.y"
     {
             (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 1806 of yacc.c  */
 #line 336 "ncgen.y"
     {
 		    vercheck(NC_OPAQUE);
@@ -1961,12 +1941,10 @@ yyreduce:
                     (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 1806 of yacc.c  */
 #line 348 "ncgen.y"
     {
                     Symbol* basetype = (yyvsp[(1) - (5)].sym);
@@ -1978,12 +1956,10 @@ yyreduce:
                     (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 1806 of yacc.c  */
 #line 362 "ncgen.y"
     {
 	    int i,j;
@@ -2013,26 +1989,20 @@ yyreduce:
  	        listpush((yyvsp[(2) - (5)].sym)->subnodes,(void*)fsym);
 	    }
 	    listsetlength(stack,stackbase);/* remove stack nodes*/
-          }
+          ;}
     break;
 
   case 32:
-
-/* Line 1806 of yacc.c  */
 #line 394 "ncgen.y"
-    {(yyval.mark)=(yyvsp[(1) - (2)].mark);}
+    {(yyval.mark)=(yyvsp[(1) - (2)].mark);;}
     break;
 
   case 33:
-
-/* Line 1806 of yacc.c  */
 #line 395 "ncgen.y"
-    {(yyval.mark)=(yyvsp[(1) - (3)].mark);}
+    {(yyval.mark)=(yyvsp[(1) - (3)].mark);;}
     break;
 
   case 34:
-
-/* Line 1806 of yacc.c  */
 #line 399 "ncgen.y"
     {
 	    int i;
@@ -2044,129 +2014,95 @@ yyreduce:
                 Symbol* f = (Symbol*)listget(stack,i);
 		f->typ.basetype = (yyvsp[(1) - (2)].sym);
             }
-        }
+        ;}
     break;
 
   case 35:
-
-/* Line 1806 of yacc.c  */
 #line 412 "ncgen.y"
-    { (yyval.sym) = primsymbols[NC_CHAR]; }
+    { (yyval.sym) = primsymbols[NC_CHAR]; ;}
     break;
 
   case 36:
-
-/* Line 1806 of yacc.c  */
 #line 413 "ncgen.y"
-    { (yyval.sym) = primsymbols[NC_BYTE]; }
+    { (yyval.sym) = primsymbols[NC_BYTE]; ;}
     break;
 
   case 37:
-
-/* Line 1806 of yacc.c  */
 #line 414 "ncgen.y"
-    { (yyval.sym) = primsymbols[NC_SHORT]; }
+    { (yyval.sym) = primsymbols[NC_SHORT]; ;}
     break;
 
   case 38:
-
-/* Line 1806 of yacc.c  */
 #line 415 "ncgen.y"
-    { (yyval.sym) = primsymbols[NC_INT]; }
+    { (yyval.sym) = primsymbols[NC_INT]; ;}
     break;
 
   case 39:
-
-/* Line 1806 of yacc.c  */
 #line 416 "ncgen.y"
-    { (yyval.sym) = primsymbols[NC_FLOAT]; }
+    { (yyval.sym) = primsymbols[NC_FLOAT]; ;}
     break;
 
   case 40:
-
-/* Line 1806 of yacc.c  */
 #line 417 "ncgen.y"
-    { (yyval.sym) = primsymbols[NC_DOUBLE]; }
+    { (yyval.sym) = primsymbols[NC_DOUBLE]; ;}
     break;
 
   case 41:
-
-/* Line 1806 of yacc.c  */
 #line 418 "ncgen.y"
-    { vercheck(NC_UBYTE); (yyval.sym) = primsymbols[NC_UBYTE]; }
+    { vercheck(NC_UBYTE); (yyval.sym) = primsymbols[NC_UBYTE]; ;}
     break;
 
   case 42:
-
-/* Line 1806 of yacc.c  */
 #line 419 "ncgen.y"
-    { vercheck(NC_USHORT); (yyval.sym) = primsymbols[NC_USHORT]; }
+    { vercheck(NC_USHORT); (yyval.sym) = primsymbols[NC_USHORT]; ;}
     break;
 
   case 43:
-
-/* Line 1806 of yacc.c  */
 #line 420 "ncgen.y"
-    { vercheck(NC_UINT); (yyval.sym) = primsymbols[NC_UINT]; }
+    { vercheck(NC_UINT); (yyval.sym) = primsymbols[NC_UINT]; ;}
     break;
 
   case 44:
-
-/* Line 1806 of yacc.c  */
 #line 421 "ncgen.y"
-    { vercheck(NC_INT64); (yyval.sym) = primsymbols[NC_INT64]; }
+    { vercheck(NC_INT64); (yyval.sym) = primsymbols[NC_INT64]; ;}
     break;
 
   case 45:
-
-/* Line 1806 of yacc.c  */
 #line 422 "ncgen.y"
-    { vercheck(NC_UINT64); (yyval.sym) = primsymbols[NC_UINT64]; }
+    { vercheck(NC_UINT64); (yyval.sym) = primsymbols[NC_UINT64]; ;}
     break;
 
   case 47:
-
-/* Line 1806 of yacc.c  */
 #line 426 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 48:
-
-/* Line 1806 of yacc.c  */
 #line 427 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 51:
-
-/* Line 1806 of yacc.c  */
 #line 434 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 52:
-
-/* Line 1806 of yacc.c  */
 #line 434 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 55:
-
-/* Line 1806 of yacc.c  */
 #line 442 "ncgen.y"
     {
 		(yyvsp[(1) - (3)].sym)->dim.declsize = (size_t)uint32_val;
 #ifdef GENDEBUG1
 fprintf(stderr,"dimension: %s = %lu\n",(yyvsp[(1) - (3)].sym)->name,(unsigned long)(yyvsp[(1) - (3)].sym)->dim.declsize);
 #endif
-	      }
+	      ;}
     break;
 
   case 56:
-
-/* Line 1806 of yacc.c  */
 #line 449 "ncgen.y"
     {
 		if(int32_val <= 0) {
@@ -2177,12 +2113,10 @@ fprintf(stderr,"dimension: %s = %lu\n",(yyvsp[(1) - (3)].sym)->name,(unsigned lo
 #ifdef GENDEBUG1
 fprintf(stderr,"dimension: %s = %lu\n",(yyvsp[(1) - (3)].sym)->name,(unsigned long)(yyvsp[(1) - (3)].sym)->dim.declsize);
 #endif
-	      }
+	      ;}
     break;
 
   case 57:
-
-/* Line 1806 of yacc.c  */
 #line 460 "ncgen.y"
     { /* for rare case where 2^31 < dimsize < 2^32 */
                        if (double_val <= 0)
@@ -2195,12 +2129,10 @@ fprintf(stderr,"dimension: %s = %lu\n",(yyvsp[(1) - (3)].sym)->name,(unsigned lo
 #ifdef GENDEBUG1
 fprintf(stderr,"dimension: %s = %lu\n",(yyvsp[(1) - (3)].sym)->name,(unsigned long)(yyvsp[(1) - (3)].sym)->dim.declsize);
 #endif
-                   }
+                   ;}
     break;
 
   case 58:
-
-/* Line 1806 of yacc.c  */
 #line 473 "ncgen.y"
     {
 		        (yyvsp[(1) - (3)].sym)->dim.declsize = NC_UNLIMITED;
@@ -2208,12 +2140,10 @@ fprintf(stderr,"dimension: %s = %lu\n",(yyvsp[(1) - (3)].sym)->name,(unsigned lo
 #ifdef GENDEBUG1
 fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 #endif
-		   }
+		   ;}
     break;
 
   case 59:
-
-/* Line 1806 of yacc.c  */
 #line 483 "ncgen.y"
     {
                      (yyvsp[(1) - (1)].sym)->objectclass=NC_DIM;
@@ -2223,40 +2153,30 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 		     addtogroup((yyvsp[(1) - (1)].sym));
 		     (yyval.sym)=(yyvsp[(1) - (1)].sym);
 		     listpush(dimdefs,(void*)(yyvsp[(1) - (1)].sym));
-                   }
+                   ;}
     break;
 
   case 61:
-
-/* Line 1806 of yacc.c  */
 #line 495 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 62:
-
-/* Line 1806 of yacc.c  */
 #line 496 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 65:
-
-/* Line 1806 of yacc.c  */
 #line 503 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 66:
-
-/* Line 1806 of yacc.c  */
 #line 503 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 67:
-
-/* Line 1806 of yacc.c  */
 #line 506 "ncgen.y"
     {
 		    int i;
@@ -2276,28 +2196,22 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 			}
 		    }
 		    listsetlength(stack,stackbase);/* remove stack nodes*/
-		}
+		;}
     break;
 
   case 68:
-
-/* Line 1806 of yacc.c  */
 #line 528 "ncgen.y"
     {(yyval.mark)=listlength(stack);
                  listpush(stack,(void*)(yyvsp[(1) - (1)].sym));
-		}
+		;}
     break;
 
   case 69:
-
-/* Line 1806 of yacc.c  */
 #line 532 "ncgen.y"
-    {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));}
+    {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));;}
     break;
 
   case 70:
-
-/* Line 1806 of yacc.c  */
 #line 536 "ncgen.y"
     {
 		    int i;
@@ -2322,40 +2236,30 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 		    (yyvsp[(1) - (2)].sym)->typ.basetype = NULL; /* not yet known*/
                     (yyvsp[(1) - (2)].sym)->objectclass=NC_VAR;
 		    listsetlength(stack,stackbase);/* remove stack nodes*/
-		    }
+		    ;}
     break;
 
   case 71:
-
-/* Line 1806 of yacc.c  */
 #line 562 "ncgen.y"
-    {(yyval.mark)=listlength(stack);}
+    {(yyval.mark)=listlength(stack);;}
     break;
 
   case 72:
-
-/* Line 1806 of yacc.c  */
 #line 563 "ncgen.y"
-    {(yyval.mark)=(yyvsp[(2) - (3)].mark);}
+    {(yyval.mark)=(yyvsp[(2) - (3)].mark);;}
     break;
 
   case 73:
-
-/* Line 1806 of yacc.c  */
 #line 566 "ncgen.y"
-    {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[(1) - (1)].sym));}
+    {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[(1) - (1)].sym));;}
     break;
 
   case 74:
-
-/* Line 1806 of yacc.c  */
 #line 568 "ncgen.y"
-    {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));}
+    {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));;}
     break;
 
   case 75:
-
-/* Line 1806 of yacc.c  */
 #line 572 "ncgen.y"
     {Symbol* dimsym = (yyvsp[(1) - (1)].sym);
 		dimsym->objectclass = NC_DIM;
@@ -2366,28 +2270,22 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 		    YYABORT;
 		}
 		(yyval.sym)=dimsym;
-	    }
+	    ;}
     break;
 
   case 76:
-
-/* Line 1806 of yacc.c  */
 #line 586 "ncgen.y"
     {(yyval.mark)=listlength(stack);
              listpush(stack,(void*)(yyvsp[(1) - (1)].sym));
-	    }
+	    ;}
     break;
 
   case 77:
-
-/* Line 1806 of yacc.c  */
 #line 590 "ncgen.y"
-    {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));}
+    {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));;}
     break;
 
   case 78:
-
-/* Line 1806 of yacc.c  */
 #line 595 "ncgen.y"
     {
 		int i;
@@ -2414,40 +2312,30 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
                 (yyvsp[(1) - (2)].sym)->subclass=NC_FIELD;
 		listsetlength(stack,stackbase);/* remove stack nodes*/
 		(yyval.sym) = (yyvsp[(1) - (2)].sym);
-	    }
+	    ;}
     break;
 
   case 79:
-
-/* Line 1806 of yacc.c  */
 #line 623 "ncgen.y"
-    {(yyval.mark)=listlength(stack);}
+    {(yyval.mark)=listlength(stack);;}
     break;
 
   case 80:
-
-/* Line 1806 of yacc.c  */
 #line 624 "ncgen.y"
-    {(yyval.mark)=(yyvsp[(2) - (3)].mark);}
+    {(yyval.mark)=(yyvsp[(2) - (3)].mark);;}
     break;
 
   case 81:
-
-/* Line 1806 of yacc.c  */
 #line 628 "ncgen.y"
-    {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[(1) - (1)].sym));}
+    {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[(1) - (1)].sym));;}
     break;
 
   case 82:
-
-/* Line 1806 of yacc.c  */
 #line 630 "ncgen.y"
-    {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));}
+    {(yyval.mark)=(yyvsp[(1) - (3)].mark); listpush(stack,(void*)(yyvsp[(3) - (3)].sym));;}
     break;
 
   case 83:
-
-/* Line 1806 of yacc.c  */
 #line 635 "ncgen.y"
     {  /* Anonymous integer dimension.
 	         Can only occur in type definitions*/
@@ -2457,12 +2345,10 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 	     (yyval.sym)->objectclass = NC_DIM;
 	     (yyval.sym)->dim.isconstant = 1;
 	     (yyval.sym)->dim.declsize = uint32_val;
-	    }
+	    ;}
     break;
 
   case 84:
-
-/* Line 1806 of yacc.c  */
 #line 645 "ncgen.y"
     {  /* Anonymous integer dimension.
 	         Can only occur in type definitions*/
@@ -2476,12 +2362,10 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 	     (yyval.sym)->objectclass = NC_DIM;
 	     (yyval.sym)->dim.isconstant = 1;
 	     (yyval.sym)->dim.declsize = int32_val;
-	    }
+	    ;}
     break;
 
   case 85:
-
-/* Line 1806 of yacc.c  */
 #line 665 "ncgen.y"
     {Symbol* vsym = (yyvsp[(1) - (1)].sym);
 		if(vsym->objectclass != NC_VAR) {
@@ -2489,12 +2373,10 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 		    YYABORT;
 		}
 		(yyval.sym)=vsym;
-	    }
+	    ;}
     break;
 
   case 86:
-
-/* Line 1806 of yacc.c  */
 #line 676 "ncgen.y"
     {Symbol* tsym = (yyvsp[(1) - (1)].sym);
 		if(tsym->objectclass != NC_TYPE) {
@@ -2502,12 +2384,10 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 		    YYABORT;
 		}
 		(yyval.sym)=tsym;
-	    }
+	    ;}
     break;
 
   case 87:
-
-/* Line 1806 of yacc.c  */
 #line 687 "ncgen.y"
     {Symbol* tvsym = (yyvsp[(1) - (1)].sym); Symbol* sym;
 		/* disambiguate*/
@@ -2526,40 +2406,30 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 		    YYABORT;
 		}
 		(yyval.sym)=tvsym;
-	    }
+	    ;}
     break;
 
   case 88:
-
-/* Line 1806 of yacc.c  */
 #line 705 "ncgen.y"
-    {(yyval.sym)=(yyvsp[(1) - (1)].sym);}
+    {(yyval.sym)=(yyvsp[(1) - (1)].sym);;}
     break;
 
   case 89:
-
-/* Line 1806 of yacc.c  */
 #line 712 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 90:
-
-/* Line 1806 of yacc.c  */
 #line 712 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 91:
-
-/* Line 1806 of yacc.c  */
 #line 716 "ncgen.y"
-    { (yyval.sym)=makeattribute((yyvsp[(2) - (4)].sym),NULL,NULL,(yyvsp[(4) - (4)].datalist),ATTRGLOBAL);}
+    { (yyval.sym)=makeattribute((yyvsp[(2) - (4)].sym),NULL,NULL,(yyvsp[(4) - (4)].datalist),ATTRGLOBAL);;}
     break;
 
   case 92:
-
-/* Line 1806 of yacc.c  */
 #line 718 "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) {
@@ -2568,12 +2438,10 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 		    derror("Doubly typed attribute: %s",asym->name);
 		    YYABORT;
 		}
-	    }
+	    ;}
     break;
 
   case 93:
-
-/* Line 1806 of yacc.c  */
 #line 727 "ncgen.y"
     {Symbol* sym = (yyvsp[(1) - (5)].sym); Symbol* asym = (yyvsp[(3) - (5)].sym);
 		if(sym->objectclass == NC_VAR) {
@@ -2584,407 +2452,289 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 		    derror("Attribute prefix not a variable or type: %s",asym->name);
 		    YYABORT;
 		}
-	    }
+	    ;}
     break;
 
   case 94:
-
-/* Line 1806 of yacc.c  */
 #line 738 "ncgen.y"
-    {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)(yyvsp[(5) - (5)].datalist),0);}
+    {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)(yyvsp[(5) - (5)].datalist),0);;}
     break;
 
   case 95:
-
-/* Line 1806 of yacc.c  */
 #line 740 "ncgen.y"
-    {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[(2) - (6)].sym),(yyvsp[(1) - (6)].sym),(void*)(yyvsp[(6) - (6)].datalist),0);}
+    {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[(2) - (6)].sym),(yyvsp[(1) - (6)].sym),(void*)(yyvsp[(6) - (6)].datalist),0);;}
     break;
 
   case 96:
-
-/* Line 1806 of yacc.c  */
 #line 742 "ncgen.y"
-    {(yyval.sym) = makespecial(_STORAGE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);}
+    {(yyval.sym) = makespecial(_STORAGE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;}
     break;
 
   case 97:
-
-/* Line 1806 of yacc.c  */
 #line 744 "ncgen.y"
-    {(yyval.sym) = makespecial(_CHUNKSIZES_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)(yyvsp[(5) - (5)].datalist),0);}
+    {(yyval.sym) = makespecial(_CHUNKSIZES_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)(yyvsp[(5) - (5)].datalist),0);;}
     break;
 
   case 98:
-
-/* Line 1806 of yacc.c  */
 #line 746 "ncgen.y"
-    {(yyval.sym) = makespecial(_FLETCHER32_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);}
+    {(yyval.sym) = makespecial(_FLETCHER32_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;}
     break;
 
   case 99:
-
-/* Line 1806 of yacc.c  */
 #line 748 "ncgen.y"
-    {(yyval.sym) = makespecial(_DEFLATE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);}
+    {(yyval.sym) = makespecial(_DEFLATE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;}
     break;
 
   case 100:
-
-/* Line 1806 of yacc.c  */
 #line 750 "ncgen.y"
-    {(yyval.sym) = makespecial(_SHUFFLE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);}
+    {(yyval.sym) = makespecial(_SHUFFLE_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;}
     break;
 
   case 101:
-
-/* Line 1806 of yacc.c  */
 #line 752 "ncgen.y"
-    {(yyval.sym) = makespecial(_ENDIAN_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);}
+    {(yyval.sym) = makespecial(_ENDIAN_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;}
     break;
 
   case 102:
-
-/* Line 1806 of yacc.c  */
 #line 754 "ncgen.y"
-    {(yyval.sym) = makespecial(_NOFILL_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);}
+    {(yyval.sym) = makespecial(_NOFILL_FLAG,(yyvsp[(1) - (5)].sym),NULL,(void*)&(yyvsp[(5) - (5)].constant),1);;}
     break;
 
   case 103:
-
-/* Line 1806 of yacc.c  */
 #line 756 "ncgen.y"
-    {(yyval.sym) = makespecial(_FORMAT_FLAG,NULL,NULL,(void*)&(yyvsp[(4) - (4)].constant),1);}
+    {(yyval.sym) = makespecial(_FORMAT_FLAG,NULL,NULL,(void*)&(yyvsp[(4) - (4)].constant),1);;}
     break;
 
   case 104:
-
-/* Line 1806 of yacc.c  */
 #line 761 "ncgen.y"
     {
 	        (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 105:
-
-/* Line 1806 of yacc.c  */
 #line 768 "ncgen.y"
     {
 	        (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*/
-	    }
+	    ;}
     break;
 
   case 107:
-
-/* Line 1806 of yacc.c  */
 #line 777 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 108:
-
-/* Line 1806 of yacc.c  */
 #line 778 "ncgen.y"
-    {}
+    {;}
     break;
 
   case 111:
-
-/* Line 1806 of yacc.c  */
 #line 786 "ncgen.y"
-    {(yyvsp[(1) - (3)].sym)->data = (yyvsp[(3) - (3)].datalist);}
+    {(yyvsp[(1) - (3)].sym)->data = (yyvsp[(3) - (3)].datalist);;}
     break;
 
   case 112:
-
-/* Line 1806 of yacc.c  */
 #line 789 "ncgen.y"
-    {(yyval.datalist) = (yyvsp[(1) - (1)].datalist);}
+    {(yyval.datalist) = (yyvsp[(1) - (1)].datalist);;}
     break;
 
   case 113:
-
-/* Line 1806 of yacc.c  */
 #line 790 "ncgen.y"
-    {(yyval.datalist) = (yyvsp[(1) - (1)].datalist);}
+    {(yyval.datalist) = (yyvsp[(1) - (1)].datalist);;}
     break;
 
   case 114:
-
-/* Line 1806 of yacc.c  */
 #line 794 "ncgen.y"
-    {(yyval.datalist) = builddatalist(0);}
+    {(yyval.datalist) = builddatalist(0);;}
     break;
 
   case 115:
-
-/* Line 1806 of yacc.c  */
 #line 798 "ncgen.y"
-    {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[(1) - (1)].constant)));}
+    {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[(1) - (1)].constant)));;}
     break;
 
   case 116:
-
-/* Line 1806 of yacc.c  */
 #line 800 "ncgen.y"
-    {datalistextend((yyvsp[(1) - (3)].datalist),&((yyvsp[(3) - (3)].constant))); (yyval.datalist)=(yyvsp[(1) - (3)].datalist);}
+    {datalistextend((yyvsp[(1) - (3)].datalist),&((yyvsp[(3) - (3)].constant))); (yyval.datalist)=(yyvsp[(1) - (3)].datalist);;}
     break;
 
   case 117:
-
-/* Line 1806 of yacc.c  */
 #line 804 "ncgen.y"
-    {(yyval.constant)=(yyvsp[(1) - (1)].constant);}
+    {(yyval.constant)=(yyvsp[(1) - (1)].constant);;}
     break;
 
   case 118:
-
-/* Line 1806 of yacc.c  */
 #line 805 "ncgen.y"
-    {(yyval.constant)=builddatasublist((yyvsp[(2) - (3)].datalist));}
+    {(yyval.constant)=builddatasublist((yyvsp[(2) - (3)].datalist));;}
     break;
 
   case 119:
-
-/* Line 1806 of yacc.c  */
 #line 809 "ncgen.y"
-    {(yyval.constant)=(yyvsp[(1) - (1)].constant);}
+    {(yyval.constant)=(yyvsp[(1) - (1)].constant);;}
     break;
 
   case 120:
-
-/* Line 1806 of yacc.c  */
 #line 810 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_OPAQUE);}
+    {(yyval.constant)=makeconstdata(NC_OPAQUE);;}
     break;
 
   case 121:
-
-/* Line 1806 of yacc.c  */
 #line 811 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_FILLVALUE);}
+    {(yyval.constant)=makeconstdata(NC_FILLVALUE);;}
     break;
 
   case 122:
-
-/* Line 1806 of yacc.c  */
 #line 812 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_NIL);}
+    {(yyval.constant)=makeconstdata(NC_NIL);;}
     break;
 
   case 123:
-
-/* Line 1806 of yacc.c  */
 #line 813 "ncgen.y"
-    {(yyval.constant)=(yyvsp[(1) - (1)].constant);}
+    {(yyval.constant)=(yyvsp[(1) - (1)].constant);;}
     break;
 
   case 125:
-
-/* Line 1806 of yacc.c  */
 #line 818 "ncgen.y"
-    {(yyval.constant) = makeenumconstref((yyvsp[(1) - (1)].sym));}
+    {(yyval.constant) = makeenumconstref((yyvsp[(1) - (1)].sym));;}
     break;
 
   case 126:
-
-/* Line 1806 of yacc.c  */
 #line 822 "ncgen.y"
-    {(yyval.constant)=evaluate((yyvsp[(1) - (4)].sym),(yyvsp[(3) - (4)].datalist));}
+    {(yyval.constant)=evaluate((yyvsp[(1) - (4)].sym),(yyvsp[(3) - (4)].datalist));;}
     break;
 
   case 127:
-
-/* Line 1806 of yacc.c  */
 #line 827 "ncgen.y"
-    {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[(1) - (1)].constant)));}
+    {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[(1) - (1)].constant)));;}
     break;
 
   case 128:
-
-/* Line 1806 of yacc.c  */
 #line 829 "ncgen.y"
-    {datalistextend((yyvsp[(1) - (3)].datalist),&((yyvsp[(3) - (3)].constant))); (yyval.datalist)=(yyvsp[(1) - (3)].datalist);}
+    {datalistextend((yyvsp[(1) - (3)].datalist),&((yyvsp[(3) - (3)].constant))); (yyval.datalist)=(yyvsp[(1) - (3)].datalist);;}
     break;
 
   case 129:
-
-/* Line 1806 of yacc.c  */
 #line 833 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_CHAR);}
+    {(yyval.constant)=makeconstdata(NC_CHAR);;}
     break;
 
   case 130:
-
-/* Line 1806 of yacc.c  */
 #line 834 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_BYTE);}
+    {(yyval.constant)=makeconstdata(NC_BYTE);;}
     break;
 
   case 131:
-
-/* Line 1806 of yacc.c  */
 #line 835 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_SHORT);}
+    {(yyval.constant)=makeconstdata(NC_SHORT);;}
     break;
 
   case 132:
-
-/* Line 1806 of yacc.c  */
 #line 836 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_INT);}
+    {(yyval.constant)=makeconstdata(NC_INT);;}
     break;
 
   case 133:
-
-/* Line 1806 of yacc.c  */
 #line 837 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_INT64);}
+    {(yyval.constant)=makeconstdata(NC_INT64);;}
     break;
 
   case 134:
-
-/* Line 1806 of yacc.c  */
 #line 838 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_UBYTE);}
+    {(yyval.constant)=makeconstdata(NC_UBYTE);;}
     break;
 
   case 135:
-
-/* Line 1806 of yacc.c  */
 #line 839 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_USHORT);}
+    {(yyval.constant)=makeconstdata(NC_USHORT);;}
     break;
 
   case 136:
-
-/* Line 1806 of yacc.c  */
 #line 840 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_UINT);}
+    {(yyval.constant)=makeconstdata(NC_UINT);;}
     break;
 
   case 137:
-
-/* Line 1806 of yacc.c  */
 #line 841 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_UINT64);}
+    {(yyval.constant)=makeconstdata(NC_UINT64);;}
     break;
 
   case 138:
-
-/* Line 1806 of yacc.c  */
 #line 842 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_FLOAT);}
+    {(yyval.constant)=makeconstdata(NC_FLOAT);;}
     break;
 
   case 139:
-
-/* Line 1806 of yacc.c  */
 #line 843 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_DOUBLE);}
+    {(yyval.constant)=makeconstdata(NC_DOUBLE);;}
     break;
 
   case 140:
-
-/* Line 1806 of yacc.c  */
 #line 844 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_STRING);}
+    {(yyval.constant)=makeconstdata(NC_STRING);;}
     break;
 
   case 141:
-
-/* Line 1806 of yacc.c  */
 #line 848 "ncgen.y"
-    {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[(1) - (1)].constant)));}
+    {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[(1) - (1)].constant)));;}
     break;
 
   case 142:
-
-/* Line 1806 of yacc.c  */
 #line 849 "ncgen.y"
-    {(yyval.datalist)=(yyvsp[(1) - (3)].datalist); datalistextend((yyvsp[(1) - (3)].datalist),&((yyvsp[(3) - (3)].constant)));}
+    {(yyval.datalist)=(yyvsp[(1) - (3)].datalist); datalistextend((yyvsp[(1) - (3)].datalist),&((yyvsp[(3) - (3)].constant)));;}
     break;
 
   case 143:
-
-/* Line 1806 of yacc.c  */
 #line 854 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_INT);}
+    {(yyval.constant)=makeconstdata(NC_INT);;}
     break;
 
   case 144:
-
-/* Line 1806 of yacc.c  */
 #line 856 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_UINT);}
+    {(yyval.constant)=makeconstdata(NC_UINT);;}
     break;
 
   case 145:
-
-/* Line 1806 of yacc.c  */
 #line 858 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_INT64);}
+    {(yyval.constant)=makeconstdata(NC_INT64);;}
     break;
 
   case 146:
-
-/* Line 1806 of yacc.c  */
 #line 860 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_UINT64);}
+    {(yyval.constant)=makeconstdata(NC_UINT64);;}
     break;
 
   case 147:
-
-/* Line 1806 of yacc.c  */
 #line 864 "ncgen.y"
-    {(yyval.constant)=makeconstdata(NC_STRING);}
+    {(yyval.constant)=makeconstdata(NC_STRING);;}
     break;
 
   case 148:
-
-/* Line 1806 of yacc.c  */
 #line 868 "ncgen.y"
-    {(yyval.constant)=(yyvsp[(1) - (1)].constant);}
+    {(yyval.constant)=(yyvsp[(1) - (1)].constant);;}
     break;
 
   case 149:
-
-/* Line 1806 of yacc.c  */
 #line 869 "ncgen.y"
-    {(yyval.constant)=(yyvsp[(1) - (1)].constant);}
+    {(yyval.constant)=(yyvsp[(1) - (1)].constant);;}
     break;
 
   case 150:
-
-/* Line 1806 of yacc.c  */
 #line 875 "ncgen.y"
-    {(yyval.sym)=(yyvsp[(1) - (1)].sym);}
+    {(yyval.sym)=(yyvsp[(1) - (1)].sym);;}
     break;
 
 
-
-/* Line 1806 of yacc.c  */
-#line 2975 "ncgentab.c"
+/* Line 1267 of yacc.c.  */
+#line 2736 "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);
@@ -2993,6 +2743,7 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 
   *++yyvsp = yyval;
 
+
   /* 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.  */
@@ -3012,10 +2763,6 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[(1) - (3)].sym)->name);
 | 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)
     {
@@ -3023,36 +2770,37 @@ yyerrlab:
 #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
     }
 
@@ -3060,7 +2808,7 @@ yyerrlab:
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse lookahead token after an
+      /* If just tried and failed to reuse look-ahead token after an
 	 error, discard it.  */
 
       if (yychar <= YYEOF)
@@ -3077,7 +2825,7 @@ yyerrlab:
 	}
     }
 
-  /* 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;
 
@@ -3111,7 +2859,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
+      if (yyn != YYPACT_NINF)
 	{
 	  yyn += YYTERROR;
 	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -3134,6 +2882,9 @@ yyerrlab1:
       YY_STACK_PRINT (yyss, yyssp);
     }
 
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
   *++yyvsp = yylval;
 
 
@@ -3158,7 +2909,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#ifndef yyoverflow
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -3169,14 +2920,9 @@ yyexhaustedlab:
 #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);
-    }
+  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);
@@ -3200,8 +2946,6 @@ yyreturn:
 }
 
 
-
-/* Line 2067 of yacc.c  */
 #line 878 "ncgen.y"
 
 
@@ -3231,7 +2975,7 @@ ncgwrap(void)                    /* returns 1 on EOF if no more input */
 }
 
 /* get lexical input routine generated by lex  */
-#include "ncgenyy.c"
+#include "ncgenl.c"
 
 /* Really should init our data within this file */
 void
diff --git a/ncgen/ncgentab.h b/ncgen/ncgeny.h
similarity index 63%
rename from ncgen/ncgentab.h
rename to ncgen/ncgeny.h
index 09bc5fa..9d2e192 100644
--- a/ncgen/ncgentab.h
+++ b/ncgen/ncgeny.h
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
-/* Bison interface for Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+   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
    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
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    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 <http://www.gnu.org/licenses/>.  */
+   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
@@ -26,11 +29,10 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-
 /* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
@@ -87,33 +89,77 @@
      DATASETID = 305
    };
 #endif
+/* Tokens.  */
+#define NC_UNLIMITED_K 258
+#define CHAR_K 259
+#define BYTE_K 260
+#define SHORT_K 261
+#define INT_K 262
+#define FLOAT_K 263
+#define DOUBLE_K 264
+#define UBYTE_K 265
+#define USHORT_K 266
+#define UINT_K 267
+#define INT64_K 268
+#define UINT64_K 269
+#define IDENT 270
+#define TERMSTRING 271
+#define CHAR_CONST 272
+#define BYTE_CONST 273
+#define SHORT_CONST 274
+#define INT_CONST 275
+#define INT64_CONST 276
+#define UBYTE_CONST 277
+#define USHORT_CONST 278
+#define UINT_CONST 279
+#define UINT64_CONST 280
+#define FLOAT_CONST 281
+#define DOUBLE_CONST 282
+#define DIMENSIONS 283
+#define VARIABLES 284
+#define NETCDF 285
+#define DATA 286
+#define TYPES 287
+#define COMPOUND 288
+#define ENUM 289
+#define OPAQUE 290
+#define OPAQUESTRING 291
+#define GROUP 292
+#define PATH 293
+#define FILLMARKER 294
+#define NIL 295
+#define _FILLVALUE 296
+#define _FORMAT 297
+#define _STORAGE 298
+#define _CHUNKSIZES 299
+#define _DEFLATELEVEL 300
+#define _SHUFFLE 301
+#define _ENDIANNESS 302
+#define _NOFILL 303
+#define _FLETCHER32 304
+#define DATASETID 305
+
 
 
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-{
-
-/* Line 2068 of yacc.c  */
 #line 131 "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 2068 of yacc.c  */
-#line 111 "ncgentab.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 1529 of yacc.c.  */
+#line 158 "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;
 
-
diff --git a/ncgen/offsets.h b/ncgen/offsets.h
index 4233231..eeef434 100644
--- a/ncgen/offsets.h
+++ b/ncgen/offsets.h
@@ -10,7 +10,7 @@
 
 typedef struct Alignment {
     char* typename;
-    int alignment;
+    unsigned int alignment;
 } Alignment;
 
 /* Define indices for every primitive C type */
diff --git a/ncgen/run_nc4_tests.sh b/ncgen/run_nc4_tests.sh
index 72de82b..794c15a 100755
--- a/ncgen/run_nc4_tests.sh
+++ b/ncgen/run_nc4_tests.sh
@@ -2,12 +2,17 @@
 # This shell script runs the ncdump tests.
 # $Id: run_nc4_tests.sh,v 1.4 2010/05/18 20:05:23 dmh Exp $
 
+if test "x$srcdir" = x ; then srcdir="."; fi
+
 echo "*** Testing ncgen for netCDF-4."
 set -e
+
 echo "*** creating netCDF-4 file c0_4.nc from c0_4.cdl..."
 ./ncgen -k nc4 -b -o c0_4.nc $srcdir/c0_4.cdl
+
 echo "*** creating netCDF-4 classic model file c0_4c.nc from c0.cdl..."
 ./ncgen -k nc7 -b -o c0_4c.nc $srcdir/c0.cdl
+
 echo "*** creating C code for CAM file ref_camrun.cdl..."
 ./ncgen -lc $srcdir/ref_camrun.cdl >ref_camrun.c
 
diff --git a/ncgen/run_tests.sh b/ncgen/run_tests.sh
index fc1bdc8..aecc018 100755
--- a/ncgen/run_tests.sh
+++ b/ncgen/run_tests.sh
@@ -8,6 +8,7 @@ fi
 
 echo "*** Testing ncgen."
 set -e
+
 echo "*** creating classic file c0.nc from c0.cdl..."
 ./ncgen -b -o c0.nc $srcdir/c0.cdl
 if [ ! -f c0.nc ]; then
@@ -29,6 +30,5 @@ if [ ! -f c5.nc ]; then
     exit 1
 fi
 
-
 echo "*** Test successful!"
 exit 0
diff --git a/ncgen/semantics.c b/ncgen/semantics.c
index 5a941f9..b8a30b7 100644
--- a/ncgen/semantics.c
+++ b/ncgen/semantics.c
@@ -174,7 +174,7 @@ Return NULL if symbol is not unique or not found at all.
 static Symbol*
 uniquetreelocate(Symbol* refsym, Symbol* root)
 {
-    int i;
+    unsigned long i;
     Symbol* sym = NULL;
     /* search the root for matching name and major type*/
     sym = lookupingroup(refsym->objectclass,refsym->name,root);
@@ -200,7 +200,7 @@ Compute the fqn for every top-level definition symbol
 static void
 computefqns(void)
 {
-    int i,j;
+    unsigned long i,j;
     /* Groups first */
     for(i=0;i<listlength(grpdefs);i++) {
         Symbol* sym = (Symbol*)listget(grpdefs,i);
@@ -259,7 +259,8 @@ computefqns(void)
 static void
 processtypes(void)
 {
-    int i,j,keep,added;
+    unsigned long i,j;
+    int keep,added;
     List* sorted = listnew(); /* hold re-ordered type set*/
     /* Prime the walk by capturing the set*/
     /*     of types that are dependent on primitive types*/
@@ -352,7 +353,7 @@ static int
 tagvlentypes(Symbol* tsym)
 {
     int tagged = 0;
-    int j;
+    unsigned long j;
     switch (tsym->subclass) {
         case NC_VLEN: 
 	    tagged = 1;
@@ -385,7 +386,7 @@ filltypecodes(void)
 static void
 processenums(void)
 {
-    int i,j;
+    unsigned long i,j;
     List* enumids = listnew();
     for(i=0;i<listlength(typdefs);i++) {
 	Symbol* sym = (Symbol*)listget(typdefs,i);
@@ -419,7 +420,7 @@ processenums(void)
 static void
 processeconstrefs(void)
 {
-    int i;
+    unsigned long i;
     /* locate all the datalist and walk them recursively */
     for(i=0;i<listlength(attdefs);i++) {
 	Symbol* att = (Symbol*)listget(attdefs,i);
@@ -774,29 +775,111 @@ processattributes(void)
 }
 
 /*
- Look at the first primitive value of the
- attribute's datalist to infer the type of the attribute.
- There is a potential ambiguity when that value is a string.
- Is the attribute type NC_CHAR or NC_STRING?
- The answer is we always assume it is NC_CHAR in order to
- be back compatible with ncgen.
+Given two types, attempt to upgrade to the "bigger type"
+Rules:
+- type size has precedence over signed/unsigned:
+   e.g. NC_INT over NC_UBYTE
 */
+static nc_type
+infertype(nc_type prior, nc_type next, int hasneg)
+{
+    nc_type sp, sn;
+    /* assert isinttype(prior) && isinttype(next) */
+    if(prior == NC_NAT) return next;
+    if(prior == next) return next;
+    sp = signedtype(prior);
+    sn = signedtype(next);
+    if(sp <= sn)
+	return next;
+    if(sn < sp)
+	return prior;
+    return NC_NAT; /* all other cases illegal */
+}
 
+/*
+Collect info by repeated walking of the attribute value list.
+*/
 static nc_type
 inferattributetype1(Datasrc* src)
 {
     nc_type result = NC_NAT;
-    /* Recurse down any enclosing compound markers to find first non-fill "primitive"*/
-    while(result == NC_NAT && srcmore(src)) {
-	if(issublist(src)) {
-	    srcpush(src);
-	    result = inferattributetype1(src);
-	    srcpop(src);
-	} else {	
-	    NCConstant* con = srcnext(src);
-	    if(isprimplus(con->nctype)) result = con->nctype;
-	    /* else keep looking*/
+    int hasneg = 0;
+    int stringcount = 0;
+    int charcount = 0;
+    int forcefloat = 0;
+    int forcedouble = 0;
+    int forceuint64 = 0;
+
+    /* Walk the top level set of attribute values to ensure non-nesting */
+    while(srcmore(src)) {
+	NCConstant* con = srcnext(src);
+	if(con == NULL) return NC_NAT;
+	if(con->nctype > NC_MAX_ATOMIC_TYPE) { /* illegal */
+	    return NC_NAT;
 	}
+	srcnext(src);
+    }	    
+    /* Walk repeatedly to get info for inference (loops could be combined) */
+
+    /* Compute: all strings or chars? */
+    srcreset(src);
+    stringcount = 0;
+    charcount = 0;
+    while(srcmore(src)) {
+	NCConstant* con = srcnext(src);
+	if(con->nctype == NC_STRING) stringcount++;
+	else if(con->nctype == NC_CHAR) charcount++;
+    }
+    if((stringcount+charcount) > 0) {
+        if((stringcount+charcount) < srclen(src)) 
+	    return NC_NAT; /* not all textual */
+	return NC_CHAR;
+    }
+
+    /* Compute: any floats/doubles? */
+    srcreset(src);
+    forcefloat = 0;
+    forcedouble = 0;
+    while(srcmore(src)) {
+	NCConstant* con = srcnext(src);
+	if(con->nctype == NC_FLOAT) forcefloat = 1;
+	else if(con->nctype == NC_DOUBLE) {forcedouble=1; break;}
+    }
+    if(forcedouble) return NC_DOUBLE;
+    if(forcefloat)  return NC_FLOAT;
+
+    /* At this point all the constants should be integers */
+
+    /* Compute: are there any uint64 values > NC_MAX_INT64? */
+    srcreset(src);
+    forceuint64 = 0;
+    while(srcmore(src)) {
+	NCConstant* con = srcnext(src);
+	if(con->nctype != NC_UINT64) continue;
+	if(con->value.uint64v > NC_MAX_INT64) {forceuint64=1; break;}
+    }
+    if(forceuint64)
+	return NC_UINT64;
+
+    /* Compute: are there any negative constants? */
+    srcreset(src);
+    hasneg = 0;
+    while(srcmore(src)) {
+	NCConstant* con = srcnext(src);
+	switch (con->nctype) {
+	case NC_BYTE :   if(con->value.int8v < 0)   {hasneg = 1;} break;
+	case NC_SHORT:   if(con->value.int16v < 0)  {hasneg = 1;} break;
+	case NC_INT:     if(con->value.int32v < 0)  {hasneg = 1;} break;
+	}	
+    }
+
+    /* Compute: inferred integer type */
+    srcreset(src);
+    result = NC_NAT;
+    while(srcmore(src)) {
+	NCConstant* con = srcnext(src);
+	result = infertype(result,con->nctype,hasneg);	
+	if(result == NC_NAT) break; /* something wrong */
     }
     return result;
 }
@@ -817,6 +900,10 @@ inferattributetype(Symbol* asym)
     src = datalist2src(datalist);
     nctype = inferattributetype1(src);    
     freedatasrc(src);
+    if(nctype == NC_NAT) { /* Illegal attribute value list */
+	semerror(asym->lineno,"Non-simple list of values for untyped attribute: %s",fullname(asym));
+	return;
+    }
     /* get the corresponding primitive type built-in symbol*/
     /* special case for string*/
     if(nctype == NC_STRING)
diff --git a/ncgen/util.c b/ncgen/util.c
index 56a2543..2f07b50 100644
--- a/ncgen/util.c
+++ b/ncgen/util.c
@@ -255,6 +255,65 @@ isbounded(Dimset* dimset)
 }
 
 int
+signedtype(nc_type nctype)
+{
+    switch (nctype) {
+    case NC_BYTE:
+    case NC_SHORT:
+    case NC_INT:
+    case NC_INT64:
+	return nctype;
+    case NC_UBYTE: return NC_BYTE;
+    case NC_USHORT: return NC_SHORT;
+    case NC_UINT: return NC_INT;
+    case NC_UINT64: return NC_INT64;
+    default: break;
+    }
+    return nctype;
+}
+
+int
+unsignedtype(nc_type nctype)
+{
+    switch (nctype) {
+    case NC_UBYTE:
+    case NC_USHORT:
+    case NC_UINT:
+    case NC_UINT64:
+	return nctype;
+    case NC_BYTE: return NC_UBYTE;
+    case NC_SHORT: return NC_USHORT;
+    case NC_INT: return NC_UINT;
+    case NC_INT64: return NC_UINT64;
+    default: break;
+    }
+    return nctype;
+}
+
+int
+isinttype(nc_type nctype)
+{
+    return (nctype != NC_CHAR)
+            && ((nctype >= NC_BYTE && nctype <= NC_INT)
+	        || (nctype >= NC_UBYTE && nctype <= NC_UINT64));
+}
+
+int
+isuinttype(nc_type t)
+{
+    return isinttype(t)
+	   && t >= NC_UBYTE
+           && t <= NC_UINT64
+           && t != NC_INT64;
+}
+
+int
+isfloattype(nc_type nctype)
+{
+    return (nctype == NC_FLOAT || nctype <= NC_DOUBLE);
+}
+
+int
 isclassicprim(nc_type nctype)
 {
     return    (nctype >= NC_BYTE && nctype <= NC_DOUBLE)
diff --git a/ncgen/util.h b/ncgen/util.h
index 7b5f9fa..8aa9dfd 100644
--- a/ncgen/util.h
+++ b/ncgen/util.h
@@ -8,7 +8,6 @@
 
 #define MAX(x,y) ((x)>(y)?(x):(y))
 
-
 extern void expe2d(char*);
 extern int pow2(int);
 extern void tztrim(char*);
@@ -27,7 +26,13 @@ extern char* nctypename(nc_type);
 extern char* ncclassname(nc_class);
 extern int ncsize(nc_type);
 
+extern nc_type signedtype(nc_type nctype);
+extern nc_type unsignedtype(nc_type nctype);
+
 /* We have several versions of primitive testing*/
+extern int isinttype(nc_type nctype); /* some kind of integer*/
+extern int isuinttype(nc_type nctype); /* some kind of integer*/
+extern int isfloattype(nc_type nctype); /* some kind of float*/
 extern int isclassicprim(nc_type); /* a classic primitive type*/
 extern int isclassicprimplus(nc_type); /* classic + String*/
 extern int isprim(nc_type); /* a netcdf4 primitive type*/
diff --git a/ncgen3/Makefile.in b/ncgen3/Makefile.in
index 7751bd4..2b6a290 100644
--- a/ncgen3/Makefile.in
+++ b/ncgen3/Makefile.in
@@ -452,7 +452,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/nctest/Makefile.in b/nctest/Makefile.in
index 484d8de..4fbb31e 100644
--- a/nctest/Makefile.in
+++ b/nctest/Makefile.in
@@ -461,7 +461,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
diff --git a/nctest/atttests.c b/nctest/atttests.c
index 5e3a437..6cd41bc 100644
--- a/nctest/atttests.c
+++ b/nctest/atttests.c
@@ -1293,7 +1293,7 @@ test_ncattdel(path)
 	error("%s: ncinquire in data mode failed", pname);
 	ncclose(cdfid); return ++nerrs;
     }
-    vtmp.dims = (int *) emalloc(sizeof(int) * MAX_VAR_DIMS);
+    vtmp.dims = (int *) emalloc(sizeof(int) * NC_MAX_VAR_DIMS);
     vtmp.name = (char *) emalloc(MAX_NC_NAME);
     if (ncvarinq(cdfid, yav_id, vtmp.name, &vtmp.type, &vtmp.ndims, vtmp.dims,
 		  &natts) == -1) {
diff --git a/oc2/CMakeLists.txt b/oc2/CMakeLists.txt
index de38840..0a0fae1 100644
--- a/oc2/CMakeLists.txt
+++ b/oc2/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(oc_SOURCES oc.c daplex.c dapparse.c daptab.c occlientparams.c occompile.c occurlfunctions.c ocdata.c ocdebug.c ocdump.c ocinternal.c ocnode.c ochttp.c ocrc.c ocread.c ocutil.c ocbytes.c oclist.c ocuri.c oclog.c occurlflags.c xxdr.c)
+SET(oc_SOURCES oc.c daplex.c dapparse.c dapy.c occlientparams.c occompile.c occurlfunctions.c ocdata.c ocdebug.c ocdump.c ocinternal.c ocnode.c ochttp.c ocrc.c ocread.c ocutil.c ocbytes.c oclist.c ocuri.c oclog.c occurlflags.c xxdr.c)
 
 add_library(oc2 OBJECT ${oc_SOURCES}) 
 
diff --git a/oc2/Make0 b/oc2/Make0
index de8a136..9d2b8fb 100755
--- a/oc2/Make0
+++ b/oc2/Make0
@@ -6,7 +6,7 @@ THISDIR=../oc2
 
 # Make consistent with Makefile.am
 SRC=oc.c \
-daplex.c dapparse.c daptab.c \
+daplex.c dapparse.c dapy.c \
 occlientparams.c occompile.c occurlfunctions.c \
 ocdata.c ocdebug.c ocdump.c  \
 ocinternal.c ocnode.c \
@@ -17,7 +17,7 @@ occurlflags.c \
 xxdr.c
 
 HDRS=oc.h ocx.h \
-dapparselex.h daptab.h \
+dapparselex.h dapy.h \
 occlientparams.h occompile.h occonstraints.h occurlfunctions.h \
 ocdata.h ocdatatypes.h ocdebug.h ocdump.h \
 ocinternal.h ocnode.h \
@@ -47,7 +47,7 @@ makeoc::
 	# This should match the bison command in Makefile.am
 	rm -f dap.tab.c dap.tab.h
 	bison --debug -d -p dap dap.y
-	mv dap.tab.c daptab.c; mv dap.tab.h daptab.h
+	mv dap.tab.c dapy.c; mv dap.tab.h dapy.h
 
 changed:
 	${MAKE} -f Make0 NAMEONLY=1 diffoc
@@ -57,7 +57,7 @@ diffoc::
 	@for file in ${FILES} ; do \
 	    f="${OCDIR}/$$file" ; \
 	    x=`basename $$f|tr -d '
' ` ; \
-	    if test "x$${x}" = "xdaptab.c" -o "x$${x}" = "xdaptab.h" ; then echo "ignore: $${x}"; continue; fi ;\
+	    if test "x$${x}" = "xdapy.c" -o "x$${x}" = "xdapy.h" ; then echo "ignore: $${x}"; continue; fi ;\
 	    if ! test -e ${THISDIR}/$$x ; then \
 		echo "Missing file: $$x"; \
 	    fi ; \
@@ -78,7 +78,7 @@ olddiff::
 	for file in ${FILES} ; do \
 	    f="${OCDIR}/$$file" ; \
 	    x=`basename $$f | tr -d '
' ` ; \
-	    if test "x$${x}" = "xdaptab.c" -o "x$${x}" = "xdaptab.h" ; then echo "ignore: $${x}"; continue; fi ;\
+	    if test "x$${x}" = "xdapy.c" -o "x$${x}" = "xdapy.h" ; then echo "ignore: $${x}"; continue; fi ;\
 	    if test -e ${THISDIR}/$$x -a -e ${OCDIR}/$$x ; then \
 		diff --brief -wBb ${THISDIR}/$$x $$f ; \
 	    else \
@@ -88,7 +88,7 @@ olddiff::
 	for file in ${FILES} ; do \
 	    f="${OCDIR}/$$file" ; \
 	    x=`basename $$f|tr -d '
' ` ; \
-	    if test "x$${x}" = "xdaptab.c" -o "x$${x}" = "xdaptab.h" ; then echo "ignore: $${x}"; continue; fi ;\
+	    if test "x$${x}" = "xdapy.c" -o "x$${x}" = "xdapy.h" ; then echo "ignore: $${x}"; continue; fi ;\
 	    if test -e ${THISDIR}/$$x -a -e ${OCDIR}/$$x ; then \
 		if ! diff --brief -wBb ${THISDIR}/$$x $$f > /dev/null ; then \
 		echo diff -wBb ${THISDIR}/$$x $$f ;\
diff --git a/oc2/Makefile.am b/oc2/Makefile.am
index 4ac66b4..df004e9 100755
--- a/oc2/Makefile.am
+++ b/oc2/Makefile.am
@@ -10,9 +10,9 @@
 # Cause C preprocessor to search current and parent directory.
 AM_CPPFLAGS =  -I.. -I$(top_srcdir) -I$(top_srcdir)/include
 
-# OC Sources; include the daptab.[ch] to avoid the need for bison by user
+# OC Sources; include the dapy.[ch] to avoid the need for bison by user
 SRC=oc.c \
-daplex.c dapparse.c daptab.c \
+daplex.c dapparse.c dapy.c \
 occlientparams.c occompile.c occurlfunctions.c \
 ocdata.c ocdebug.c ocdump.c  \
 ocinternal.c ocnode.c \
@@ -23,7 +23,7 @@ occurlflags.c \
 xxdr.c
 
 HDRS=oc.h ocx.h \
-dapparselex.h daptab.h \
+dapparselex.h dapy.h \
 occlientparams.h occompile.h occonstraints.h occurlfunctions.h \
 ocdata.h ocdatatypes.h ocdebug.h ocdump.h \
 ocinternal.h ocnode.h \
@@ -49,6 +49,6 @@ endif
 bison:: dap.y
 	rm -f dap.tab.c dap.tab.h
 	bison --debug -d -p dap dap.y
-	mv dap.tab.c daptab.c; mv dap.tab.h daptab.h
+	mv dap.tab.c dapy.c; mv dap.tab.h dapy.h
 
 
diff --git a/oc2/Makefile.in b/oc2/Makefile.in
index fd8ec59..eefcc5c 100644
--- a/oc2/Makefile.in
+++ b/oc2/Makefile.in
@@ -112,17 +112,17 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 liboc_la_LIBADD =
-am__liboc_la_SOURCES_DIST = oc.c daplex.c dapparse.c daptab.c \
+am__liboc_la_SOURCES_DIST = oc.c daplex.c dapparse.c dapy.c \
 	occlientparams.c occompile.c occurlfunctions.c ocdata.c \
 	ocdebug.c ocdump.c ocinternal.c ocnode.c ochttp.c ocrc.c \
 	ocread.c ocutil.c ocbytes.c oclist.c ocuri.c oclog.c \
-	occurlflags.c xxdr.c oc.h ocx.h dapparselex.h daptab.h \
+	occurlflags.c xxdr.c oc.h ocx.h dapparselex.h dapy.h \
 	occlientparams.h occompile.h occonstraints.h occurlfunctions.h \
 	ocdata.h ocdatatypes.h ocdebug.h ocdump.h ocinternal.h \
 	ocnode.h ochttp.h ocread.h ocutil.h ocbytes.h oclist.h ocuri.h \
 	oclog.h xxdr.h
 am__objects_1 = liboc_la-oc.lo liboc_la-daplex.lo liboc_la-dapparse.lo \
-	liboc_la-daptab.lo liboc_la-occlientparams.lo \
+	liboc_la-dapy.lo liboc_la-occlientparams.lo \
 	liboc_la-occompile.lo liboc_la-occurlfunctions.lo \
 	liboc_la-ocdata.lo liboc_la-ocdebug.lo liboc_la-ocdump.lo \
 	liboc_la-ocinternal.lo liboc_la-ocnode.lo liboc_la-ochttp.lo \
@@ -253,7 +253,6 @@ HAS_NC4 = @HAS_NC4@
 HAS_PARALLEL = @HAS_PARALLEL@
 HAS_PARALLEL4 = @HAS_PARALLEL4@
 HAS_PNETCDF = @HAS_PNETCDF@
-HAS_SZIP = @HAS_SZIP@
 HAS_SZLIB = @HAS_SZLIB@
 HAVE_DOT = @HAVE_DOT@
 INSTALL = @INSTALL@
@@ -375,9 +374,9 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 
-# OC Sources; include the daptab.[ch] to avoid the need for bison by user
+# OC Sources; include the dapy.[ch] to avoid the need for bison by user
 SRC = oc.c \
-daplex.c dapparse.c daptab.c \
+daplex.c dapparse.c dapy.c \
 occlientparams.c occompile.c occurlfunctions.c \
 ocdata.c ocdebug.c ocdump.c  \
 ocinternal.c ocnode.c \
@@ -388,7 +387,7 @@ occurlflags.c \
 xxdr.c
 
 HDRS = oc.h ocx.h \
-dapparselex.h daptab.h \
+dapparselex.h dapy.h \
 occlientparams.h occompile.h occonstraints.h occurlfunctions.h \
 ocdata.h ocdatatypes.h ocdebug.h ocdump.h \
 ocinternal.h ocnode.h \
@@ -456,7 +455,7 @@ distclean-compile:
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-daplex.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-dapparse.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-daptab.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-dapy.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-oc.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-ocbytes.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-occlientparams.Plo at am__quote@
@@ -522,12 +521,12 @@ liboc_la-dapparse.lo: dapparse.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liboc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o liboc_la-dapparse.lo `test -f 'dapparse.c' || echo '$(srcdir)/'`dapparse.c
 
-liboc_la-daptab.lo: daptab.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liboc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT liboc_la-daptab.lo -MD -MP -MF $(DEPDIR)/liboc_la-daptab.Tpo -c -o liboc_la-daptab.lo `test -f 'daptab.c' || echo '$(srcdir)/'`daptab.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/liboc_la-daptab.Tpo $(DEPDIR)/liboc_la-daptab.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='daptab.c' object='liboc_la-daptab.lo' libtool=yes @AMDEPBACKSLASH@
+liboc_la-dapy.lo: dapy.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liboc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT liboc_la-dapy.lo -MD -MP -MF $(DEPDIR)/liboc_la-dapy.Tpo -c -o liboc_la-dapy.lo `test -f 'dapy.c' || echo '$(srcdir)/'`dapy.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/liboc_la-dapy.Tpo $(DEPDIR)/liboc_la-dapy.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='dapy.c' object='liboc_la-dapy.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liboc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o liboc_la-daptab.lo `test -f 'daptab.c' || echo '$(srcdir)/'`daptab.c
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liboc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o liboc_la-dapy.lo `test -f 'dapy.c' || echo '$(srcdir)/'`dapy.c
 
 liboc_la-occlientparams.lo: occlientparams.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liboc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT liboc_la-occlientparams.lo -MD -MP -MF $(DEPDIR)/liboc_la-occlientparams.Tpo -c -o liboc_la-occlientparams.lo `test -f 'occlientparams.c' || echo '$(srcdir)/'`occlientparams.c
@@ -877,7 +876,7 @@ uninstall-am:
 bison:: dap.y
 	rm -f dap.tab.c dap.tab.h
 	bison --debug -d -p dap dap.y
-	mv dap.tab.c daptab.c; mv dap.tab.h daptab.h
+	mv dap.tab.c dapy.c; mv dap.tab.h dapy.h
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/oc2/auth.html.in b/oc2/auth.html.in
index 72a7aa7..383af61 100644
--- a/oc2/auth.html.in
+++ b/oc2/auth.html.in
@@ -2,7 +2,7 @@
 <!- See the COPYRIGHT file for more information. --> 
 <html> 
 <head>
-<link rel="stylesheet" type="text/css" href="oc.css">
+<!--css-->
 </head>
 <body> 
  
@@ -12,7 +12,7 @@
 <h1>Address: http://www.unidata.ucar.edu/staff/dmh/</h1>
 <h1>Draft: 11/21/2014</h1>
 <h1>Last Revised: 10/24/2015</h1>
-<OC><h1>ZZ Version 4.0</h1> 
+<OC><h1>ZZ Version VVVV</h1> 
 </div>
  
 <h1 class="toc">Table of Contents</h1> 
diff --git a/oc2/dap.y b/oc2/dap.y
index 73fc650..cf2569a 100644
--- a/oc2/dap.y
+++ b/oc2/dap.y
@@ -11,7 +11,7 @@
 %{
 #include "config.h"
 #include "dapparselex.h"
-#include "daptab.h"
+#include "dapy.h"
 int dapdebug = 0;
 %}
 
diff --git a/oc2/daplex.c b/oc2/daplex.c
index 274995f..08d69ad 100644
--- a/oc2/daplex.c
+++ b/oc2/daplex.c
@@ -6,7 +6,7 @@
 #include <strings.h>
 #endif
 #include "dapparselex.h"
-#include "daptab.h"
+#include "dapy.h"
 
 #undef URLCVT /* NEVER turn this on */
 
diff --git a/oc2/dapparse.c b/oc2/dapparse.c
index e8a6365..148278a 100644
--- a/oc2/dapparse.c
+++ b/oc2/dapparse.c
@@ -4,7 +4,7 @@
 
 #include "config.h"
 #include "dapparselex.h"
-#include "daptab.h"
+#include "dapy.h"
 
 /* Forward */
 
diff --git a/oc2/daptab.c b/oc2/dapy.c
similarity index 64%
rename from oc2/daptab.c
rename to oc2/dapy.c
index 1014c72..e2af8b2 100644
--- a/oc2/daptab.c
+++ b/oc2/dapy.c
@@ -1,19 +1,19 @@
-/* A Bison parser, made by GNU Bison 3.0.  */
+/* A Bison parser, made by GNU Bison 2.5.  */
 
 /* Bison implementation for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
-
+   
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+   
    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.
-
+   
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    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 <http://www.gnu.org/licenses/>.  */
 
@@ -26,7 +26,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -44,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0"
+#define YYBISON_VERSION "2.5"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -58,32 +58,37 @@
 /* Pull parsers.  */
 #define YYPULL 1
 
+/* Using locations.  */
+#define YYLSP_NEEDED 0
 
 /* Substitute the variable and function names.  */
 #define yyparse         dapparse
 #define yylex           daplex
 #define yyerror         daperror
+#define yylval          daplval
+#define yychar          dapchar
 #define yydebug         dapdebug
 #define yynerrs         dapnerrs
 
 
 /* Copy the first part of user declarations.  */
-#line 11 "dap.y" /* yacc.c:339  */
+
+/* Line 268 of yacc.c  */
+#line 11 "dap.y"
 
 #include "config.h"
 #include "dapparselex.h"
-#include "daptab.h"
+#include "dapy.h"
 int dapdebug = 0;
 
-#line 79 "dap.tab.c" /* yacc.c:339  */
 
-# ifndef YY_NULL
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULL nullptr
-#  else
-#   define YY_NULL 0
-#  endif
-# endif
+/* Line 268 of yacc.c  */
+#line 87 "dap.tab.c"
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -93,67 +98,61 @@ int dapdebug = 0;
 # define YYERROR_VERBOSE 1
 #endif
 
-/* In a future release of Bison, this section will be replaced
-   by #include "dap.tab.h".  */
-#ifndef YY_DAP_DAP_TAB_H_INCLUDED
-# define YY_DAP_DAP_TAB_H_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
-#if YYDEBUG
-extern int dapdebug;
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
 #endif
 
-/* Token type.  */
+
+/* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
-  enum yytokentype
-  {
-    SCAN_ALIAS = 258,
-    SCAN_ARRAY = 259,
-    SCAN_ATTR = 260,
-    SCAN_BYTE = 261,
-    SCAN_CODE = 262,
-    SCAN_DATASET = 263,
-    SCAN_DATA = 264,
-    SCAN_ERROR = 265,
-    SCAN_FLOAT32 = 266,
-    SCAN_FLOAT64 = 267,
-    SCAN_GRID = 268,
-    SCAN_INT16 = 269,
-    SCAN_INT32 = 270,
-    SCAN_MAPS = 271,
-    SCAN_MESSAGE = 272,
-    SCAN_SEQUENCE = 273,
-    SCAN_STRING = 274,
-    SCAN_STRUCTURE = 275,
-    SCAN_UINT16 = 276,
-    SCAN_UINT32 = 277,
-    SCAN_URL = 278,
-    SCAN_PTYPE = 279,
-    SCAN_PROG = 280,
-    WORD_WORD = 281,
-    WORD_STRING = 282
-  };
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_ALIAS = 258,
+     SCAN_ARRAY = 259,
+     SCAN_ATTR = 260,
+     SCAN_BYTE = 261,
+     SCAN_CODE = 262,
+     SCAN_DATASET = 263,
+     SCAN_DATA = 264,
+     SCAN_ERROR = 265,
+     SCAN_FLOAT32 = 266,
+     SCAN_FLOAT64 = 267,
+     SCAN_GRID = 268,
+     SCAN_INT16 = 269,
+     SCAN_INT32 = 270,
+     SCAN_MAPS = 271,
+     SCAN_MESSAGE = 272,
+     SCAN_SEQUENCE = 273,
+     SCAN_STRING = 274,
+     SCAN_STRUCTURE = 275,
+     SCAN_UINT16 = 276,
+     SCAN_UINT32 = 277,
+     SCAN_URL = 278,
+     SCAN_PTYPE = 279,
+     SCAN_PROG = 280,
+     WORD_WORD = 281,
+     WORD_STRING = 282
+   };
 #endif
 
-/* Value type.  */
+
+
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef int YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
 
-
-int dapparse (DAPparsestate* parsestate);
-
-#endif /* !YY_DAP_DAP_TAB_H_INCLUDED  */
-
 /* Copy the second part of user declarations.  */
 
-#line 157 "dap.tab.c" /* yacc.c:358  */
+
+/* Line 343 of yacc.c  */
+#line 156 "dap.tab.c"
 
 #ifdef short
 # undef short
@@ -167,8 +166,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
@@ -188,7 +190,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 <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
@@ -202,49 +205,39 @@ typedef short int yytype_int16;
 # if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* 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 __attribute__
-/* This feature is available in gcc versions 2.5 and later.  */
-# if (! defined __GNUC__ || __GNUC__ < 2 \
-      || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
-#  define __attribute__(Spec) /* empty */
+#  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 yyi)
+#else
+static int
+YYID (yyi)
+    int yyi;
 #endif
-#ifndef YY_INITIAL_VALUE
-# define YY_INITIAL_VALUE(Value) /* Nothing. */
+{
+  return yyi;
+}
 #endif
 
-
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */
@@ -262,9 +255,9 @@ 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 EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
 #     ifndef EXIT_SUCCESS
 #      define EXIT_SUCCESS 0
 #     endif
@@ -274,8 +267,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
@@ -291,7 +284,7 @@ typedef short int yytype_int16;
 #  endif
 #  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
-             && (defined YYFREE || defined free)))
+	     && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
 #   ifndef EXIT_SUCCESS
 #    define EXIT_SUCCESS 0
@@ -299,13 +292,15 @@ typedef short int yytype_int16;
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS
+#   if ! defined malloc && ! defined EXIT_SUCCESS && (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 EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
@@ -315,7 +310,7 @@ 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
@@ -340,35 +335,35 @@ union yyalloc
    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_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 (YYID (0))
 
 #endif
 
 #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from SRC to DST.  The source and destination do
+/* Copy COUNT objects from FROM to TO.  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)))
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
 #  else
-#   define YYCOPY(Dst, Src, Count)              \
-      do                                        \
-        {                                       \
-          YYSIZE_T yyi;                         \
-          for (yyi = 0; yyi < (Count); yyi++)   \
-            (Dst)[yyi] = (Src)[yyi];            \
-        }                                       \
-      while (0)
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
 #  endif
 # endif
 #endif /* !YYCOPY_NEEDED */
@@ -384,19 +379,17 @@ union yyalloc
 #define YYNNTS  34
 /* YYNRULES -- Number of rules.  */
 #define YYNRULES  106
-/* YYNSTATES -- Number of states.  */
+/* YYNRULES -- Number of states.  */
 #define YYNSTATES  201
 
-/* 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   282
 
-#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,
@@ -431,7 +424,62 @@ 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,     6,    10,    13,    16,    18,    20,    22,
+      24,    30,    31,    34,    39,    47,    54,    66,    68,    70,
+      72,    74,    76,    78,    80,    82,    84,    86,    87,    90,
+      94,    99,   105,   107,   109,   111,   113,   117,   119,   120,
+     123,   126,   131,   136,   141,   146,   151,   156,   161,   166,
+     171,   176,   178,   180,   184,   186,   190,   192,   196,   198,
+     202,   204,   208,   210,   214,   216,   220,   222,   226,   228,
+     232,   234,   236,   238,   242,   250,   251,   256,   257,   262,
+     263,   268,   269,   274,   276,   278,   280,   282,   284,   286,
+     288,   290,   292,   294,   296,   298,   300,   302,   304,   306,
+     308,   310,   312,   314,   316,   318,   320
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      37,     0,    -1,    38,    41,    -1,    38,    41,     9,    -1,
+      39,    49,    -1,    40,    64,    -1,     1,    -1,     8,    -1,
+       5,    -1,    10,    -1,    28,    42,    29,    47,    30,    -1,
+      -1,    42,    43,    -1,    44,    48,    45,    30,    -1,    20,
+      28,    42,    29,    48,    45,    30,    -1,    18,    28,    42,
+      29,    48,    30,    -1,    13,    28,     4,    31,    43,    16,
+      31,    42,    29,    48,    30,    -1,     1,    -1,     6,    -1,
+      14,    -1,    21,    -1,    15,    -1,    22,    -1,    11,    -1,
+      12,    -1,    23,    -1,    19,    -1,    -1,    45,    46,    -1,
+      32,    26,    33,    -1,    32,    34,    26,    33,    -1,    32,
+      69,    34,    26,    33,    -1,     1,    -1,    48,    -1,     1,
+      -1,    69,    -1,    28,    50,    29,    -1,     1,    -1,    -1,
+      50,    51,    -1,    63,    30,    -1,     6,    69,    52,    30,
+      -1,    14,    69,    53,    30,    -1,    21,    69,    54,    30,
+      -1,    15,    69,    55,    30,    -1,    22,    69,    56,    30,
+      -1,    11,    69,    57,    30,    -1,    12,    69,    58,    30,
+      -1,    19,    69,    59,    30,    -1,    23,    69,    60,    30,
+      -1,    69,    28,    50,    29,    -1,     1,    -1,    26,    -1,
+      52,    35,    26,    -1,    26,    -1,    53,    35,    26,    -1,
+      26,    -1,    54,    35,    26,    -1,    26,    -1,    55,    35,
+      26,    -1,    26,    -1,    56,    35,    26,    -1,    26,    -1,
+      57,    35,    26,    -1,    26,    -1,    58,    35,    26,    -1,
+      62,    -1,    59,    35,    62,    -1,    61,    -1,    60,    35,
+      61,    -1,    62,    -1,    69,    -1,    27,    -1,     3,    26,
+      26,    -1,    28,    65,    66,    67,    68,    29,    30,    -1,
+      -1,     7,    34,    26,    30,    -1,    -1,    17,    34,    26,
+      30,    -1,    -1,    24,    34,    26,    30,    -1,    -1,    25,
+      34,    26,    30,    -1,    26,    -1,     3,    -1,     4,    -1,
+       5,    -1,     6,    -1,     8,    -1,     9,    -1,    10,    -1,
+      11,    -1,    12,    -1,    13,    -1,    14,    -1,    15,    -1,
+      16,    -1,    18,    -1,    19,    -1,    20,    -1,    21,    -1,
+      22,    -1,    23,    -1,     7,    -1,    17,    -1,    25,    -1,
+      24,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
        0,    54,    54,    55,    56,    57,    58,    62,    66,    70,
@@ -448,7 +496,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[] =
@@ -464,13 +512,13 @@ static const char *const yytname[] =
   "array_decl", "datasetname", "var_name", "attributebody", "attr_list",
   "attribute", "bytes", "int16", "uint16", "int32", "uint32", "float32",
   "float64", "strs", "urls", "url", "str_or_id", "alias", "errorbody",
-  "errorcode", "errormsg", "errorptype", "errorprog", "name", YY_NULL
+  "errorcode", "errormsg", "errorptype", "errorprog", "name", 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,
@@ -480,46 +528,41 @@ static const yytype_uint16 yytoknum[] =
 };
 # endif
 
-#define YYPACT_NINF -91
-
-#define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-91)))
-
-#define YYTABLE_NINF -1
-
-#define yytable_value_is_error(Yytable_value) \
-  0
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    36,    37,    37,    37,    37,    37,    38,    39,    40,
+      41,    42,    42,    43,    43,    43,    43,    43,    44,    44,
+      44,    44,    44,    44,    44,    44,    44,    45,    45,    46,
+      46,    46,    46,    47,    47,    48,    49,    49,    50,    50,
+      51,    51,    51,    51,    51,    51,    51,    51,    51,    51,
+      51,    51,    52,    52,    53,    53,    54,    54,    55,    55,
+      56,    56,    57,    57,    58,    58,    59,    59,    60,    60,
+      61,    62,    62,    63,    64,    65,    65,    66,    66,    67,
+      67,    68,    68,    69,    69,    69,    69,    69,    69,    69,
+      69,    69,    69,    69,    69,    69,    69,    69,    69,    69,
+      69,    69,    69,    69,    69,    69,    69
+};
 
-  /* 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[] =
 {
-       6,   -91,   -91,   -91,   -91,     9,   -22,     7,   -16,   -91,
-     -91,    10,   -91,   -91,   -91,    20,   -91,    37,   -91,   191,
-      -6,    14,   -91,   -91,   -91,   -91,    17,   -91,   -91,    18,
-     -91,    19,   -91,   -91,   -91,   271,   -91,   320,   -91,    27,
-     -91,   -91,   320,   -91,   -91,   -91,   -91,   320,   320,   -91,
-     320,   320,   -91,   -91,   -91,   320,   -91,   320,   320,   320,
-     -91,   -91,   -91,   -91,   -91,    24,    43,    35,    39,    50,
-      74,   -91,   -91,   -91,   -91,   -91,   -91,   -91,   -91,   -91,
-     -91,   -91,   -91,   -91,    55,   -91,   -91,   -91,    60,    67,
-      68,    70,    71,    73,   295,    77,    78,   295,   -91,   -91,
-      65,    79,    66,    81,    76,    69,   127,   -91,     4,   -91,
-     -91,   -20,   -91,   -13,   -91,   -12,   -91,   -10,   -91,    -9,
-     -91,    32,   -91,   -91,   -91,    33,   -91,    34,    42,   -91,
-     -91,   218,   -91,    80,    82,    75,    83,   346,   320,   320,
-     -91,   -91,   159,   -91,   -91,    85,   -91,    88,   -91,    89,
-     -91,    90,   -91,    91,   -91,   295,   -91,    92,   -91,    93,
-     -91,   295,   -91,   -91,    95,    94,    96,   105,    97,   -91,
-      98,   103,   100,   -91,   -91,   -91,   -91,   -91,   -91,   -91,
-     -91,   -91,   -91,   102,   -91,    99,   -91,    12,   -91,   111,
-     109,   -91,   -91,   -91,   -91,   118,   244,   -91,   320,   106,
-     -91
+       0,     2,     2,     3,     2,     2,     1,     1,     1,     1,
+       5,     0,     2,     4,     7,     6,    11,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     0,     2,     3,
+       4,     5,     1,     1,     1,     1,     3,     1,     0,     2,
+       2,     4,     4,     4,     4,     4,     4,     4,     4,     4,
+       4,     1,     1,     3,     1,     3,     1,     3,     1,     3,
+       1,     3,     1,     3,     1,     3,     1,     3,     1,     3,
+       1,     1,     1,     3,     7,     0,     4,     0,     4,     0,
+       4,     0,     4,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     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 reduction number in state STATE-NUM.
+   Performed when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
        0,     6,     8,     7,     9,     0,     0,     0,     0,     1,
@@ -545,16 +588,7 @@ static const yytype_uint8 yydefact[] =
       16
 };
 
-  /* YYPGOTO[NTERM-NUM].  */
-static const yytype_int8 yypgoto[] =
-{
-     -91,   -91,   -91,   -91,   -91,   -91,   -69,   -15,   -91,   -17,
-     -91,   -91,   -37,   -91,    54,   -91,   -91,   -91,   -91,   -91,
-     -91,   -91,   -91,   -91,   -91,    -7,   -90,   -91,   -91,   -91,
-     -91,   -91,   -91,   -18
-};
-
-  /* YYDEFGOTO[NTERM-NUM].  */
+/* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
       -1,     5,     6,     7,     8,    11,    17,    36,    37,   108,
@@ -563,9 +597,47 @@ static const yytype_int16 yydefgoto[] =
       69,   103,   136,    86
 };
 
-  /* 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 -91
+static const yytype_int16 yypact[] =
+{
+       6,   -91,   -91,   -91,   -91,     9,   -22,     7,   -16,   -91,
+     -91,    10,   -91,   -91,   -91,    20,   -91,    37,   -91,   191,
+      -6,    14,   -91,   -91,   -91,   -91,    17,   -91,   -91,    18,
+     -91,    19,   -91,   -91,   -91,   271,   -91,   320,   -91,    27,
+     -91,   -91,   320,   -91,   -91,   -91,   -91,   320,   320,   -91,
+     320,   320,   -91,   -91,   -91,   320,   -91,   320,   320,   320,
+     -91,   -91,   -91,   -91,   -91,    24,    43,    35,    39,    50,
+      74,   -91,   -91,   -91,   -91,   -91,   -91,   -91,   -91,   -91,
+     -91,   -91,   -91,   -91,    55,   -91,   -91,   -91,    60,    67,
+      68,    70,    71,    73,   295,    77,    78,   295,   -91,   -91,
+      65,    79,    66,    81,    76,    69,   127,   -91,     4,   -91,
+     -91,   -20,   -91,   -13,   -91,   -12,   -91,   -10,   -91,    -9,
+     -91,    32,   -91,   -91,   -91,    33,   -91,    34,    42,   -91,
+     -91,   218,   -91,    80,    82,    75,    83,   346,   320,   320,
+     -91,   -91,   159,   -91,   -91,    85,   -91,    88,   -91,    89,
+     -91,    90,   -91,    91,   -91,   295,   -91,    92,   -91,    93,
+     -91,   295,   -91,   -91,    95,    94,    96,   105,    97,   -91,
+      98,   103,   100,   -91,   -91,   -91,   -91,   -91,   -91,   -91,
+     -91,   -91,   -91,   102,   -91,    99,   -91,    12,   -91,   111,
+     109,   -91,   -91,   -91,   -91,   118,   244,   -91,   320,   106,
+     -91
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+     -91,   -91,   -91,   -91,   -91,   -91,   -69,   -15,   -91,   -17,
+     -91,   -91,   -37,   -91,    54,   -91,   -91,   -91,   -91,   -91,
+     -91,   -91,   -91,   -91,   -91,    -7,   -90,   -91,   -91,   -91,
+     -91,   -91,   -91,   -18
+};
+
+/* 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 YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -1
 static const yytype_uint8 yytable[] =
 {
       87,    66,   105,   106,   122,   140,    10,     1,    12,     9,
@@ -607,6 +679,12 @@ static const yytype_uint8 yytable[] =
       27,    28,     0,     0,    29,    30,    31,    32,    33,    34
 };
 
+#define yypact_value_is_default(yystate) \
+  ((yystate) == (-91))
+
+#define yytable_value_is_error(yytable_value) \
+  YYID (0)
+
 static const yytype_int16 yycheck[] =
 {
       37,    19,    71,    72,    94,     1,    28,     1,     1,     0,
@@ -648,8 +726,8 @@ static const yytype_int16 yycheck[] =
       14,    15,    -1,    -1,    18,    19,    20,    21,    22,    23
 };
 
-  /* 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,     1,     5,     8,    10,    37,    38,    39,    40,     0,
@@ -675,73 +753,94 @@ static const yytype_uint8 yystos[] =
       30
 };
 
-  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    36,    37,    37,    37,    37,    37,    38,    39,    40,
-      41,    42,    42,    43,    43,    43,    43,    43,    44,    44,
-      44,    44,    44,    44,    44,    44,    44,    45,    45,    46,
-      46,    46,    46,    47,    47,    48,    49,    49,    50,    50,
-      51,    51,    51,    51,    51,    51,    51,    51,    51,    51,
-      51,    51,    52,    52,    53,    53,    54,    54,    55,    55,
-      56,    56,    57,    57,    58,    58,    59,    59,    60,    60,
-      61,    62,    62,    63,    64,    65,    65,    66,    66,    67,
-      67,    68,    68,    69,    69,    69,    69,    69,    69,    69,
-      69,    69,    69,    69,    69,    69,    69,    69,    69,    69,
-      69,    69,    69,    69,    69,    69,    69
-};
-
-  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     2,     3,     2,     2,     1,     1,     1,     1,
-       5,     0,     2,     4,     7,     6,    11,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     0,     2,     3,
-       4,     5,     1,     1,     1,     1,     3,     1,     0,     2,
-       2,     4,     4,     4,     4,     4,     4,     4,     4,     4,
-       4,     1,     1,     3,     1,     3,     1,     3,     1,     3,
-       1,     3,     1,     3,     1,     3,     1,     3,     1,     3,
-       1,     1,     1,     3,     7,     0,     4,     0,     4,     0,
-       4,     0,     4,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     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
+
+
+/* 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.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
+
+#define YYFAIL		goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
 
-#define yyerrok         (yyerrstatus = 0)
-#define yyclearin       (yychar = YYEMPTY)
-#define YYEMPTY         (-2)
-#define YYEOF           0
+#define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYACCEPT        goto yyacceptlab
-#define YYABORT         goto yyabortlab
-#define YYERROR         goto yyerrorlab
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (parsestate, YY_("syntax error: cannot back up")); \
+      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
 
 
-#define YYRECOVERING()  (!!yyerrstatus)
+/* This macro is provided for backward compatibility. */
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (parsestate, YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
 
-/* Error token number */
-#define YYTERROR        1
-#define YYERRCODE       256
 
+/* YYLEX -- calling `yylex' with the right arguments.  */
 
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, parsestate)
+#endif
 
 /* Enable debugging if requested.  */
 #if YYDEBUG
@@ -751,47 +850,56 @@ 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, parsestate); \
-      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, parsestate); \
+      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, DAPparsestate* parsestate)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, parsestate)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    DAPparsestate* parsestate;
+#endif
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
-  YYUSE (parsestate);
   if (!yyvaluep)
     return;
+  YYUSE (parsestate);
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
 # endif
-  YYUSE (yytype);
+  switch (yytype)
+    {
+      default:
+	break;
+    }
 }
 
 
@@ -799,11 +907,23 @@ 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, DAPparsestate* parsestate)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, parsestate)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    DAPparsestate* parsestate;
+#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, parsestate);
   YYFPRINTF (yyoutput, ")");
@@ -814,8 +934,16 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, DAP
 | TOP (included).                                                   |
 `------------------------------------------------------------------*/
 
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
+#endif
 {
   YYFPRINTF (stderr, "Stack now");
   for (; yybottom <= yytop; yybottom++)
@@ -826,42 +954,50 @@ yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
   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 (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, DAPparsestate* parsestate)
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule, DAPparsestate* parsestate)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule, parsestate)
+    YYSTYPE *yyvsp;
+    int yyrule;
+    DAPparsestate* parsestate;
+#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)])
-                                              , parsestate);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       		       , parsestate);
       YYFPRINTF (stderr, "\n");
     }
 }
 
-# define YY_REDUCE_PRINT(Rule)          \
-do {                                    \
-  if (yydebug)                          \
-    yy_reduce_print (yyssp, yyvsp, Rule, parsestate); \
-} while (0)
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule, parsestate); \
+} while (YYID (0))
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
    multiple parsers can coexist.  */
@@ -875,7 +1011,7 @@ int yydebug;
 
 
 /* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef YYINITDEPTH
+#ifndef	YYINITDEPTH
 # define YYINITDEPTH 200
 #endif
 
@@ -898,8 +1034,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++)
@@ -915,8 +1058,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;
@@ -946,27 +1097,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: ;
     }
 
@@ -989,11 +1140,12 @@ static int
 yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                 yytype_int16 *yyssp, int yytoken)
 {
-  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
   YYSIZE_T yysize = yysize0;
+  YYSIZE_T yysize1;
   enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
   /* Internationalized format string. */
-  const char *yyformat = YY_NULL;
+  const char *yyformat = 0;
   /* Arguments of yyformat. */
   char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
   /* Number of reported tokens (one for the "unexpected", one per
@@ -1001,6 +1153,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
   int yycount = 0;
 
   /* There are many possibilities here to consider:
+     - Assume YYFAIL is not used.  It's too flawed to consider.  See
+       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+       for details.  YYERROR is fine as it does not invoke this
+       function.
      - 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
@@ -1049,13 +1205,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                     break;
                   }
                 yyarg[yycount++] = yytname[yyx];
-                {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                    return 2;
-                  yysize = yysize1;
-                }
+                yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+                if (! (yysize <= yysize1
+                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  return 2;
+                yysize = yysize1;
               }
         }
     }
@@ -1075,12 +1229,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
 # undef YYCASE_
     }
 
-  {
-    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-      return 2;
-    yysize = yysize1;
-  }
+  yysize1 = yysize + yystrlen (yyformat);
+  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    return 2;
+  yysize = yysize1;
 
   if (*yymsg_alloc < yysize)
     {
@@ -1117,39 +1269,83 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
 | 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, DAPparsestate* parsestate)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, parsestate)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    DAPparsestate* parsestate;
+#endif
 {
   YYUSE (yyvaluep);
   YYUSE (parsestate);
+
   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 (DAPparsestate* parsestate);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
 
 
 /*----------.
 | 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 (DAPparsestate* parsestate)
+#else
+int
+yyparse (parsestate)
+    DAPparsestate* parsestate;
+#endif
+#endif
 {
 /* The lookahead symbol.  */
 int yychar;
 
-
 /* The semantic value of the lookahead symbol.  */
-/* Default value used for initialization, for pacifying older GCCs
-   or non-GCC compilers.  */
-YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
-YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
+YYSTYPE yylval;
 
     /* Number of syntax errors so far.  */
     int yynerrs;
@@ -1159,10 +1355,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     int yyerrstatus;
 
     /* The stacks and their tools:
-       'yyss': related to states.
-       'yyvs': related to semantic values.
+       `yyss': related to states.
+       `yyvs': related to semantic values.
 
-       Refer to the stacks through separate pointers, to allow yyoverflow
+       Refer to the stacks thru separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
 
     /* The state stack.  */
@@ -1180,7 +1376,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
   int yyn;
   int yyresult;
   /* Lookahead token as an internal (translated) token number.  */
-  int yytoken = 0;
+  int yytoken;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
@@ -1198,8 +1394,9 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yyssp = yyss = yyssa;
-  yyvsp = yyvs = yyvsa;
+  yytoken = 0;
+  yyss = yyssa;
+  yyvs = yyvsa;
   yystacksize = YYINITDEPTH;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1208,6 +1405,14 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
   yyerrstatus = 0;
   yynerrs = 0;
   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;
 
 /*------------------------------------------------------------.
@@ -1228,23 +1433,23 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
 #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
@@ -1252,22 +1457,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 # 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_alloc, yyss);
+	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
 #  undef YYSTACK_RELOCATE
-        if (yyss1 != yyssa)
-          YYSTACK_FREE (yyss1);
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
       }
 # endif
 #endif /* no yyoverflow */
@@ -1276,10 +1481,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
       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));
@@ -1308,7 +1513,7 @@ yybackup:
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = yylex (&yylval, parsestate);
+      yychar = YYLEX;
     }
 
   if (yychar <= YYEOF)
@@ -1348,9 +1553,7 @@ yybackup:
   yychar = YYEMPTY;
 
   yystate = yyn;
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -1373,7 +1576,7 @@ yyreduce:
   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
@@ -1387,613 +1590,716 @@ yyreduce:
   switch (yyn)
     {
         case 6:
-#line 58 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 58 "dap.y"
     {dap_unrecognizedresponse(parsestate); YYABORT;}
-#line 1393 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 7:
-#line 63 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 63 "dap.y"
     {dap_tagparse(parsestate,SCAN_DATASET);}
-#line 1399 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 8:
-#line 67 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 67 "dap.y"
     {dap_tagparse(parsestate,SCAN_ATTR);}
-#line 1405 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 9:
-#line 71 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 71 "dap.y"
     {dap_tagparse(parsestate,SCAN_ERROR);}
-#line 1411 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 10:
-#line 76 "dap.y" /* yacc.c:1646  */
-    {dap_datasetbody(parsestate,(yyvsp[-1]),(yyvsp[-3]));}
-#line 1417 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 76 "dap.y"
+    {dap_datasetbody(parsestate,(yyvsp[(4) - (5)]),(yyvsp[(2) - (5)]));}
     break;
 
   case 11:
-#line 81 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 81 "dap.y"
     {(yyval)=dap_declarations(parsestate,null,null);}
-#line 1423 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 12:
-#line 82 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_declarations(parsestate,(yyvsp[-1]),(yyvsp[0]));}
-#line 1429 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 82 "dap.y"
+    {(yyval)=dap_declarations(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));}
     break;
 
   case 13:
-#line 89 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_makebase(parsestate,(yyvsp[-2]),(yyvsp[-3]),(yyvsp[-1]));}
-#line 1435 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 89 "dap.y"
+    {(yyval)=dap_makebase(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(1) - (4)]),(yyvsp[(3) - (4)]));}
     break;
 
   case 14:
-#line 91 "dap.y" /* yacc.c:1646  */
-    {if(((yyval)=dap_makestructure(parsestate,(yyvsp[-2]),(yyvsp[-1]),(yyvsp[-4])))==null) {YYABORT;}}
-#line 1441 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 91 "dap.y"
+    {if(((yyval)=dap_makestructure(parsestate,(yyvsp[(5) - (7)]),(yyvsp[(6) - (7)]),(yyvsp[(3) - (7)])))==null) {YYABORT;}}
     break;
 
   case 15:
-#line 93 "dap.y" /* yacc.c:1646  */
-    {if(((yyval)=dap_makesequence(parsestate,(yyvsp[-1]),(yyvsp[-3])))==null) {YYABORT;}}
-#line 1447 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 93 "dap.y"
+    {if(((yyval)=dap_makesequence(parsestate,(yyvsp[(5) - (6)]),(yyvsp[(3) - (6)])))==null) {YYABORT;}}
     break;
 
   case 16:
-#line 96 "dap.y" /* yacc.c:1646  */
-    {if(((yyval)=dap_makegrid(parsestate,(yyvsp[-1]),(yyvsp[-6]),(yyvsp[-3])))==null) {YYABORT;}}
-#line 1453 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 96 "dap.y"
+    {if(((yyval)=dap_makegrid(parsestate,(yyvsp[(10) - (11)]),(yyvsp[(5) - (11)]),(yyvsp[(8) - (11)])))==null) {YYABORT;}}
     break;
 
   case 17:
-#line 98 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 98 "dap.y"
     {dapsemanticerror(parsestate,OC_EBADTYPE,"Unrecognized type"); YYABORT;}
-#line 1459 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 18:
-#line 103 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 103 "dap.y"
     {(yyval)=(Object)SCAN_BYTE;}
-#line 1465 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 19:
-#line 104 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 104 "dap.y"
     {(yyval)=(Object)SCAN_INT16;}
-#line 1471 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 20:
-#line 105 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 105 "dap.y"
     {(yyval)=(Object)SCAN_UINT16;}
-#line 1477 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 21:
-#line 106 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 106 "dap.y"
     {(yyval)=(Object)SCAN_INT32;}
-#line 1483 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 22:
-#line 107 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 107 "dap.y"
     {(yyval)=(Object)SCAN_UINT32;}
-#line 1489 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 23:
-#line 108 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 108 "dap.y"
     {(yyval)=(Object)SCAN_FLOAT32;}
-#line 1495 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 24:
-#line 109 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 109 "dap.y"
     {(yyval)=(Object)SCAN_FLOAT64;}
-#line 1501 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 25:
-#line 110 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 110 "dap.y"
     {(yyval)=(Object)SCAN_URL;}
-#line 1507 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 26:
-#line 111 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 111 "dap.y"
     {(yyval)=(Object)SCAN_STRING;}
-#line 1513 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 27:
-#line 115 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 115 "dap.y"
     {(yyval)=dap_arraydecls(parsestate,null,null);}
-#line 1519 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 28:
-#line 116 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_arraydecls(parsestate,(yyvsp[-1]),(yyvsp[0]));}
-#line 1525 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 116 "dap.y"
+    {(yyval)=dap_arraydecls(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));}
     break;
 
   case 29:
-#line 120 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_arraydecl(parsestate,null,(yyvsp[-1]));}
-#line 1531 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 120 "dap.y"
+    {(yyval)=dap_arraydecl(parsestate,null,(yyvsp[(2) - (3)]));}
     break;
 
   case 30:
-#line 121 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_arraydecl(parsestate,null,(yyvsp[-1]));}
-#line 1537 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 121 "dap.y"
+    {(yyval)=dap_arraydecl(parsestate,null,(yyvsp[(3) - (4)]));}
     break;
 
   case 31:
-#line 122 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_arraydecl(parsestate,(yyvsp[-3]),(yyvsp[-1]));}
-#line 1543 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 122 "dap.y"
+    {(yyval)=dap_arraydecl(parsestate,(yyvsp[(2) - (5)]),(yyvsp[(4) - (5)]));}
     break;
 
   case 32:
-#line 124 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 124 "dap.y"
     {dapsemanticerror(parsestate,OC_EDIMSIZE,"Illegal dimension declaration"); YYABORT;}
-#line 1549 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 33:
-#line 128 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[0]);}
-#line 1555 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 128 "dap.y"
+    {(yyval)=(yyvsp[(1) - (1)]);}
     break;
 
   case 34:
-#line 130 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 130 "dap.y"
     {dapsemanticerror(parsestate,OC_EDDS,"Illegal dataset declaration"); YYABORT;}
-#line 1561 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 35:
-#line 133 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[0]);}
-#line 1567 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 133 "dap.y"
+    {(yyval)=(yyvsp[(1) - (1)]);}
     break;
 
   case 36:
-#line 136 "dap.y" /* yacc.c:1646  */
-    {dap_attributebody(parsestate,(yyvsp[-1]));}
-#line 1573 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 136 "dap.y"
+    {dap_attributebody(parsestate,(yyvsp[(2) - (3)]));}
     break;
 
   case 37:
-#line 138 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 138 "dap.y"
     {dapsemanticerror(parsestate,OC_EDAS,"Illegal DAS body"); YYABORT;}
-#line 1579 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 38:
-#line 142 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 142 "dap.y"
     {(yyval)=dap_attrlist(parsestate,null,null);}
-#line 1585 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 39:
-#line 143 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrlist(parsestate,(yyvsp[-1]),(yyvsp[0]));}
-#line 1591 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 143 "dap.y"
+    {(yyval)=dap_attrlist(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));}
     break;
 
   case 40:
-#line 147 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 147 "dap.y"
     {(yyval)=null;}
-#line 1597 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 41:
-#line 149 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attribute(parsestate,(yyvsp[-2]),(yyvsp[-1]),(Object)SCAN_BYTE);}
-#line 1603 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 149 "dap.y"
+    {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_BYTE);}
     break;
 
   case 42:
-#line 151 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attribute(parsestate,(yyvsp[-2]),(yyvsp[-1]),(Object)SCAN_INT16);}
-#line 1609 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 151 "dap.y"
+    {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_INT16);}
     break;
 
   case 43:
-#line 153 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attribute(parsestate,(yyvsp[-2]),(yyvsp[-1]),(Object)SCAN_UINT16);}
-#line 1615 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 153 "dap.y"
+    {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_UINT16);}
     break;
 
   case 44:
-#line 155 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attribute(parsestate,(yyvsp[-2]),(yyvsp[-1]),(Object)SCAN_INT32);}
-#line 1621 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 155 "dap.y"
+    {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_INT32);}
     break;
 
   case 45:
-#line 157 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attribute(parsestate,(yyvsp[-2]),(yyvsp[-1]),(Object)SCAN_UINT32);}
-#line 1627 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 157 "dap.y"
+    {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_UINT32);}
     break;
 
   case 46:
-#line 159 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attribute(parsestate,(yyvsp[-2]),(yyvsp[-1]),(Object)SCAN_FLOAT32);}
-#line 1633 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 159 "dap.y"
+    {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_FLOAT32);}
     break;
 
   case 47:
-#line 161 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attribute(parsestate,(yyvsp[-2]),(yyvsp[-1]),(Object)SCAN_FLOAT64);}
-#line 1639 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 161 "dap.y"
+    {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_FLOAT64);}
     break;
 
   case 48:
-#line 163 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attribute(parsestate,(yyvsp[-2]),(yyvsp[-1]),(Object)SCAN_STRING);}
-#line 1645 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 163 "dap.y"
+    {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_STRING);}
     break;
 
   case 49:
-#line 165 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attribute(parsestate,(yyvsp[-2]),(yyvsp[-1]),(Object)SCAN_URL);}
-#line 1651 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 165 "dap.y"
+    {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_URL);}
     break;
 
   case 50:
-#line 166 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrset(parsestate,(yyvsp[-3]),(yyvsp[-1]));}
-#line 1657 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 166 "dap.y"
+    {(yyval)=dap_attrset(parsestate,(yyvsp[(1) - (4)]),(yyvsp[(3) - (4)]));}
     break;
 
   case 51:
-#line 168 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 168 "dap.y"
     {dapsemanticerror(parsestate,OC_EDAS,"Illegal attribute"); YYABORT;}
-#line 1663 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 52:
-#line 172 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[0]),(Object)SCAN_BYTE);}
-#line 1669 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 172 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_BYTE);}
     break;
 
   case 53:
-#line 174 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,(yyvsp[-2]),(yyvsp[0]),(Object)SCAN_BYTE);}
-#line 1675 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 174 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_BYTE);}
     break;
 
   case 54:
-#line 177 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[0]),(Object)SCAN_INT16);}
-#line 1681 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 177 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_INT16);}
     break;
 
   case 55:
-#line 179 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,(yyvsp[-2]),(yyvsp[0]),(Object)SCAN_INT16);}
-#line 1687 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 179 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_INT16);}
     break;
 
   case 56:
-#line 182 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[0]),(Object)SCAN_UINT16);}
-#line 1693 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 182 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_UINT16);}
     break;
 
   case 57:
-#line 184 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,(yyvsp[-2]),(yyvsp[0]),(Object)SCAN_UINT16);}
-#line 1699 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 184 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_UINT16);}
     break;
 
   case 58:
-#line 187 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[0]),(Object)SCAN_INT32);}
-#line 1705 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 187 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_INT32);}
     break;
 
   case 59:
-#line 189 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,(yyvsp[-2]),(yyvsp[0]),(Object)SCAN_INT32);}
-#line 1711 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 189 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_INT32);}
     break;
 
   case 60:
-#line 192 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[0]),(Object)SCAN_UINT32);}
-#line 1717 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 192 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_UINT32);}
     break;
 
   case 61:
-#line 193 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,(yyvsp[-2]),(yyvsp[0]),(Object)SCAN_UINT32);}
-#line 1723 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 193 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_UINT32);}
     break;
 
   case 62:
-#line 196 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[0]),(Object)SCAN_FLOAT32);}
-#line 1729 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 196 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_FLOAT32);}
     break;
 
   case 63:
-#line 197 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,(yyvsp[-2]),(yyvsp[0]),(Object)SCAN_FLOAT32);}
-#line 1735 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 197 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_FLOAT32);}
     break;
 
   case 64:
-#line 200 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[0]),(Object)SCAN_FLOAT64);}
-#line 1741 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 200 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_FLOAT64);}
     break;
 
   case 65:
-#line 201 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,(yyvsp[-2]),(yyvsp[0]),(Object)SCAN_FLOAT64);}
-#line 1747 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 201 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_FLOAT64);}
     break;
 
   case 66:
-#line 204 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[0]),(Object)SCAN_STRING);}
-#line 1753 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 204 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_STRING);}
     break;
 
   case 67:
-#line 205 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,(yyvsp[-2]),(yyvsp[0]),(Object)SCAN_STRING);}
-#line 1759 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 205 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_STRING);}
     break;
 
   case 68:
-#line 209 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[0]),(Object)SCAN_URL);}
-#line 1765 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 209 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_URL);}
     break;
 
   case 69:
-#line 210 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dap_attrvalue(parsestate,(yyvsp[-2]),(yyvsp[0]),(Object)SCAN_URL);}
-#line 1771 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 210 "dap.y"
+    {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_URL);}
     break;
 
   case 70:
-#line 214 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[0]);}
-#line 1777 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 214 "dap.y"
+    {(yyval)=(yyvsp[(1) - (1)]);}
     break;
 
   case 71:
-#line 218 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[0]);}
-#line 1783 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 218 "dap.y"
+    {(yyval)=(yyvsp[(1) - (1)]);}
     break;
 
   case 72:
-#line 219 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[0]);}
-#line 1789 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 219 "dap.y"
+    {(yyval)=(yyvsp[(1) - (1)]);}
     break;
 
   case 73:
-#line 230 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[-1]); (yyval)=(yyvsp[0]); (yyval)=null;}
-#line 1795 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 230 "dap.y"
+    {(yyval)=(yyvsp[(2) - (3)]); (yyval)=(yyvsp[(3) - (3)]); (yyval)=null;}
     break;
 
   case 74:
-#line 235 "dap.y" /* yacc.c:1646  */
-    {dap_errorbody(parsestate,(yyvsp[-5]),(yyvsp[-4]),(yyvsp[-3]),(yyvsp[-2]));}
-#line 1801 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 235 "dap.y"
+    {dap_errorbody(parsestate,(yyvsp[(2) - (7)]),(yyvsp[(3) - (7)]),(yyvsp[(4) - (7)]),(yyvsp[(5) - (7)]));}
     break;
 
   case 75:
-#line 238 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 238 "dap.y"
     {(yyval)=null;}
-#line 1807 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 76:
-#line 238 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[-1]);}
-#line 1813 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 238 "dap.y"
+    {(yyval)=(yyvsp[(3) - (4)]);}
     break;
 
   case 77:
-#line 239 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 239 "dap.y"
     {(yyval)=null;}
-#line 1819 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 78:
-#line 239 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[-1]);}
-#line 1825 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 239 "dap.y"
+    {(yyval)=(yyvsp[(3) - (4)]);}
     break;
 
   case 79:
-#line 240 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 240 "dap.y"
     {(yyval)=null;}
-#line 1831 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 80:
-#line 240 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[-1]);}
-#line 1837 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 240 "dap.y"
+    {(yyval)=(yyvsp[(3) - (4)]);}
     break;
 
   case 81:
-#line 241 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 241 "dap.y"
     {(yyval)=null;}
-#line 1843 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 82:
-#line 241 "dap.y" /* yacc.c:1646  */
-    {(yyval)=(yyvsp[-1]);}
-#line 1849 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 241 "dap.y"
+    {(yyval)=(yyvsp[(3) - (4)]);}
     break;
 
   case 83:
-#line 247 "dap.y" /* yacc.c:1646  */
-    {(yyval)=dapdecode(parsestate->lexstate,(yyvsp[0]));}
-#line 1855 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 247 "dap.y"
+    {(yyval)=dapdecode(parsestate->lexstate,(yyvsp[(1) - (1)]));}
     break;
 
   case 84:
-#line 248 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 248 "dap.y"
     {(yyval)=strdup("alias");}
-#line 1861 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 85:
-#line 249 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 249 "dap.y"
     {(yyval)=strdup("array");}
-#line 1867 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 86:
-#line 250 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 250 "dap.y"
     {(yyval)=strdup("attributes");}
-#line 1873 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 87:
-#line 251 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 251 "dap.y"
     {(yyval)=strdup("byte");}
-#line 1879 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 88:
-#line 252 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 252 "dap.y"
     {(yyval)=strdup("dataset");}
-#line 1885 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 89:
-#line 253 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 253 "dap.y"
     {(yyval)=strdup("data");}
-#line 1891 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 90:
-#line 254 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 254 "dap.y"
     {(yyval)=strdup("error");}
-#line 1897 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 91:
-#line 255 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 255 "dap.y"
     {(yyval)=strdup("float32");}
-#line 1903 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 92:
-#line 256 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 256 "dap.y"
     {(yyval)=strdup("float64");}
-#line 1909 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 93:
-#line 257 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 257 "dap.y"
     {(yyval)=strdup("grid");}
-#line 1915 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 94:
-#line 258 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 258 "dap.y"
     {(yyval)=strdup("int16");}
-#line 1921 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 95:
-#line 259 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 259 "dap.y"
     {(yyval)=strdup("int32");}
-#line 1927 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 96:
-#line 260 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 260 "dap.y"
     {(yyval)=strdup("maps");}
-#line 1933 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 97:
-#line 261 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 261 "dap.y"
     {(yyval)=strdup("sequence");}
-#line 1939 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 98:
-#line 262 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 262 "dap.y"
     {(yyval)=strdup("string");}
-#line 1945 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 99:
-#line 263 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 263 "dap.y"
     {(yyval)=strdup("structure");}
-#line 1951 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 100:
-#line 264 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 264 "dap.y"
     {(yyval)=strdup("uint16");}
-#line 1957 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 101:
-#line 265 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 265 "dap.y"
     {(yyval)=strdup("uint32");}
-#line 1963 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 102:
-#line 266 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 266 "dap.y"
     {(yyval)=strdup("url");}
-#line 1969 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 103:
-#line 267 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 267 "dap.y"
     {(yyval)=strdup("code");}
-#line 1975 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 104:
-#line 268 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 268 "dap.y"
     {(yyval)=strdup("message");}
-#line 1981 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 105:
-#line 269 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 269 "dap.y"
     {(yyval)=strdup("program");}
-#line 1987 "dap.tab.c" /* yacc.c:1646  */
     break;
 
   case 106:
-#line 270 "dap.y" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 270 "dap.y"
     {(yyval)=strdup("program_type");}
-#line 1993 "dap.tab.c" /* yacc.c:1646  */
     break;
 
 
-#line 1997 "dap.tab.c" /* yacc.c:1646  */
+
+/* Line 1806 of yacc.c  */
+#line 2303 "dap.tab.c"
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -2015,7 +2321,7 @@ yyreduce:
 
   *++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.  */
 
@@ -2030,9 +2336,9 @@ yyreduce:
   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.  */
@@ -2083,20 +2389,20 @@ yyerrlab:
   if (yyerrstatus == 3)
     {
       /* If just tried and failed to reuse lookahead token after an
-         error, discard it.  */
+	 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, parsestate);
-          yychar = YYEMPTY;
-        }
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval, parsestate);
+	  yychar = YYEMPTY;
+	}
     }
 
   /* Else will try to reuse lookahead token after shifting the error
@@ -2115,7 +2421,7 @@ yyerrorlab:
   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;
@@ -2128,37 +2434,35 @@ yyerrorlab:
 | 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;
-            }
-        }
+	{
+	  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, parsestate);
+		  yystos[yystate], yyvsp, parsestate);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
     }
 
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -2182,7 +2486,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined yyoverflow || YYERROR_VERBOSE
+#if !defined(yyoverflow) || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -2201,14 +2505,14 @@ yyreturn:
       yydestruct ("Cleanup: discarding lookahead",
                   yytoken, &yylval, parsestate);
     }
-  /* Do not reclaim the symbols of the rule whose action triggered
+  /* 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, parsestate);
+		  yystos[*yyssp], yyvsp, parsestate);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
@@ -2219,7 +2523,13 @@ yyreturn:
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
 #endif
-  return yyresult;
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
 }
-#line 273 "dap.y" /* yacc.c:1906  */
+
+
+
+/* Line 2067 of yacc.c  */
+#line 273 "dap.y"
+
 
diff --git a/oc2/daptab.h b/oc2/dapy.h
similarity index 61%
rename from oc2/daptab.h
rename to oc2/dapy.h
index d015b33..e085df5 100644
--- a/oc2/daptab.h
+++ b/oc2/dapy.h
@@ -1,19 +1,19 @@
-/* A Bison parser, made by GNU Bison 3.0.  */
+/* A Bison parser, made by GNU Bison 2.5.  */
 
 /* Bison interface for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
-
+   
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+   
    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.
-
+   
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    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 <http://www.gnu.org/licenses/>.  */
 
@@ -26,62 +26,54 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-#ifndef YY_DAP_DAP_TAB_H_INCLUDED
-# define YY_DAP_DAP_TAB_H_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
-#if YYDEBUG
-extern int dapdebug;
-#endif
 
-/* Token type.  */
+/* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
-  enum yytokentype
-  {
-    SCAN_ALIAS = 258,
-    SCAN_ARRAY = 259,
-    SCAN_ATTR = 260,
-    SCAN_BYTE = 261,
-    SCAN_CODE = 262,
-    SCAN_DATASET = 263,
-    SCAN_DATA = 264,
-    SCAN_ERROR = 265,
-    SCAN_FLOAT32 = 266,
-    SCAN_FLOAT64 = 267,
-    SCAN_GRID = 268,
-    SCAN_INT16 = 269,
-    SCAN_INT32 = 270,
-    SCAN_MAPS = 271,
-    SCAN_MESSAGE = 272,
-    SCAN_SEQUENCE = 273,
-    SCAN_STRING = 274,
-    SCAN_STRUCTURE = 275,
-    SCAN_UINT16 = 276,
-    SCAN_UINT32 = 277,
-    SCAN_URL = 278,
-    SCAN_PTYPE = 279,
-    SCAN_PROG = 280,
-    WORD_WORD = 281,
-    WORD_STRING = 282
-  };
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_ALIAS = 258,
+     SCAN_ARRAY = 259,
+     SCAN_ATTR = 260,
+     SCAN_BYTE = 261,
+     SCAN_CODE = 262,
+     SCAN_DATASET = 263,
+     SCAN_DATA = 264,
+     SCAN_ERROR = 265,
+     SCAN_FLOAT32 = 266,
+     SCAN_FLOAT64 = 267,
+     SCAN_GRID = 268,
+     SCAN_INT16 = 269,
+     SCAN_INT32 = 270,
+     SCAN_MAPS = 271,
+     SCAN_MESSAGE = 272,
+     SCAN_SEQUENCE = 273,
+     SCAN_STRING = 274,
+     SCAN_STRUCTURE = 275,
+     SCAN_UINT16 = 276,
+     SCAN_UINT32 = 277,
+     SCAN_URL = 278,
+     SCAN_PTYPE = 279,
+     SCAN_PROG = 280,
+     WORD_WORD = 281,
+     WORD_STRING = 282
+   };
 #endif
 
-/* Value type.  */
+
+
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef int YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
 
 
-int dapparse (DAPparsestate* parsestate);
 
-#endif /* !YY_DAP_DAP_TAB_H_INCLUDED  */
diff --git a/oc2/oc.css b/oc2/oc.css
index 3e0844d..e69de29 100644
--- a/oc2/oc.css
+++ b/oc2/oc.css
@@ -1,39 +0,0 @@
-<style> 
-.break { page-break-before: always; } 
-body { counter-reset: H2; font-size: 12pt; } 
-h1.title {
-  font-size: 18pt;
-  text-decoration: underline;
-}
-div.subtitle {
-}
-.subtitle h1 {
-  font-size: 14pt;
-  margin-top: 0;
-  margin-bottom: 0;
-}
-
-h1.toc {
-  font-size: 16pt;
-  text-decoration: underline;
-}
-h1.appendix {
-  font-size: 14pt;
-}
-
-h2:before { 
-  content: counter(H2) " "; 
-  counter-increment: H2; 
-} 
-h2 { counter-reset: H3; text-decoration: underline; } 
-h3:before { 
-  content: counter(H2) "." counter(H3) " "; 
-  counter-increment:H3; 
-} 
-h3 { counter-reset: H4; } 
-h4:before { 
-  content: counter(H2) "." counter(H3) "." counter(H4) " "; 
-  counter-increment:H4; 
-} 
-
-</style> 
diff --git a/oc2/oc.h b/oc2/oc.h
index f3d0de2..e0fa0ad 100644
--- a/oc2/oc.h
+++ b/oc2/oc.h
@@ -537,7 +537,7 @@ extern OCerror oc_svcerrordata(OClink link, char** codep,
    note that this may or may not be the same as returned
    by oc_svcerrordata.
  */
-extern OCerror oc_httpcode(OClink);
+extern int oc_httpcode(OClink);
 
 /*
 (Re-)initialize the oc library as if nothing had been called.
diff --git a/oc2/ochttp.c b/oc2/ochttp.c
index df38f3d..3385336 100644
--- a/oc2/ochttp.c
+++ b/oc2/ochttp.c
@@ -373,5 +373,3 @@ done:
     }
     return OCTHROW(stat);
 }
-
-
diff --git a/oc2/ocinternal.c b/oc2/ocinternal.c
index 464929a..ce9161a 100644
--- a/oc2/ocinternal.c
+++ b/oc2/ocinternal.c
@@ -12,7 +12,7 @@
 #endif
 #include <errno.h>
 
-#ifdef _WIN32
+#ifdef _MSC_VER
 typedef int pid_t;
 #endif
 
diff --git a/oc2/ocnode.c b/oc2/ocnode.c
index cc6db92..1bbc92c 100644
--- a/oc2/ocnode.c
+++ b/oc2/ocnode.c
@@ -8,9 +8,10 @@
 
 static const unsigned int MAX_UINT = 0xffffffff;
 
-static int mergedas1(OCnode* dds, OCnode* das);
-static int mergedods1(OCnode* dds, OCnode* das);
-static char* pathtostring(OClist* path, char* separator, int usecdfname);
+static OCerror mergedas1(OCnode* dds, OCnode* das);
+static OCerror mergedods1(OCnode* dds, OCnode* das);
+static OCerror mergeother1(OCnode* root, OCnode* das);
+static char* pathtostring(OClist* path, char* separator);
 static void computefullname(OCnode* node);
 
 /* Process ocnodes to fix various semantic issues*/
@@ -60,9 +61,11 @@ computefullname(OCnode* node)
     OClist* path;
 
     OCASSERT((node->name != NULL));
+    if(node->fullname != NULL)
+	return;
     path = oclistnew();
     occollectpathtonode(node,path);
-    tmp = pathtostring(path,PATHSEPARATOR,1);
+    tmp = pathtostring(path,PATHSEPARATOR);
     if(tmp == NULL) {
         fullname = nulldup(node->name);
     } else {
@@ -72,14 +75,16 @@ computefullname(OCnode* node)
     oclistfree(path);
 }
 
-/* Convert path to a string; leave off the dataset name*/
+/* Convert path to a string */
 static char*
-pathtostring(OClist* path, char* separator, int usecdfname)
+pathtostring(OClist* path, char* separator)
 {
     int slen,i,len;
     char* pathname;
-    if(path == NULL || (len = oclistlength(path))==0) return NULL;
-    for(slen=0,i=0;i<len;i++) {
+    if(path == NULL) return NULL;
+    len = oclistlength(path);
+    if(len == 0) return NULL;
+    for(i=0,slen=0;i<len;i++) {
 	OCnode* node = (OCnode*)oclistget(path,(size_t)i);
 	if(node->container == NULL || node->name == NULL) continue;
 	slen += strlen(node->name);
@@ -140,12 +145,6 @@ makeattribute(char* name, OCtype ptype, OClist* values)
     return att;
 }
 
-static void
-marklostattribute(OCnode* att)
-{
-    oclog(OCLOGNOTE,"Lost attribute: %s",att->name);
-}
-
 void
 ocroot_free(OCnode* root)
 {
@@ -239,6 +238,7 @@ As described there, the algorithm is as follows.
     Note: If a dataset contains two constructor types which have field names
     that are the same (say point.x and pair.x) one should use fully qualified
     names to get each of those variables.
+
 */
 
 OCerror
@@ -262,7 +262,7 @@ ocddsdasmerge(OCstate* state, OCnode* dasroot, OCnode* ddsroot)
 
     /* 1. collect all the relevant DAS nodes;
           namely those that contain at least one
-          attribute value.
+          attribute value, not including the leaf attributes.
           Simultaneously look for potential ambiguities
           if found; complain but continue: result are indeterminate.
           also collect globals separately*/
@@ -305,7 +305,7 @@ ocddsdasmerge(OCstate* state, OCnode* dasroot, OCnode* ddsroot)
           attributes to the DDS node(s).
           Match means:
           1. DAS->fullname :: DDS->fullname
-          2. DAS->name :: DDS->fullname (support DAS names with embedded '.'
+          2. DAS->name :: DDS->fullname (support DAS names with embedded '.')
           3. DAS->name :: DDS->name
     */
     for(i=0;i<oclistlength(dasnodes);i++) {
@@ -322,22 +322,25 @@ ocddsdasmerge(OCstate* state, OCnode* dasroot, OCnode* ddsroot)
 	}
     }
 
-    /* 4. If there are attributes left, then complain about them being lost.*/
-    for(i=0;i<oclistlength(dasnodes);i++) {
-	OCnode* das = (OCnode*)oclistget(dasnodes,i);
-	if(das != NULL) marklostattribute(das);
-    }
-
-    /* 5. Assign globals*/
+    /* 4. Assign globals*/
     for(i=0;i<oclistlength(dasglobals);i++) {
 	OCnode* das = (OCnode*)oclistget(dasglobals,i);
+	if(das == NULL) continue;
 	mergedas1(ddsroot,das);
     }
-    /* 6. Assign DODS_*/
+    /* 5. Assign DODS_*/
     for(i=0;i<oclistlength(dodsglobals);i++) {
 	OCnode* das = (OCnode*)oclistget(dodsglobals,i);
+	if(das == NULL) continue;
 	mergedods1(ddsroot,das);
     }
+    /* 6. Assign other orphan attributes, which means
+	  construct their full name and assign as a global attribute. */
+    for(i=0;i<oclistlength(dasnodes);i++) {
+	OCnode* das = (OCnode*)oclistget(dasnodes,i);
+	if(das == NULL) continue;
+	mergeother1(ddsroot, das);
+    }
 
 done:
     /* cleanup*/
@@ -348,11 +351,11 @@ done:
     return OCTHROW(stat);
 }
 
-static int
+static OCerror
 mergedas1(OCnode* dds, OCnode* das)
 {
     unsigned int i;
-    int stat = OC_NOERR;
+    OCerror stat = OC_NOERR;
     if(das == NULL) return OC_NOERR; /* nothing to do */
     if(dds->attributes == NULL) dds->attributes = oclistnew();
     /* assign the simple attributes in the das set to this dds node*/
@@ -368,11 +371,11 @@ mergedas1(OCnode* dds, OCnode* das)
     return OCTHROW(stat);
 }
 
-static int
+static OCerror
 mergedods1(OCnode* dds, OCnode* dods)
 {
     unsigned int i;
-    int stat = OC_NOERR;
+    OCerror stat = OC_NOERR;
     if(dods == NULL) return OC_NOERR; /* nothing to do */
     OCASSERT(dods->octype == OC_Attributeset);
     if(dds->attributes == NULL) dds->attributes = oclistnew();
@@ -395,9 +398,7 @@ mergedods1(OCnode* dds, OCnode* dods)
 	    strcpy(newname,dods->name);
 	    strcat(newname,".");
 	    strcat(newname,attnode->name);
-	    att = makeattribute(newname,
-						attnode->etype,
-						attnode->att.values);
+	    att = makeattribute(newname,attnode->etype,attnode->att.values);
 	    free(newname);
             oclistpush(dds->attributes,(void*)att);
 	}
@@ -405,88 +406,33 @@ mergedods1(OCnode* dds, OCnode* dods)
     return OCTHROW(stat);
 }
 
-
-
-#if 0
-
-int
-ocddsdasmerge(OCstate* state, OCnode* ddsroot, OCnode* dasroot)
-{
-    int i,j;
-    int stat = OC_NOERR;
-    OClist* globals = oclistnew();
-    if(dasroot == NULL) return OCTHROW(stat);
-    /* Start by looking for global attributes*/
-    for(i=0;i<oclistlength(dasroot->subnodes);i++) {
-	OCnode* node = (OCnode*)oclistget(dasroot->subnodes,i);
-	if(node->att.isglobal) {
-	    for(j=0;j<oclistlength(node->subnodes);j++) {
-		OCnode* attnode = (OCnode*)oclistget(node->subnodes,j);
-		Attribute* att = makeattribute(attnode->name,
-						attnode->etype,
-						attnode->att.values);
-		oclistpush(globals,(void*)att);
-	    }
-	}
-    }
-    ddsroot->attributes = globals;
-    /* Now try to match subnode names with attribute set names*/
-    for(i=0;i<oclistlength(dasroot->subnodes);i++) {
-	OCnode* das = (OCnode*)oclistget(dasroot->subnodes,i);
-	int match = 0;
-        if(das->att.isglobal) continue;
-        if(das->octype == OC_Attributeset) {
-            for(j=0;j<oclistlength(ddsroot->subnodes) && !match;j++) {
-	        OCnode* dds = (OCnode*)oclistget(ddsroot->subnodes,j);
-	        if(strcmp(das->name,dds->name) == 0) {
-		    match = 1;
-	            stat = mergedas1(dds,das);
-	            if(stat != OC_NOERR) break;
-		}
-	    }
-	}
-        if(!match) {marklostattribute(das);}
-    }
-    if(stat == OC_NOERR) ddsroot->attributed = 1;
-    return OCTHROW(stat);
-}
-
-/* Merge das attributes into the dds node*/
-
-static int
-mergedas1(OCnode* dds, OCnode* das)
+static OCerror
+mergeother1(OCnode* root, OCnode* das)
 {
-    int i,j;
-    int stat = OC_NOERR;
-    if(dds->attributes == NULL) dds->attributes = oclistnew();
-    /* assign the simple attributes in the das set to this dds node*/
-    for(i=0;i<oclistlength(das->subnodes);i++) {
-	OCnode* attnode = (OCnode*)oclistget(das->subnodes,i);
-	if(attnode->octype == OC_Attribute) {
-	    Attribute* att = makeattribute(attnode->name,
-						attnode->etype,
-						attnode->att.values);
-            oclistpush(dds->attributes,(void*)att);
-	}
-    }
-    /* Try to merge any enclosed sets with subnodes of dds*/
-    for(i=0;i<oclistlength(das->subnodes);i++) {
-	OCnode* dasnode = (OCnode*)oclistget(das->subnodes,i);
-	int match = 0;
-        if(dasnode->octype == OC_Attribute) continue; /* already dealt with above*/
-        for(j=0;j<oclistlength(dds->subnodes) && !match;j++) {
-	    OCnode* ddsnode = (OCnode*)oclistget(dds->subnodes,j);
-	    if(strcmp(dasnode->name,ddsnode->name) == 0) {
-	        match = 1;
-	        stat = mergedas1(ddsnode,dasnode);
-	        if(stat != OC_NOERR) break;
-	    }
-	}
-        if(!match) {marklostattribute(dasnode);}
-    }
+    OCerror stat = OC_NOERR;
+    OCattribute* att = NULL;
+
+    OCASSERT(root != NULL);
+    if(root->attributes == NULL) root->attributes = oclistnew();
+
+    if(das->octype == OC_Attribute) {
+        /* compute the full name of this attribute */
+        computefullname(das);
+        /* create attribute */
+        att = makeattribute(das->fullname,das->etype,das->att.values);	
+        oclistpush(root->attributes,(void*)att);
+    } else if(das->octype == OC_Attributeset) {
+	int i;
+	/* Recurse */
+        for(i=0;i<oclistlength(das->subnodes);i++) {
+	    OCnode* sub = (OCnode*)oclistget(das->subnodes,i);
+	    if(sub == NULL) continue;
+	    mergeother1(root,sub);
+	}	
+    } else
+	stat = OC_EDAS;
     return OCTHROW(stat);
 }
-#endif
 
 static void
 ocuncorrelate(OCnode* root)
@@ -612,6 +558,85 @@ ocmarkcacheable(OCstate* state, OCnode* ddsroot)
 }
 
 #if 0
+
+OCerror
+ocddsdasmerge(OCstate* state, OCnode* ddsroot, OCnode* dasroot)
+{
+    int i,j;
+    OCerror stat = OC_NOERR;
+    OClist* globals = oclistnew();
+    if(dasroot == NULL) return OCTHROW(stat);
+    /* Start by looking for global attributes*/
+    for(i=0;i<oclistlength(dasroot->subnodes);i++) {
+	OCnode* node = (OCnode*)oclistget(dasroot->subnodes,i);
+	if(node->att.isglobal) {
+	    for(j=0;j<oclistlength(node->subnodes);j++) {
+		OCnode* attnode = (OCnode*)oclistget(node->subnodes,j);
+		Attribute* att = makeattribute(attnode->name,
+						attnode->etype,
+						attnode->att.values);
+		oclistpush(globals,(void*)att);
+	    }
+	}
+    }
+    ddsroot->attributes = globals;
+    /* Now try to match subnode names with attribute set names*/
+    for(i=0;i<oclistlength(dasroot->subnodes);i++) {
+	OCnode* das = (OCnode*)oclistget(dasroot->subnodes,i);
+	int match = 0;
+        if(das->att.isglobal) continue;
+        if(das->octype == OC_Attributeset) {
+            for(j=0;j<oclistlength(ddsroot->subnodes) && !match;j++) {
+	        OCnode* dds = (OCnode*)oclistget(ddsroot->subnodes,j);
+	        if(strcmp(das->name,dds->name) == 0) {
+		    match = 1;
+	            stat = mergedas1(dds,das);
+	            if(stat != OC_NOERR) break;
+		}
+	    }
+	}
+        if(!match) {marklostattribute(das);}
+    }
+    if(stat == OC_NOERR) ddsroot->attributed = 1;
+    return OCTHROW(stat);
+}
+
+/* Merge das attributes into the dds node*/
+
+static int
+mergedas1(OCnode* dds, OCnode* das)
+{
+    int i,j;
+    int stat = OC_NOERR;
+    if(dds->attributes == NULL) dds->attributes = oclistnew();
+    /* assign the simple attributes in the das set to this dds node*/
+    for(i=0;i<oclistlength(das->subnodes);i++) {
+	OCnode* attnode = (OCnode*)oclistget(das->subnodes,i);
+	if(attnode->octype == OC_Attribute) {
+	    Attribute* att = makeattribute(attnode->name,
+						attnode->etype,
+						attnode->att.values);
+            oclistpush(dds->attributes,(void*)att);
+	}
+    }
+    /* Try to merge any enclosed sets with subnodes of dds*/
+    for(i=0;i<oclistlength(das->subnodes);i++) {
+	OCnode* dasnode = (OCnode*)oclistget(das->subnodes,i);
+	int match = 0;
+        if(dasnode->octype == OC_Attribute) continue; /* already dealt with above*/
+        for(j=0;j<oclistlength(dds->subnodes) && !match;j++) {
+	    OCnode* ddsnode = (OCnode*)oclistget(dds->subnodes,j);
+	    if(strcmp(dasnode->name,ddsnode->name) == 0) {
+	        match = 1;
+	        stat = mergedas1(ddsnode,dasnode);
+	        if(stat != OC_NOERR) break;
+	    }
+	}
+        if(!match) {marklostattribute(dasnode);}
+    }
+    return OCTHROW(stat);
+}
+
 void*
 oclinearize(OCtype etype, unsigned int nstrings, char** strings)
 {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/netcdf.git



More information about the Pkg-grass-devel mailing list